@caupulican/pi-adaptative 0.81.2 → 0.81.3
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/CHANGELOG.md +15 -0
- package/dist/core/agent-session.d.ts +1 -23
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +117 -131
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +2 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +3 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/billing-failover-controller.d.ts +31 -0
- package/dist/core/billing-failover-controller.d.ts.map +1 -0
- package/dist/core/billing-failover-controller.js +72 -0
- package/dist/core/billing-failover-controller.js.map +1 -0
- package/dist/core/billing-failover.d.ts +25 -0
- package/dist/core/billing-failover.d.ts.map +1 -0
- package/dist/core/billing-failover.js +21 -0
- package/dist/core/billing-failover.js.map +1 -0
- package/dist/core/context-pipeline.d.ts +1 -0
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +51 -14
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/model-router/config-diagnostics.d.ts +1 -1
- package/dist/core/model-router/config-diagnostics.d.ts.map +1 -1
- package/dist/core/model-router/config-diagnostics.js +29 -1
- package/dist/core/model-router/config-diagnostics.js.map +1 -1
- package/dist/core/model-router/fitness-gate.d.ts +23 -0
- package/dist/core/model-router/fitness-gate.d.ts.map +1 -0
- package/dist/core/model-router/fitness-gate.js +33 -0
- package/dist/core/model-router/fitness-gate.js.map +1 -0
- package/dist/core/model-router/status.d.ts +25 -1
- package/dist/core/model-router/status.d.ts.map +1 -1
- package/dist/core/model-router/status.js +27 -4
- package/dist/core/model-router/status.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +10 -1
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +108 -27
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +16 -0
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +88 -1
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/scout-controller.d.ts +44 -0
- package/dist/core/scout-controller.d.ts.map +1 -0
- package/dist/core/scout-controller.js +165 -0
- package/dist/core/scout-controller.js.map +1 -0
- package/dist/core/settings-manager.d.ts +16 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +35 -3
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/context-scout.d.ts +19 -0
- package/dist/core/tools/context-scout.d.ts.map +1 -0
- package/dist/core/tools/context-scout.js +47 -0
- package/dist/core/tools/context-scout.js.map +1 -0
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +77 -7
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts +5 -2
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +115 -1
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/docs/index.md +1 -0
- package/docs/providers.md +2 -0
- package/docs/scout.md +71 -0
- package/docs/settings.md +14 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-router-controller.js","sourceRoot":"","sources":["../../src/core/model-router-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EAAE,8BAA8B,EAA+B,MAAM,gCAAgC,CAAC;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mCAAmC,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAA0B,MAAM,qCAAqC,CAAC;AACvG,OAAO,EAAE,6BAA6B,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EACN,qCAAqC,EACrC,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,GAE7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACN,uBAAuB,EACvB,6BAA6B,EAC7B,iCAAiC,GAEjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EACN,qBAAqB,EACrB,eAAe,EACf,gCAAgC,GAChC,MAAM,iCAAiC,CAAC;AAEzC,wGAAwG;AACxG,MAAM,UAAU,sBAAsB,CAAC,KAAiB,EAAU;IACjE,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;AAAA,CACvC;AAED,SAAS,0BAA0B,CAClC,cAAyD,EACzD,QAAmC,EAC5B;IACP,cAAc,CAAC,iBAAiB,CAAC,iCAAiC,EAAE,QAAQ,CAAC,CAAC;AAAA,CAC9E;AA2CD;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IACjC,gFAAgF;IACxE,wBAAwB,CAAqB;IAC7C,uBAAuB,CAAiB;IACxC,yBAAyB,CAA4B;IACrD,+BAA+B,GAAG,KAAK,CAAC;IACxC,mBAAmB,GAAG,KAAK,CAAC;IAC5B,wBAAwB,CAA6B;IACrD,0BAA0B,CAAU;IACpC,sBAAsB,CAAqB;IAElC,IAAI,CAA4B;IAEjD,YAAY,IAA+B,EAAE;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAAA,CACjB;IAED,6GAA6G;IAC7G,eAAe,GAAY;QAC1B,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAAA,CAChC;IAED,qFAAqF;IACrF,eAAe,GAA0C;QACxD,OAAO,IAAI,CAAC,wBAAwB,CAAC;IAAA,CACrC;IAED;;;;OAIG;IACH,qBAAqB,CAAC,QAAgB,EAAE,IAAa,EAA+C;QACnG,IACC,IAAI,CAAC,uBAAuB;YAC5B,6BAA6B,CAAC;gBAC7B,IAAI,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI;gBACvC,QAAQ;gBACR,IAAI;gBACJ,UAAU,EAAE,IAAI,CAAC,uBAAuB,CAAC,UAAU;aACnD,CAAC,EACD,CAAC;YACF,IAAI,CAAC,+BAA+B,GAAG,IAAI,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC;YAC7B,OAAO;gBACN,KAAK,EAAE,IAAI;gBACX,MAAM,EACL,sIAAsI;aACvI,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IAAA,CACjB;IAED;;;;OAIG;IACH,qBAAqB,CAAC,OAAqB,EAAW;QACrD,MAAM,iBAAiB,GAAG,IAAI,CAAC,yBAAyB,CAAC;QACzD,IAAI,CAAC,iBAAiB;YAAE,OAAO,KAAK,CAAC;QACrC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/B,qCAAqC,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9F,+BAA+B,CAAC,iBAAiB,EAAE,OAAkB,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,KAAK,CAAC;IAAA,CACb;IAEO,0BAA0B,CAAC,OAAe,EAAW;QAC5D,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACrG,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAAA,CACtE;IAEO,qBAAqB,CAC5B,MAAc,EACd,eAAmC,EAC0B;QAC7D,IAAI,CAAC,eAAe;YAAE,OAAO,SAAS,CAAC;QACvC,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACjG,IAAI,CAAC,OAAO,CAAC,OAAO;gBAAE,OAAO,SAAS,CAAC;YACvC,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YAC7G,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACzG,8EAA8E;YAC9E,kDAAkD;YAClD,MAAM,YAAY,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACvE,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;iBAC/D,UAAU,EAAE;iBACZ,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC;YAC1C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC5F,IAAI,CAAC,sBAAsB,GAAG,UAAU,CAAC;YACzC,OAAO;gBACN,QAAQ,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,cAAc;oBACpB,UAAU,EAAE,CAAC;oBACb,UAAU,EAAE,iBAAiB;oBAC7B,OAAO,EAAE,CAAC,wDAAwD,OAAO,CAAC,UAAU,GAAG,CAAC;iBACxF;gBACD,KAAK,EAAE,QAAQ,CAAC,KAAK;aACrB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IAAA,CACD;IAED,0GAA0G;IAClG,2BAA2B,CAAC,SAAiB,EAAW;QAC/D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5E,IAAK,OAA6B,CAAC,IAAI,KAAK,YAAY;gBAAE,SAAS;YACnE,IAAK,OAAiC,CAAC,QAAQ,KAAK,oBAAoB;gBAAE,SAAS;YACnF,IAAK,OAAiC,CAAC,OAAO,KAAK,IAAI;gBAAE,SAAS;YAClE,MAAM,OAAO,GAAI,OAA+C,CAAC,OAAO,EAAE,OAAO,CAAC;YAClF,IAAI,OAAO,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAC;QACzC,CAAC;QACD,OAAO,KAAK,CAAC;IAAA,CACb;IAED,iGAAiG;IACzF,KAAK,CAAC,2BAA2B,CAAC,QAAuC,EAA+B;QAC/G,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAClF,IAAI,CAAC,OAAO;gBAAE,OAAO,SAAS,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,iBAAiB,EAAE,CAAC;YACnE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;gBACxD,YAAY,EAAE,gCAAgC;gBAC9C,QAAQ,EAAE;oBACT;wBACC,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;wBAC1E,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;qBACrB;iBACD;gBACD,KAAK;gBACL,aAAa,EAAE,KAAK;gBACpB,SAAS,EAAE,GAAG;gBACd,cAAc,EAAE,OAAO;aACvB,CAAC,CAAC;YACH,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;gBACzE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACjF,CAAC;YACD,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACtD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,OAAO,2BAA2B,IAAI,CAAC,MAAM,IAAI,OAAO,4DAA4D,CAAC;QACtH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IAAA,CACD;IAEO,4BAA4B,CAAC,MAAc,EAA8D;QAChH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;QACzE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,0BAA0B,GAAG,UAAU,CAAC;YAC7C,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,wFAAwF;QACxF,mFAAmF;QACnF,uFAAqF;QACrF,yFAAyF;QACzF,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QACjF,IAAI,aAAa;YAAE,OAAO,aAAa,CAAC;QAExC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,sBAAsB,GAAG,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEhF,6DAA6D;QAC7D,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC,0BAA0B,GAAG,8CAA8C,CAAC;YACjF,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,YAAY,GACjB,QAAQ,CACP,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CACxG,CAAC;QACH,MAAM,KAAK,GACV,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAE7G,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YACrG,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC;YACjD,IAAI,gBAAgB,IAAI,IAAI,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC3E,MAAM,iBAAiB,GAAG,eAAe,CAAC;oBACzC,QAAQ,EAAE,gBAAgB;oBAC1B,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;iBAC3C,CAAC,CAAC;gBACH,IAAI,iBAAiB,CAAC,KAAK,EAAE,CAAC;oBAC7B,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC;oBACjC,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC;oBAC5B,QAAQ,CAAC,UAAU,GAAG,uCAAuC,CAAC;oBAC9D,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,8DAA8D,CAAC,CAAC;oBACzG,QAAQ,CAAC,KAAK,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;oBACjE,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;oBAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC;gBACrD,CAAC;YACF,CAAC;YACD,IAAI,CAAC,0BAA0B,GAAG,qDAAqD,CAAC;YACxF,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YACnB,IAAI,CAAC,0BAA0B,GAAG,GAAG,KAAK,QAAQ,CAAC;YACnD,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,0BAA0B,GAAG,GAAG,KAAK,gBAAgB,YAAY,EAAE,CAAC;YACzE,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,YAAY,GAAG,sBAAsB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,0BAA0B,GAAG,GAAG,KAAK,kBAAkB,YAAY,EAAE,CAAC;YAC3E,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;QAC5C,QAAQ,CAAC,KAAK,GAAG,YAAY,CAAC;QAC9B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;IAAA,CAC3C;IAEO,iCAAiC,CAAC,MAAyB,EAA0B;QAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;QACzE,MAAM,YAAY,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC3F,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtF,OAAO,QAAQ,CAAC,KAAK,CAAC;IAAA,CACtB;IAED,0BAA0B,CAAC,IAAsC,EAA0B;QAC1F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;QACzE,MAAM,OAAO,GACZ,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC7G,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACrG,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtF,OAAO,QAAQ,CAAC,KAAK,CAAC;IAAA,CACtB;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,sBAAsB,CAC3B,MAAc,EACd,OAAiC,EACqC;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QAChC,IAAI,OAAO,EAAE,SAAS;YAAE,OAAO,QAAQ,CAAC;QACxC,yEAAyE;QACzE,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,KAAK,iBAAiB;YAAE,OAAO,QAAQ,CAAC;QAExE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;QACzE,IAAI,CAAC,QAAQ,CAAC,YAAY;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,WAAW,CAAC;QACjE,IAAI,CAAC,YAAY;YAAE,OAAO,QAAQ,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAC5D,IAAI,CAAC,UAAU;YAAE,OAAO,QAAQ,CAAC;QAEjC,IAAI,UAA6B,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YAClC,MAAM;YACN,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE;YACvC,QAAQ,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;gBACzD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;oBACxD,YAAY;oBACZ,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;oBAClG,KAAK,EAAE,UAAU;oBACjB,oFAAoF;oBACpF,6EAA6E;oBAC7E,aAAa,EAAE,QAAQ,CAAC,aAAa,IAAI,KAAK;oBAC9C,SAAS,EAAE,6BAA6B;oBACxC,MAAM;oBACN,2EAAyE;oBACzE,cAAc,EAAE,OAAO;iBACvB,CAAC,CAAC;gBACH,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC;gBAC9B,OAAO;oBACN,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;oBACpC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;iBACzC,CAAC;YAAA,CACF;SACD,CAAC,CAAC;QACH,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,UAAU,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7E,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxE,yFAAyF;YACzF,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC7D,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QACxC,IAAI,UAAU,KAAK,OAAO,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YACrF,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC/D,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,OAAO;gBACN,QAAQ,EAAE;oBACT,GAAG,QAAQ,CAAC,QAAQ;oBACpB,OAAO,EAAE;wBACR,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO;wBAC5B,qBAAqB,UAAU,qDAAqD;qBACpF;iBACD;gBACD,KAAK,EAAE,QAAQ,CAAC,KAAK;aACrB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAA,CAC5G;IAED,uEAAuE;IAC/D,4BAA4B,CAAC,MAAc,EAA0B;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC;QAC3D,OAAO,QAAQ,EAAE,KAAK,CAAC;IAAA,CACvB;IAED,SAAS,CAAC,WAAuC,EAAU;QAC1D,MAAM,eAAe,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;QAClG,MAAM,YAAY,GAAG,IAAI,CAAC,wBAAwB,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,MAAM,mBAAmB,GAAG,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3G,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;QACzE,MAAM,KAAK,GAAG;YACb,uBAAuB,CACtB,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,IAAI,CAAC,0BAA0B,EAC/B,IAAI,CAAC,sBAAsB,IAAI,YAAY,EAAE,MAAM,CACnD;SACD,CAAC;QACF,MAAM,WAAW,GAAG,mCAAmC,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAChG,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;YACrF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACtC,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAAA,CACxB;IAED,KAAK,CAAC,aAAa,CAClB,QAAuC,EACvC,WAAmC,EACnC,aAAwC,EACxC,eAAe,GAAG,IAAI,EACN;QAChB,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,OAAO;QACR,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QACxC,MAAM,qBAAqB,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC;QACxD,MAAM,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QAC5C,MAAM,oBAAoB,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;QACtD,+FAA+F;QAC/F,4FAA0F;QAC1F,mBAAmB;QACnB,IAAI,YAAkD,CAAC;QACvD,IAAI,mBAA4D,CAAC;QACjE,MAAM,+BAA+B,GAAG,IAAI,CAAC,wBAAwB,CAAC;QACtE,MAAM,8BAA8B,GAAG,IAAI,CAAC,uBAAuB,CAAC;QACpE,MAAM,gCAAgC,GAAG,IAAI,CAAC,yBAAyB,CAAC;QACxE,MAAM,sCAAsC,GAAG,IAAI,CAAC,+BAA+B,CAAC;QACpF,MAAM,gBAAgB,GAAG,aAAa,EAAE,IAAI,KAAK,OAAO,CAAC;QACzD,MAAM,qBAAqB,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1D,IAAI,UAAkC,CAAC;QACvC,IAAI,iBAAiB,GAA0C,aAAa;YAC3E,CAAC,CAAC;gBACA,KAAK,EAAE,aAAa;gBACpB,WAAW,EAAE,sBAAsB,CAAC,WAAW,CAAC;gBAChD,OAAO,EAAE,QAAQ;gBACjB,MAAM,EAAE,aAAa,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;aAC9D;YACF,CAAC,CAAC,SAAS,CAAC;QACb,IAAI,WAAoB,CAAC;QACzB,IAAI,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,wBAAwB,GAAG,aAAa;YAC5C,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,OAAO;gBAC/B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,QAAQ;YACX,CAAC,CAAC,SAAS,CAAC;QACb,IAAI,CAAC,uBAAuB,GAAG,aAAa,CAAC;QAC7C,IAAI,gBAAgB,EAAE,CAAC;YACtB,IAAI,CAAC,yBAAyB,GAAG,8BAA8B,EAAE,CAAC;YAClE,IAAI,CAAC,+BAA+B,GAAG,KAAK,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC;YAChC,4FAA4F;YAC5F,kFAAkF;YAClF,uFAAuF;YACvF,6FAA2F;YAC3F,2FAA2F;YAC3F,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,sBAAsB,EAAE,CAAC;YACvF,MAAM,kBAAkB,GAAG,CAAC,aAAa;gBACxC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,aAAa,CAAC,UAAU,KAAK,iBAAiB;oBAC/C,CAAC,CAAC,sBAAsB,CAAC,gBAAgB;oBACzC,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,OAAO;wBAC/B,CAAC,CAAC,sBAAsB,CAAC,aAAa;wBACtC,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,QAAQ;4BAChC,CAAC,CAAC,sBAAsB,CAAC,cAAc;4BACvC,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,WAAW;gCACnC,CAAC,CAAC,sBAAsB,CAAC,iBAAiB;gCAC1C,CAAC,CAAC,SAAS,CAAC;YACjB,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,kBAAkB,CAC7C,WAAW,EACX,kBAAkB,IAAI,qBAAqB,CAC1B,CAAC;YACnB,sFAAsF;YACtF,yFAAuF;YACvF,iEAAiE;YACjE,MAAM,aAAa,GAAG,4BAA4B,CAAC;gBAClD,aAAa,EAAE,WAAW,CAAC,aAAa;gBACxC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,0BAA0B,EAAE,CAAC,IAAI;aACtE,CAAC,CAAC;YACH,IAAI,aAAa,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,IAAI,GAAG,CACtB,4BAA4B,CAC3B,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAC1C,aAAa,CACb,CACD,CAAC;gBACF,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC1E,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,YAAY,CAAC;gBACjC,0FAAwF;gBACxF,2FAA2F;gBAC3F,0FAA0F;gBAC1F,mDAAmD;gBACnD,IAAI,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;oBAClE,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAC5D,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1C,CAAC;oBACF,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,mBAAmB,CAAC;gBAChD,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,uFAAuF;YACvF,oFAAoF;YACpF,iFAAiF;YACjF,wFAAsF;YACtF,6CAA6C;YAC7C,IACC,aAAa,EAAE,UAAU,KAAK,iBAAiB;gBAC/C,CAAC,IAAI,CAAC,mBAAmB;gBACzB,CAAC,IAAI,CAAC,2BAA2B,CAAC,qBAAqB,CAAC,EACvD,CAAC;gBACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC;gBACjE,IAAI,OAAO,EAAE,CAAC;oBACb,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;oBACnD,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;wBAC9B,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;qBACnF,CAAC,CAAC;oBACH,iBAAiB,GAAG;wBACnB,KAAK,EAAE;4BACN,GAAG,aAAa;4BAChB,UAAU,EAAE,4BAA4B;4BACxC,OAAO,EAAE;gCACR,GAAG,aAAa,CAAC,OAAO;gCACxB,sEAAsE;6BACtE;yBACD;wBACD,WAAW,EAAE,sBAAsB,CAAC,WAAW,CAAC;wBAChD,OAAO,EAAE,QAAQ;wBACjB,MAAM,EAAE,UAAU;qBAClB,CAAC;oBACF,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACP,qFAAqF;oBACrF,mFAAmF;oBACnF,uFAAqF;oBACrF,gFAAgF;oBAChF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;wBACd,IAAI,EAAE,SAAS;wBACf,OAAO,EACN,yKAAyK;qBAC1K,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YACD,IAAI,gBAAgB,IAAI,IAAI,CAAC,+BAA+B,EAAE,CAAC;gBAC9D,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;gBACnD,UAAU,GAAG,IAAI,CAAC,iCAAiC,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC;gBAC/E,iBAAiB,GAAG;oBACnB,KAAK,EAAE,aAAc;oBACrB,WAAW,EAAE,sBAAsB,CAAC,WAAW,CAAC;oBAChD,OAAO,EAAE,WAAW;oBACpB,UAAU,EAAE,sBAAsB,CAAC,UAAU,CAAC;oBAC9C,MAAM,EAAE,aAAc,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;iBAC/D,CAAC;gBACF,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;YACnD,CAAC;iBAAM,IAAI,gBAAgB,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBAC/D,6BAA6B,CAC5B,IAAI,CAAC,yBAAyB,EAC9B,CAAC,OAAO,EAAE,EAAE,CAAC;oBACZ,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAAA,CACrD,EACD,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBAAA,CAC9F,CACD,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,WAAW,GAAG,KAAK,CAAC;YACpB,IAAI,iBAAiB,EAAE,CAAC;gBACvB,iBAAiB,GAAG,EAAE,GAAG,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;gBAChE,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;YACnD,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,oFAAoF;YACpF,kFAAkF;YAClF,iFAAiF;YACjF,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBACpD,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;gBAClC,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,qBAAqB,CAAC;gBAClD,qFAAqF;gBACrF,qFAAqF;gBACrF,4FAA0F;gBAC1F,sFAAsF;gBACtF,4FAA0F;gBAC1F,8EAA8E;gBAC9E,IAAI,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;oBACtE,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,iBAAiB,CAAC;gBACvC,CAAC;gBACD,IAAI,mBAAmB,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,mBAAmB,EAAE,CAAC;oBAC3F,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,oBAAoB,CAAC;gBACjD,CAAC;gBACD,qFAAqF;gBACrF,kFAAkF;gBAClF,IAAI,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,wBAAwB,GAAG,+BAA+B,CAAC;YAChE,IAAI,CAAC,uBAAuB,GAAG,8BAA8B,CAAC;YAC9D,IAAI,CAAC,yBAAyB,GAAG,gCAAgC,CAAC;YAClE,IAAI,CAAC,+BAA+B,GAAG,sCAAsC,CAAC;QAC/E,CAAC;QAED,IAAI,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAChC,MAAM,0BAA0B,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC5D,IAAI,CAAC;gBACJ,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;gBAChC,MAAM,aAAa,GAAkB;oBACpC,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,GAAG;oBACf,UAAU,EAAE,gCAAgC;oBAC5C,OAAO,EAAE,CAAC,6DAA6D,CAAC;oBACxE,YAAY,EAAE,OAAO;oBACrB,KAAK,EAAE,sBAAsB,CAAC,UAAU,CAAC;iBACzC,CAAC;gBACF,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;gBACrE,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;YACnD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,WAAW,GAAG,KAAK,CAAC;gBACpB,IAAI,iBAAiB,EAAE,CAAC;oBACvB,iBAAiB,GAAG,EAAE,GAAG,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;oBAChE,IAAI,CAAC,wBAAwB,GAAG,iBAAiB,CAAC;gBACnD,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,IAAI,CAAC,mBAAmB,GAAG,0BAA0B,CAAC;YACvD,CAAC;QACF,CAAC;QAED,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;YAC1C,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,iBAAiB,CAAC,CAAC;YAC7E,kFAAkF;YAClF,6FAA2F;YAC3F,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;gBAC/B,IAAI,EAAE,8BAA8B,CAAC,aAAa;gBAClD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,OAAO,EAAE;oBACR,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI;oBAClC,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI;oBAClC,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,UAAU;oBAC9C,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,UAAU;oBAC9C,OAAO,EAAE,iBAAiB,CAAC,OAAO;iBAClC;aACD,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YACjB,MAAM,WAAW,CAAC;QACnB,CAAC;IAAA,CACD;CACD","sourcesContent":["/**\n * Model-router turn routing: the session's per-turn model-selection subsystem — the regex/executor\n * route resolver, the optional bounded routing judge, the executor lane (Level-0 toolkit direct hit\n * + speculative brain-refined retry), the per-tier thinking/tool-surface swap around a routed turn,\n * the cheap-research-turn session buffer with mutating-tool escalation to an expensive retry, and\n * the router status/diagnostics report.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the transient per-turn\n * route state — the active intent/route, the cheap-turn session buffer, the escalation-requested and\n * retry-in-flight flags — and the sticky last-decision/last-skip-reason/last-intent used by the\n * status report. Everything else it needs — the live agent + its state, the current model, the\n * session/settings managers, the model registry, the agent dir, the reflection abort signal, the\n * base system prompt, the isolated-completion primitive, spawned-usage accounting, the event/telemetry\n * emitters, and the recently-extracted BackgroundLaneController (resolveLaneModel) / ContextPipeline\n * (resolveCurationModelIfFit) collaborators — is reached through narrow deps accessors rather than the\n * whole AgentSession.\n *\n * Drive-path boundary (deliberate): the actual agent.prompt()/continue() loop stays host-side in\n * AgentSession._runAgentPrompt; this controller's parallel routed drive path ({@link runRoutedTurn})\n * owns only the route decision/escalation/tier bookkeeping and delegates every agent turn back through\n * {@link ModelRouterControllerDeps.runAgentPrompt}, so the drive-loop logic is never duplicated. The\n * host keeps a one-line delegation at each call-in: the routing prep + routed-turn entry in\n * _promptUnserialized, the beforeToolCall escalation branch ({@link maybeEscalateToolCall}), the\n * message_end cheap-turn buffering ({@link captureSessionMessage}), the retry-event suppression\n * ({@link isRetryInFlight}), and the public getModelRouterStatus / autonomy-telemetry reads.\n */\n\nimport type { Agent, AgentMessage, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Message, Model, Usage } from \"@caupulican/pi-ai\";\nimport { clampThinkingLevel, modelsAreEqual } from \"@caupulican/pi-ai\";\nimport type { AgentSessionEvent, IsolatedCompletionOptions, IsolatedCompletionResult } from \"./agent-session.ts\";\nimport type { RouteDecision } from \"./autonomy/contracts.ts\";\nimport { AUTONOMY_TELEMETRY_EVENT_TYPES, type AutonomyTelemetryEvent } from \"./autonomy/telemetry-events.ts\";\nimport { latestUserPromptText } from \"./context-pipeline.ts\";\nimport { deriveModelCapabilityProfile, filterToolNamesForCapability } from \"./model-capability.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveCliModel } from \"./model-resolver.ts\";\nimport { collectModelRouterConfigDiagnostics } from \"./model-router/config-diagnostics.ts\";\nimport { classifyExecutorTurn } from \"./model-router/executor-route.ts\";\nimport { classifyModelRouterRoute, type ModelRouterIntent } from \"./model-router/intent-classifier.ts\";\nimport { ROUTE_JUDGE_MAX_OUTPUT_TOKENS, runRouteJudge } from \"./model-router/route-judge.ts\";\nimport {\n\tbufferModelRouterSessionCustomMessage,\n\tbufferModelRouterSessionMessage,\n\tcreateModelRouterSessionBuffer,\n\tflushModelRouterSessionBuffer,\n\ttype ModelRouterSessionBuffer,\n} from \"./model-router/session-buffer.ts\";\nimport {\n\tformatModelRouterStatus,\n\tgetRecentModelRouterDecisions,\n\tMODEL_ROUTER_DECISION_CUSTOM_TYPE,\n\ttype ModelRouterDecisionStatus,\n} from \"./model-router/status.ts\";\nimport { shouldEscalateModelRouterTool } from \"./model-router/tool-escalation.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\n\n/** Canonical `provider/id` label for a routed/resolved model, as it appears in decisions and status. */\nexport function formatModelRouterModel(model: Model<Api>): string {\n\treturn `${model.provider}/${model.id}`;\n}\n\nfunction persistModelRouterDecision(\n\tsessionManager: Pick<SessionManager, \"appendCustomEntry\">,\n\tdecision: ModelRouterDecisionStatus,\n): void {\n\tsessionManager.appendCustomEntry(MODEL_ROUTER_DECISION_CUSTOM_TYPE, decision);\n}\n\nexport interface ModelRouterControllerDeps {\n\t/** Live agent — the controller reads/writes agent.state.{model,thinkingLevel,tools,systemPrompt,messages}\n\t * for the per-turn tier swap and aborts it on a mutating-tool escalation. */\n\tgetAgent(): Agent;\n\t/** Current session model, used to decide whether a routed turn actually swaps the model. */\n\tgetModel(): Model<Api> | undefined;\n\t/** Router/executor/judge/thinking settings + capability mode (all opt-in gates). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Session log: routed-turn message buffering/persistence, decision persistence, recent-decision status. */\n\tgetSessionManager(): SessionManager;\n\t/** Resolves configured route/judge/executor model patterns against configured auth. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Root dir the host-keyed {@link FitnessStore} lives under (executor tool-call fitness gate). */\n\tgetAgentDir(): string;\n\t/** Aborts the judge's bounded completion when the session is disposed. */\n\tgetReflectionSignal(): AbortSignal;\n\t/** Base (extension-free) system prompt — the tier swap only sheds tools when the turn is on it. */\n\tgetBaseSystemPrompt(): string;\n\t/** The host-side drive loop (agent.prompt()/continue()); the routed drive path delegates every turn here. */\n\trunAgentPrompt(messages: AgentMessage | AgentMessage[]): Promise<void>;\n\t/** Rebuilds the system prompt for a filtered tool surface (routed-model capability shedding). */\n\tbuildSystemPromptForToolNames(toolNames: string[]): string;\n\t/** Re-resolves the restored model against the registry after a routed turn (provider override safety). */\n\trefreshCurrentModelFromRegistry(): void;\n\t/** One-shot, tool-less LLM call — the routing judge and the executor reflex-brain warmup ride this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Rolls judge/brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\t/** Session event stream (executor-miss warning). */\n\temit(event: AgentSessionEvent): void;\n\t/** Autonomy telemetry stream (one route-decision event per user-facing routed turn). */\n\temitAutonomyTelemetry(event: AutonomyTelemetryEvent): void;\n\t/** Resolves the judge model pattern via {@link BackgroundLaneController}. */\n\tresolveLaneModel(pattern: string): Model<Api> | undefined;\n\t/** Fitness-gated reflex-brain model via {@link ContextPipeline} (executor speculative refinement). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n}\n\n/**\n * Owns the model-router turn routing extracted from {@link AgentSession}. See the module header for the\n * drive-path boundary that keeps the agent.prompt()/continue() loop host-side.\n */\nexport class ModelRouterController {\n\t/** Active model-router intent for the current transient routed turn, if any. */\n\tprivate _activeModelRouterIntent?: ModelRouterIntent;\n\tprivate _activeModelRouterRoute?: RouteDecision;\n\tprivate _modelRouterSessionBuffer?: ModelRouterSessionBuffer;\n\tprivate _modelRouterEscalationRequested = false;\n\tprivate _isModelRouterRetry = false;\n\tprivate _lastModelRouterDecision?: ModelRouterDecisionStatus;\n\tprivate _lastModelRouterSkipReason?: string;\n\tprivate _lastModelRouterIntent?: ModelRouterIntent;\n\n\tprivate readonly deps: ModelRouterControllerDeps;\n\n\tconstructor(deps: ModelRouterControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** True while the escalation retry turn is running, so the host can suppress its duplicate prompt events. */\n\tisRetryInFlight(): boolean {\n\t\treturn this._isModelRouterRetry;\n\t}\n\n\t/** Latest completed route decision (sticky), for the autonomy telemetry snapshot. */\n\tgetLastDecision(): ModelRouterDecisionStatus | undefined {\n\t\treturn this._lastModelRouterDecision;\n\t}\n\n\t/**\n\t * beforeToolCall escalation gate: a cheap research turn that reaches for a mutating tool aborts the\n\t * turn and requests a retry on the expensive model. Returns the block result the host hook forwards,\n\t * or undefined when no escalation is required.\n\t */\n\tmaybeEscalateToolCall(toolName: string, args: unknown): { block: true; reason: string } | undefined {\n\t\tif (\n\t\t\tthis._activeModelRouterRoute &&\n\t\t\tshouldEscalateModelRouterTool({\n\t\t\t\ttier: this._activeModelRouterRoute.tier,\n\t\t\t\ttoolName,\n\t\t\t\targs,\n\t\t\t\treasonCode: this._activeModelRouterRoute.reasonCode,\n\t\t\t})\n\t\t) {\n\t\t\tthis._modelRouterEscalationRequested = true;\n\t\t\tthis.deps.getAgent().abort();\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason:\n\t\t\t\t\t\"Model router escalation required: a cheap research turn attempted a mutating tool. Retry the turn on the configured expensive model.\",\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * message_end hook: while a cheap routed turn is buffering, capture its messages into the session\n\t * buffer instead of persisting them (they are flushed on success or discarded on escalation).\n\t * Returns true when the message was buffered, so the host skips its own persistence.\n\t */\n\tcaptureSessionMessage(message: AgentMessage): boolean {\n\t\tconst modelRouterBuffer = this._modelRouterSessionBuffer;\n\t\tif (!modelRouterBuffer) return false;\n\t\tif (message.role === \"custom\") {\n\t\t\tbufferModelRouterSessionCustomMessage(modelRouterBuffer, message);\n\t\t\treturn true;\n\t\t}\n\t\tif (message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") {\n\t\t\tbufferModelRouterSessionMessage(modelRouterBuffer, message as Message);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _isModelAvailableAndAuthed(pattern: string): boolean {\n\t\tconst resolved = resolveCliModel({ cliModel: pattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return false;\n\t\treturn this.deps.getModelRegistry().hasConfiguredAuth(resolved.model);\n\t}\n\n\tprivate _resolveExecutorRoute(\n\t\tprompt: string,\n\t\texecutorPattern: string | undefined,\n\t): { decision: RouteDecision; model: Model<Api> } | undefined {\n\t\tif (!executorPattern) return undefined;\n\t\ttry {\n\t\t\tconst verdict = classifyExecutorTurn(prompt, this.deps.getSettingsManager().getToolkitScripts());\n\t\t\tif (!verdict.execute) return undefined;\n\t\t\tconst resolved = resolveCliModel({ cliModel: executorPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\t\tif (!resolved.model || !this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\t\t// Fitness gate: the executor must have PROVEN tool-calling on this host (same\n\t\t\t// canonical-ref discipline as the curation gate).\n\t\t\tconst canonicalRef = `${resolved.model.provider}/${resolved.model.id}`;\n\t\t\tconst fitness = FitnessStore.forAgentDir(this.deps.getAgentDir())\n\t\t\t\t.getForHost()\n\t\t\t\t.find((entry) => entry.model === canonicalRef);\n\t\t\tconst toolCall = fitness?.report.toolCall;\n\t\t\tif (!toolCall || toolCall.succeeded < Math.ceil(toolCall.total * (2 / 3))) return undefined;\n\t\t\tthis._lastModelRouterIntent = \"research\";\n\t\t\treturn {\n\t\t\t\tdecision: {\n\t\t\t\t\ttier: \"cheap\",\n\t\t\t\t\trisk: \"scoped-write\",\n\t\t\t\t\tconfidence: 1,\n\t\t\t\t\treasonCode: \"executor_direct\",\n\t\t\t\t\treasons: [`Executor lane: Level-0 direct hit on toolkit script \"${verdict.scriptName}\"`],\n\t\t\t\t},\n\t\t\t\tmodel: resolved.model,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** True if a run_toolkit_script tool result since `fromIndex` actually EXECUTED (not error/ambiguous). */\n\tprivate _executorTurnExecutedScript(fromIndex: number): boolean {\n\t\tfor (const message of this.deps.getAgent().state.messages.slice(fromIndex)) {\n\t\t\tif ((message as { role?: string }).role !== \"toolResult\") continue;\n\t\t\tif ((message as { toolName?: string }).toolName !== \"run_toolkit_script\") continue;\n\t\t\tif ((message as { isError?: boolean }).isError === true) continue;\n\t\t\tconst outcome = (message as { details?: { outcome?: unknown } }).details?.outcome;\n\t\t\tif (outcome === \"executed\") return true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/** Ask the reflex brain to refine the last user request into an explicit toolkit instruction. */\n\tprivate async _buildExecutorRefinedPrompt(messages: AgentMessage | AgentMessage[]): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\tif (!model) return undefined;\n\t\t\tconst list = Array.isArray(messages) ? messages : [messages];\n\t\t\tconst request = latestUserPromptText(list.filter((m): m is AgentMessage => true));\n\t\t\tif (!request) return undefined;\n\t\t\tconst scripts = this.deps.getSettingsManager().getToolkitScripts();\n\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\tmessages: [\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\tmaxTokens: 256,\n\t\t\t\tcacheRetention: \"short\",\n\t\t\t});\n\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"executor-brain-warmup\" });\n\t\t\t}\n\t\t\tconst plan = parseReflexPlan(completion.text);\n\t\t\tif (!plan || plan.script === \"none\") return undefined;\n\t\t\tconst argHint = plan.args.length > 0 ? ` with args ${JSON.stringify(plan.args)}` : \"\";\n\t\t\treturn `Run the toolkit script \"${plan.script}\"${argHint} using run_toolkit_script, then report its result exactly.`;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate _resolveModelRouterTurnRoute(prompt: string): { decision: RouteDecision; model: Model<Api> } | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._lastModelRouterSkipReason = \"disabled\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// G16 executor lane: a Level-0 DIRECT toolkit hit on a command-shaped prompt routes the\n\t\t// whole turn to the configured local executor (tool-call-fitness-gated) instead of\n\t\t// spending the frontier model on a one-tool reflex. Ambiguity never routes here — it\n\t\t// stays with the big model and the reflex brain. Deterministic, so the judge is skipped.\n\t\tconst executorRoute = this._resolveExecutorRoute(prompt, settings.executorModel);\n\t\tif (executorRoute) return executorRoute;\n\n\t\tconst decision = classifyModelRouterRoute(prompt);\n\t\tthis._lastModelRouterIntent = decision.tier === \"cheap\" ? \"research\" : \"modify\";\n\n\t\t// Learning tier must not be selected for normal user prompts\n\t\tif (decision.tier === \"learning\") {\n\t\t\tthis._lastModelRouterSkipReason = \"learning tier not supported for user prompts\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst modelPattern =\n\t\t\tsettings[\n\t\t\t\tdecision.tier === \"cheap\" ? \"cheapModel\" : decision.tier === \"medium\" ? \"mediumModel\" : \"expensiveModel\"\n\t\t\t];\n\t\tconst label =\n\t\t\tdecision.tier === \"cheap\" ? \"cheap model\" : decision.tier === \"medium\" ? \"medium model\" : \"expensive model\";\n\n\t\tif (decision.tier === \"medium\" && (!modelPattern || !this._isModelAvailableAndAuthed(modelPattern))) {\n\t\t\tconst expensivePattern = settings.expensiveModel;\n\t\t\tif (expensivePattern && this._isModelAvailableAndAuthed(expensivePattern)) {\n\t\t\t\tconst resolvedExpensive = resolveCliModel({\n\t\t\t\t\tcliModel: expensivePattern,\n\t\t\t\t\tmodelRegistry: this.deps.getModelRegistry(),\n\t\t\t\t});\n\t\t\t\tif (resolvedExpensive.model) {\n\t\t\t\t\tdecision.fallbackFrom = \"medium\";\n\t\t\t\t\tdecision.tier = \"expensive\";\n\t\t\t\t\tdecision.reasonCode = \"medium_unavailable_fallback_expensive\";\n\t\t\t\t\tdecision.reasons = [...decision.reasons, \"Medium model is unavailable, falling back to expensive model\"];\n\t\t\t\t\tdecision.model = formatModelRouterModel(resolvedExpensive.model);\n\t\t\t\t\tthis._lastModelRouterSkipReason = undefined;\n\t\t\t\t\treturn { decision, model: resolvedExpensive.model };\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._lastModelRouterSkipReason = \"medium model and expensive fallback are unavailable\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (!modelPattern) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} unset`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst resolved = resolveCliModel({ cliModel: modelPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} unresolved: ${modelPattern}`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst resolvedName = formatModelRouterModel(resolved.model);\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} missing auth: ${resolvedName}`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthis._lastModelRouterSkipReason = undefined;\n\t\tdecision.model = resolvedName;\n\t\treturn { decision, model: resolved.model };\n\t}\n\n\tprivate _resolveModelRouterModelForIntent(intent: ModelRouterIntent): Model<Api> | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst modelPattern = intent === \"research\" ? settings.cheapModel : settings.expensiveModel;\n\t\tif (!modelPattern) return undefined;\n\t\tconst resolved = resolveCliModel({ cliModel: modelPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return undefined;\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\treturn resolved.model;\n\t}\n\n\tresolveConfiguredTierModel(tier: \"cheap\" | \"medium\" | \"expensive\"): Model<Api> | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst pattern =\n\t\t\ttier === \"cheap\" ? settings.cheapModel : tier === \"medium\" ? settings.mediumModel : settings.expensiveModel;\n\t\tif (!pattern) return undefined;\n\t\tconst resolved = resolveCliModel({ cliModel: pattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return undefined;\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\treturn resolved.model;\n\t}\n\n\t/**\n\t * Router resolution with the routing judge (auto-on with the router): the regex classifier's\n\t * decision is the baseline; when a judge model resolves (judgeModel, else mediumModel), one\n\t * bounded, tool-less completion may move the tier between cheap/medium/expensive — never to\n\t * learning. Core rule encoded in the judge prompt: planning is never cheap unless genuinely\n\t * trivial. Every fallback stays visible in the decision reasons, and judge spend reports\n\t * through spawned-usage accounting.\n\t */\n\tasync resolveTurnRouteJudged(\n\t\tprompt: string,\n\t\toptions?: { skipJudge?: boolean },\n\t): Promise<{ decision: RouteDecision; model: Model<Api> } | undefined> {\n\t\tconst baseline = this._resolveModelRouterTurnRoute(prompt);\n\t\tif (!baseline) return undefined;\n\t\tif (options?.skipJudge) return baseline;\n\t\t// Deterministic executor routes need no judge (Level-0 already decided).\n\t\tif (baseline.decision.reasonCode === \"executor_direct\") return baseline;\n\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tif (!settings.judgeEnabled) return baseline;\n\t\tconst judgePattern = settings.judgeModel ?? settings.mediumModel;\n\t\tif (!judgePattern) return baseline;\n\t\tconst judgeModel = this.deps.resolveLaneModel(judgePattern);\n\t\tif (!judgeModel) return baseline;\n\n\t\tlet spentUsage: Usage | undefined;\n\t\tconst judged = await runRouteJudge({\n\t\t\tprompt,\n\t\t\tbaseline: baseline.decision,\n\t\t\tsignal: this.deps.getReflectionSignal(),\n\t\t\tcomplete: async ({ systemPrompt, userPrompt, signal }) => {\n\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t\tmessages: [{ role: \"user\", content: [{ type: \"text\", text: userPrompt }], timestamp: Date.now() }],\n\t\t\t\t\tmodel: judgeModel,\n\t\t\t\t\t// Per-tier thinking (R1): judgeThinking overrides the judge's own completion; unset\n\t\t\t\t\t// keeps today's \"off\" (the judge is a cheap classification call by default).\n\t\t\t\t\tthinkingLevel: settings.judgeThinking ?? \"off\",\n\t\t\t\t\tmaxTokens: ROUTE_JUDGE_MAX_OUTPUT_TOKENS,\n\t\t\t\t\tsignal,\n\t\t\t\t\t// The judge system prompt is static — the provider can cache the prefix.\n\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t});\n\t\t\t\tspentUsage = completion.usage;\n\t\t\t\treturn {\n\t\t\t\t\ttext: completion.text,\n\t\t\t\t\tcostUsd: completion.usage.cost.total,\n\t\t\t\t\tstopReason: String(completion.stopReason),\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t\tif (spentUsage && (spentUsage.cost.total > 0 || spentUsage.totalTokens > 0)) {\n\t\t\tthis.deps.addSpawnedUsage(spentUsage, { label: \"router-judge\" });\n\t\t}\n\n\t\tif (!judged.verdict || judged.decision.tier === baseline.decision.tier) {\n\t\t\t// Same tier (or judge fell back): keep the baseline model, carry the annotated decision.\n\t\t\treturn { decision: judged.decision, model: baseline.model };\n\t\t}\n\n\t\tconst judgedTier = judged.decision.tier;\n\t\tif (judgedTier !== \"cheap\" && judgedTier !== \"medium\" && judgedTier !== \"expensive\") {\n\t\t\treturn { decision: baseline.decision, model: baseline.model };\n\t\t}\n\t\tconst judgedModel = this.resolveConfiguredTierModel(judgedTier);\n\t\tif (!judgedModel) {\n\t\t\treturn {\n\t\t\t\tdecision: {\n\t\t\t\t\t...baseline.decision,\n\t\t\t\t\treasons: [\n\t\t\t\t\t\t...baseline.decision.reasons,\n\t\t\t\t\t\t`Route judge chose ${judgedTier} but no model resolves for that tier; baseline kept`,\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tmodel: baseline.model,\n\t\t\t};\n\t\t}\n\t\treturn { decision: { ...judged.decision, model: formatModelRouterModel(judgedModel) }, model: judgedModel };\n\t}\n\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: test seam\n\tprivate _resolveModelRouterTurnModel(prompt: string): Model<Api> | undefined {\n\t\tconst resolved = this._resolveModelRouterTurnRoute(prompt);\n\t\treturn resolved?.model;\n\t}\n\n\tgetStatus(formatLabel?: (label: string) => string): string {\n\t\tconst recentDecisions = getRecentModelRouterDecisions(this.deps.getSessionManager().getEntries());\n\t\tconst lastDecision = this._lastModelRouterDecision ?? recentDecisions.at(-1);\n\t\tconst historicalDecisions = this._lastModelRouterDecision ? recentDecisions : recentDecisions.slice(0, -1);\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst lines = [\n\t\t\tformatModelRouterStatus(\n\t\t\t\tsettings,\n\t\t\t\tlastDecision,\n\t\t\t\tformatLabel,\n\t\t\t\thistoricalDecisions,\n\t\t\t\tthis._lastModelRouterSkipReason,\n\t\t\t\tthis._lastModelRouterIntent ?? lastDecision?.intent,\n\t\t\t),\n\t\t];\n\t\tconst diagnostics = collectModelRouterConfigDiagnostics(settings, this.deps.getModelRegistry());\n\t\tif (diagnostics.length > 0) {\n\t\t\tlines.push(formatLabel ? formatLabel(\"Config diagnostics:\") : \"Config diagnostics:\");\n\t\t\tfor (const diagnostic of diagnostics) {\n\t\t\t\tlines.push(`- ${diagnostic}`);\n\t\t\t}\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tasync runRoutedTurn(\n\t\tmessages: AgentMessage | AgentMessage[],\n\t\troutedModel: Model<Api> | undefined,\n\t\trouteDecision: RouteDecision | undefined,\n\t\tpersistDecision = true,\n\t): Promise<void> {\n\t\tif (!routedModel) {\n\t\t\tawait this.deps.runAgentPrompt(messages);\n\t\t\treturn;\n\t\t}\n\n\t\tconst agent = this.deps.getAgent();\n\t\tconst previousModel = agent.state.model;\n\t\tconst previousThinkingLevel = agent.state.thinkingLevel;\n\t\tconst previousTurnTools = agent.state.tools;\n\t\tconst previousSystemPrompt = agent.state.systemPrompt;\n\t\t// G4 swap bookkeeping (Bug G): the exact references the swap below assigns, so the finally can\n\t\t// restore ONLY what IT put there — never assigned when no swap happens (e.g. a full-class\n\t\t// routed profile).\n\t\tlet swappedTools: typeof previousTurnTools | undefined;\n\t\tlet swappedSystemPrompt: typeof previousSystemPrompt | undefined;\n\t\tconst previousActiveModelRouterIntent = this._activeModelRouterIntent;\n\t\tconst previousActiveModelRouterRoute = this._activeModelRouterRoute;\n\t\tconst previousModelRouterSessionBuffer = this._modelRouterSessionBuffer;\n\t\tconst previousModelRouterEscalationRequested = this._modelRouterEscalationRequested;\n\t\tconst bufferRoutedTurn = routeDecision?.tier === \"cheap\";\n\t\tconst originalHistoryLength = agent.state.messages.length;\n\t\tlet retryModel: Model<Api> | undefined;\n\t\tlet completedDecision: ModelRouterDecisionStatus | undefined = routeDecision\n\t\t\t? {\n\t\t\t\t\troute: routeDecision,\n\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\toutcome: \"routed\",\n\t\t\t\t\tintent: routeDecision.tier === \"cheap\" ? \"research\" : \"modify\",\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tlet thrownError: unknown;\n\t\tif (routeDecision) {\n\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t}\n\t\tthis._activeModelRouterIntent = routeDecision\n\t\t\t? routeDecision.tier === \"cheap\"\n\t\t\t\t? \"research\"\n\t\t\t\t: \"modify\"\n\t\t\t: undefined;\n\t\tthis._activeModelRouterRoute = routeDecision;\n\t\tif (bufferRoutedTurn) {\n\t\t\tthis._modelRouterSessionBuffer = createModelRouterSessionBuffer();\n\t\t\tthis._modelRouterEscalationRequested = false;\n\t\t}\n\t\tif (!modelsAreEqual(this.deps.getModel(), routedModel)) {\n\t\t\tagent.state.model = routedModel;\n\t\t\t// Per-tier thinking (R1): a configured tier/executor thinking level overrides the inherited\n\t\t\t// session thinking for THIS routed turn only; unset falls back to exactly today's\n\t\t\t// inherit-and-clamp behavior. Executor routes carry tier \"cheap\" too, so reasonCode is\n\t\t\t// checked first — otherwise an executor turn would silently pick up cheapThinking instead.\n\t\t\t// The judge's own completion has a separate knob (judgeThinking) applied at its call site.\n\t\t\tconst routerThinkingSettings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\t\tconst configuredThinking = !routeDecision\n\t\t\t\t? undefined\n\t\t\t\t: routeDecision.reasonCode === \"executor_direct\"\n\t\t\t\t\t? routerThinkingSettings.executorThinking\n\t\t\t\t\t: routeDecision.tier === \"cheap\"\n\t\t\t\t\t\t? routerThinkingSettings.cheapThinking\n\t\t\t\t\t\t: routeDecision.tier === \"medium\"\n\t\t\t\t\t\t\t? routerThinkingSettings.mediumThinking\n\t\t\t\t\t\t\t: routeDecision.tier === \"expensive\"\n\t\t\t\t\t\t\t\t? routerThinkingSettings.expensiveThinking\n\t\t\t\t\t\t\t\t: undefined;\n\t\t\tagent.state.thinkingLevel = clampThinkingLevel(\n\t\t\t\troutedModel,\n\t\t\t\tconfiguredThinking ?? previousThinkingLevel,\n\t\t\t) as ThinkingLevel;\n\t\t\t// G4: capability tool-filtering follows the ROUTED model for the turn. Without this a\n\t\t\t// cheap/local routed model inherits the session model's full tool surface — schemas it\n\t\t\t// pays for on every request and may not be able to drive at all.\n\t\t\tconst routedProfile = deriveModelCapabilityProfile({\n\t\t\t\tcontextWindow: routedModel.contextWindow,\n\t\t\t\tmode: this.deps.getSettingsManager().getModelCapabilitySettings().mode,\n\t\t\t});\n\t\t\tif (routedProfile.class !== \"full\") {\n\t\t\t\tconst allowed = new Set(\n\t\t\t\t\tfilterToolNamesForCapability(\n\t\t\t\t\t\tpreviousTurnTools.map((tool) => tool.name),\n\t\t\t\t\t\troutedProfile,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tswappedTools = previousTurnTools.filter((tool) => allowed.has(tool.name));\n\t\t\t\tagent.state.tools = swappedTools;\n\t\t\t\t// G4: the system prompt follows the ROUTED model's filtered surface too — otherwise the\n\t\t\t\t// cheap/local model is billed for (and told about) tool guidelines/snippets it can't call.\n\t\t\t\t// Per-turn only; restored in the finally. A live extension override of the prompt is left\n\t\t\t\t// alone (only shed when we're on the base prompt).\n\t\t\t\tif (agent.state.systemPrompt === this.deps.getBaseSystemPrompt()) {\n\t\t\t\t\tswappedSystemPrompt = this.deps.buildSystemPromptForToolNames(\n\t\t\t\t\t\tagent.state.tools.map((tool) => tool.name),\n\t\t\t\t\t);\n\t\t\t\t\tagent.state.systemPrompt = swappedSystemPrompt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tawait this.deps.runAgentPrompt(messages);\n\t\t\t// Speculative muscle-retry (G16 refinement): an executor-routed turn is a bet that the\n\t\t\t// small model can run the toolkit command directly. If it ends WITHOUT a successful\n\t\t\t// run_toolkit_script execution, retry ONCE on the same executor with the brain's\n\t\t\t// refined instruction injected — the brain warms while the muscle tries, so the retry\n\t\t\t// pays only when the muscle actually missed.\n\t\t\tif (\n\t\t\t\trouteDecision?.reasonCode === \"executor_direct\" &&\n\t\t\t\t!this._isModelRouterRetry &&\n\t\t\t\t!this._executorTurnExecutedScript(originalHistoryLength)\n\t\t\t) {\n\t\t\t\tconst refined = await this._buildExecutorRefinedPrompt(messages);\n\t\t\t\tif (refined) {\n\t\t\t\t\tagent.state.messages.splice(originalHistoryLength);\n\t\t\t\t\tawait this.deps.runAgentPrompt([\n\t\t\t\t\t\t{ role: \"user\", content: [{ type: \"text\", text: refined }], timestamp: Date.now() },\n\t\t\t\t\t]);\n\t\t\t\t\tcompletedDecision = {\n\t\t\t\t\t\troute: {\n\t\t\t\t\t\t\t...routeDecision,\n\t\t\t\t\t\t\treasonCode: \"executor_speculative_retry\",\n\t\t\t\t\t\t\treasons: [\n\t\t\t\t\t\t\t\t...routeDecision.reasons,\n\t\t\t\t\t\t\t\t\"Executor missed on first try; retried with brain-refined instruction\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\t\toutcome: \"routed\",\n\t\t\t\t\t\tintent: \"research\",\n\t\t\t\t\t};\n\t\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t\t} else {\n\t\t\t\t\t// The muscle missed AND the reflex brain could not refine the request into a toolkit\n\t\t\t\t\t// instruction (no fit brain model, or no confident plan). There is deliberately NO\n\t\t\t\t\t// frontier fallback here, so surface the miss instead of letting it stand silently —\n\t\t\t\t\t// otherwise the routed turn just ends with an unrun command and no explanation.\n\t\t\t\t\tthis.deps.emit({\n\t\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Executor lane: the toolkit command did not run and the reflex brain could not refine it into an explicit instruction; leaving the turn as-is (no automatic escalation).\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bufferRoutedTurn && this._modelRouterEscalationRequested) {\n\t\t\t\tagent.state.messages.splice(originalHistoryLength);\n\t\t\t\tretryModel = this._resolveModelRouterModelForIntent(\"modify\") ?? previousModel;\n\t\t\t\tcompletedDecision = {\n\t\t\t\t\troute: routeDecision!,\n\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\toutcome: \"escalated\",\n\t\t\t\t\tretryModel: formatModelRouterModel(retryModel),\n\t\t\t\t\tintent: routeDecision!.tier === \"cheap\" ? \"research\" : \"modify\",\n\t\t\t\t};\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t} else if (bufferRoutedTurn && this._modelRouterSessionBuffer) {\n\t\t\t\tflushModelRouterSessionBuffer(\n\t\t\t\t\tthis._modelRouterSessionBuffer,\n\t\t\t\t\t(message) => {\n\t\t\t\t\t\tthis.deps.getSessionManager().appendMessage(message);\n\t\t\t\t\t},\n\t\t\t\t\t(customType, content, display, details) => {\n\t\t\t\t\t\tthis.deps.getSessionManager().appendCustomMessageEntry(customType, content, display, details);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrownError = error;\n\t\t\tif (completedDecision) {\n\t\t\t\tcompletedDecision = { ...completedDecision, outcome: \"failed\" };\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t}\n\t\t} finally {\n\t\t\t// Restore the pre-route model ONLY if the routed model is still in place: a command\n\t\t\t// handler may have legitimately changed the session model mid-turn (setModel or a\n\t\t\t// provider re-registration), and clobbering that would silently undo the change.\n\t\t\tif (modelsAreEqual(agent.state.model, routedModel)) {\n\t\t\t\tagent.state.model = previousModel;\n\t\t\t\tagent.state.thinkingLevel = previousThinkingLevel;\n\t\t\t\t// Symmetric restore (Bug G): undo tools/systemPrompt only if each is STILL the exact\n\t\t\t\t// reference/string the G4 swap above assigned (never assigned at all when the routed\n\t\t\t\t// profile was full-class — then there is nothing to restore either). An extension calling\n\t\t\t\t// setActiveToolsByName mid-turn reassigns both to its own values without touching the\n\t\t\t\t// model — the model guard above still passes, but that live change is legitimate and must\n\t\t\t\t// survive rather than being silently reverted to the stale pre-turn snapshot.\n\t\t\t\tif (swappedTools !== undefined && agent.state.tools === swappedTools) {\n\t\t\t\t\tagent.state.tools = previousTurnTools;\n\t\t\t\t}\n\t\t\t\tif (swappedSystemPrompt !== undefined && agent.state.systemPrompt === swappedSystemPrompt) {\n\t\t\t\t\tagent.state.systemPrompt = previousSystemPrompt;\n\t\t\t\t}\n\t\t\t\t// The registry may have changed mid-turn (command-time registerProvider): re-resolve\n\t\t\t\t// the restored model so a provider override is not dropped with the routed model.\n\t\t\t\tthis.deps.refreshCurrentModelFromRegistry();\n\t\t\t}\n\t\t\tthis._activeModelRouterIntent = previousActiveModelRouterIntent;\n\t\t\tthis._activeModelRouterRoute = previousActiveModelRouterRoute;\n\t\t\tthis._modelRouterSessionBuffer = previousModelRouterSessionBuffer;\n\t\t\tthis._modelRouterEscalationRequested = previousModelRouterEscalationRequested;\n\t\t}\n\n\t\tif (retryModel && !thrownError) {\n\t\t\tconst previousIsModelRouterRetry = this._isModelRouterRetry;\n\t\t\ttry {\n\t\t\t\tthis._isModelRouterRetry = true;\n\t\t\t\tconst retryDecision: RouteDecision = {\n\t\t\t\t\ttier: \"expensive\",\n\t\t\t\t\trisk: \"high-impact\",\n\t\t\t\t\tconfidence: 1.0,\n\t\t\t\t\treasonCode: \"cheap_mutating_tool_escalation\",\n\t\t\t\t\treasons: [\"Cheap research turn attempted a mutating tool and escalated\"],\n\t\t\t\t\tfallbackFrom: \"cheap\",\n\t\t\t\t\tmodel: formatModelRouterModel(retryModel),\n\t\t\t\t};\n\t\t\t\tawait this.runRoutedTurn(messages, retryModel, retryDecision, false);\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t} catch (error) {\n\t\t\t\tthrownError = error;\n\t\t\t\tif (completedDecision) {\n\t\t\t\t\tcompletedDecision = { ...completedDecision, outcome: \"failed\" };\n\t\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tthis._isModelRouterRetry = previousIsModelRouterRetry;\n\t\t\t}\n\t\t}\n\n\t\tif (persistDecision && completedDecision) {\n\t\t\tpersistModelRouterDecision(this.deps.getSessionManager(), completedDecision);\n\t\t\t// G3: one route event per user-facing routed turn (the escalation retry runs with\n\t\t\t// persistDecision=false, so it does not double-emit). Codes/numbers only — no prompt text.\n\t\t\tthis.deps.emitAutonomyTelemetry({\n\t\t\t\ttype: AUTONOMY_TELEMETRY_EVENT_TYPES.routeDecision,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tpayload: {\n\t\t\t\t\ttier: completedDecision.route.tier,\n\t\t\t\t\trisk: completedDecision.route.risk,\n\t\t\t\t\treasonCode: completedDecision.route.reasonCode,\n\t\t\t\t\tconfidence: completedDecision.route.confidence,\n\t\t\t\t\toutcome: completedDecision.outcome,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (thrownError) {\n\t\t\tthrow thrownError;\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-router-controller.js","sourceRoot":"","sources":["../../src/core/model-router-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model-router turn routing: the session's per-turn model-selection subsystem — the regex/executor\n * route resolver, the optional bounded routing judge, the executor lane (Level-0 toolkit direct hit\n * + speculative brain-refined retry), the per-tier thinking/tool-surface swap around a routed turn,\n * the cheap-research-turn session buffer with mutating-tool escalation to an expensive retry, and\n * the router status/diagnostics report.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the transient per-turn\n * route state — the active intent/route, the cheap-turn session buffer, the escalation-requested and\n * retry-in-flight flags — and the sticky last-decision/last-skip-reason/last-intent used by the\n * status report. Everything else it needs — the live agent + its state, the current model, the\n * session/settings managers, the model registry, the agent dir, the reflection abort signal, the\n * base system prompt, the isolated-completion primitive, spawned-usage accounting, the event/telemetry\n * emitters, and the recently-extracted BackgroundLaneController (resolveLaneModel) / ContextPipeline\n * (resolveCurationModelIfFit) collaborators — is reached through narrow deps accessors rather than the\n * whole AgentSession.\n *\n * Drive-path boundary (deliberate): the actual agent.prompt()/continue() loop stays host-side in\n * AgentSession._runAgentPrompt; this controller's parallel routed drive path ({@link runRoutedTurn})\n * owns only the route decision/escalation/tier bookkeeping and delegates every agent turn back through\n * {@link ModelRouterControllerDeps.runAgentPrompt}, so the drive-loop logic is never duplicated. The\n * host keeps a one-line delegation at each call-in: the routing prep + routed-turn entry in\n * _promptUnserialized, the beforeToolCall escalation branch ({@link maybeEscalateToolCall}), the\n * message_end cheap-turn buffering ({@link captureSessionMessage}), the retry-event suppression\n * ({@link isRetryInFlight}), and the public getModelRouterStatus / autonomy-telemetry reads.\n */\n\nimport type { Agent, AgentMessage, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Message, Model, Usage } from \"@caupulican/pi-ai\";\nimport { clampThinkingLevel, modelsAreEqual } from \"@caupulican/pi-ai\";\nimport type { AgentSessionEvent, IsolatedCompletionOptions, IsolatedCompletionResult } from \"./agent-session.ts\";\nimport type { RouteDecision } from \"./autonomy/contracts.ts\";\nimport { AUTONOMY_TELEMETRY_EVENT_TYPES, type AutonomyTelemetryEvent } from \"./autonomy/telemetry-events.ts\";\nimport { latestUserPromptText } from \"./context-pipeline.ts\";\nimport { deriveModelCapabilityProfile, filterToolNamesForCapability } from \"./model-capability.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveCliModel } from \"./model-resolver.ts\";\nimport { collectModelRouterConfigDiagnostics } from \"./model-router/config-diagnostics.ts\";\nimport { classifyExecutorTurn } from \"./model-router/executor-route.ts\";\nimport {\n\tevaluateSurfaceFitness,\n\ttype FitnessGatedSurface,\n\ttype FitnessGateVerdict,\n} from \"./model-router/fitness-gate.ts\";\nimport { classifyModelRouterRoute, type ModelRouterIntent } from \"./model-router/intent-classifier.ts\";\nimport { ROUTE_JUDGE_MAX_OUTPUT_TOKENS, runRouteJudge } from \"./model-router/route-judge.ts\";\nimport {\n\tbufferModelRouterSessionCustomMessage,\n\tbufferModelRouterSessionMessage,\n\tcreateModelRouterSessionBuffer,\n\tflushModelRouterSessionBuffer,\n\ttype ModelRouterSessionBuffer,\n} from \"./model-router/session-buffer.ts\";\nimport {\n\tformatModelRouterStatus,\n\tgetRecentModelRouterDecisions,\n\tMODEL_ROUTER_DECISION_CUSTOM_TYPE,\n\ttype ModelRouterDecisionStatus,\n\ttype ModelRouterFailoverStatus,\n\ttype ModelRouterFitnessStatuses,\n} from \"./model-router/status.ts\";\nimport { shouldEscalateModelRouterTool } from \"./model-router/tool-escalation.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\n\n/** Canonical `provider/id` label for a routed/resolved model, as it appears in decisions and status. */\nexport function formatModelRouterModel(model: Model<Api>): string {\n\treturn `${model.provider}/${model.id}`;\n}\n\nfunction persistModelRouterDecision(\n\tsessionManager: Pick<SessionManager, \"appendCustomEntry\">,\n\tdecision: ModelRouterDecisionStatus,\n): void {\n\tsessionManager.appendCustomEntry(MODEL_ROUTER_DECISION_CUSTOM_TYPE, decision);\n}\n\nexport interface ModelRouterControllerDeps {\n\t/** Live agent — the controller reads/writes agent.state.{model,thinkingLevel,tools,systemPrompt,messages}\n\t * for the per-turn tier swap and aborts it on a mutating-tool escalation. */\n\tgetAgent(): Agent;\n\t/** Current session model, used to decide whether a routed turn actually swaps the model. */\n\tgetModel(): Model<Api> | undefined;\n\t/** Router/executor/judge/thinking settings + capability mode (all opt-in gates). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Session log: routed-turn message buffering/persistence, decision persistence, recent-decision status. */\n\tgetSessionManager(): SessionManager;\n\t/** Resolves configured route/judge/executor model patterns against configured auth. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Session-scoped provider/model quota exhaustion guard. */\n\tisModelExhausted(model: Model<Api>): boolean;\n\t/** Status snapshot for B5 exhausted models and the last failover notice. */\n\tgetFailoverStatus(): ModelRouterFailoverStatus;\n\t/** Root dir the host-keyed {@link FitnessStore} lives under (executor tool-call fitness gate). */\n\tgetAgentDir(): string;\n\t/** Aborts the judge's bounded completion when the session is disposed. */\n\tgetReflectionSignal(): AbortSignal;\n\t/** Base (extension-free) system prompt — the tier swap only sheds tools when the turn is on it. */\n\tgetBaseSystemPrompt(): string;\n\t/** The host-side drive loop (agent.prompt()/continue()); the routed drive path delegates every turn here. */\n\trunAgentPrompt(messages: AgentMessage | AgentMessage[]): Promise<void>;\n\t/** Rebuilds the system prompt for a filtered tool surface (routed-model capability shedding). */\n\tbuildSystemPromptForToolNames(toolNames: string[]): string;\n\t/** Re-resolves the restored model against the registry after a routed turn (provider override safety). */\n\trefreshCurrentModelFromRegistry(): void;\n\t/** One-shot, tool-less LLM call — the routing judge and the executor reflex-brain warmup ride this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Rolls judge/brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\t/** Session event stream (executor-miss warning). */\n\temit(event: AgentSessionEvent): void;\n\t/** Autonomy telemetry stream (one route-decision event per user-facing routed turn). */\n\temitAutonomyTelemetry(event: AutonomyTelemetryEvent): void;\n\t/** Resolves the judge model pattern via {@link BackgroundLaneController}. */\n\tresolveLaneModel(pattern: string): Model<Api> | undefined;\n\t/** Fitness-gated reflex-brain model via {@link ContextPipeline} (executor speculative refinement). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n}\n\n/**\n * Owns the model-router turn routing extracted from {@link AgentSession}. See the module header for the\n * drive-path boundary that keeps the agent.prompt()/continue() loop host-side.\n */\nexport class ModelRouterController {\n\t/** Active model-router intent for the current transient routed turn, if any. */\n\tprivate _activeModelRouterIntent?: ModelRouterIntent;\n\tprivate _activeModelRouterRoute?: RouteDecision;\n\tprivate _modelRouterSessionBuffer?: ModelRouterSessionBuffer;\n\tprivate _modelRouterEscalationRequested = false;\n\tprivate _isModelRouterRetry = false;\n\tprivate _lastModelRouterDecision?: ModelRouterDecisionStatus;\n\tprivate _lastModelRouterSkipReason?: string;\n\tprivate _lastModelRouterIntent?: ModelRouterIntent;\n\n\tprivate readonly deps: ModelRouterControllerDeps;\n\n\tconstructor(deps: ModelRouterControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** True while the escalation retry turn is running, so the host can suppress its duplicate prompt events. */\n\tisRetryInFlight(): boolean {\n\t\treturn this._isModelRouterRetry;\n\t}\n\n\t/** Latest completed route decision (sticky), for the autonomy telemetry snapshot. */\n\tgetLastDecision(): ModelRouterDecisionStatus | undefined {\n\t\treturn this._lastModelRouterDecision;\n\t}\n\n\t/**\n\t * beforeToolCall escalation gate: a cheap research turn that reaches for a mutating tool aborts the\n\t * turn and requests a retry on the expensive model. Returns the block result the host hook forwards,\n\t * or undefined when no escalation is required.\n\t */\n\tmaybeEscalateToolCall(toolName: string, args: unknown): { block: true; reason: string } | undefined {\n\t\tif (\n\t\t\tthis._activeModelRouterRoute &&\n\t\t\tshouldEscalateModelRouterTool({\n\t\t\t\ttier: this._activeModelRouterRoute.tier,\n\t\t\t\ttoolName,\n\t\t\t\targs,\n\t\t\t\treasonCode: this._activeModelRouterRoute.reasonCode,\n\t\t\t})\n\t\t) {\n\t\t\tthis._modelRouterEscalationRequested = true;\n\t\t\tthis.deps.getAgent().abort();\n\t\t\treturn {\n\t\t\t\tblock: true,\n\t\t\t\treason:\n\t\t\t\t\t\"Model router escalation required: a cheap research turn attempted a mutating tool. Retry the turn on the configured expensive model.\",\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * message_end hook: while a cheap routed turn is buffering, capture its messages into the session\n\t * buffer instead of persisting them (they are flushed on success or discarded on escalation).\n\t * Returns true when the message was buffered, so the host skips its own persistence.\n\t */\n\tcaptureSessionMessage(message: AgentMessage): boolean {\n\t\tconst modelRouterBuffer = this._modelRouterSessionBuffer;\n\t\tif (!modelRouterBuffer) return false;\n\t\tif (message.role === \"custom\") {\n\t\t\tbufferModelRouterSessionCustomMessage(modelRouterBuffer, message);\n\t\t\treturn true;\n\t\t}\n\t\tif (message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\") {\n\t\t\tbufferModelRouterSessionMessage(modelRouterBuffer, message as Message);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _isModelAvailableAndAuthed(pattern: string): boolean {\n\t\tconst resolved = resolveCliModel({ cliModel: pattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return false;\n\t\treturn this.deps.getModelRegistry().hasConfiguredAuth(resolved.model);\n\t}\n\n\tprivate _evaluateModelFitness(surface: FitnessGatedSurface, model: Model<Api>): FitnessGateVerdict {\n\t\tconst fitness = FitnessStore.forAgentDir(this.deps.getAgentDir())\n\t\t\t.getForHost()\n\t\t\t.find((entry) => entry.model === formatModelRouterModel(model));\n\t\treturn evaluateSurfaceFitness(surface, fitness?.report);\n\t}\n\n\tprivate _formatFitnessFailure(verdict: Exclude<FitnessGateVerdict, { fit: true }>): string {\n\t\treturn verdict.reason === \"unprobed\" ? \"unprobed\" : `${verdict.lane} ${verdict.succeeded}/${verdict.total}`;\n\t}\n\n\tprivate _routerSurfaceForTier(tier: \"cheap\" | \"medium\" | \"expensive\"): FitnessGatedSurface {\n\t\treturn tier === \"cheap\" ? \"router_cheap\" : tier === \"medium\" ? \"router_medium\" : \"router_expensive\";\n\t}\n\n\tprivate _getRouterTierFitnessStatuses(): ModelRouterFitnessStatuses {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst statuses: ModelRouterFitnessStatuses = {};\n\t\tfor (const tier of [\"cheap\", \"medium\", \"expensive\"] as const) {\n\t\t\tconst pattern =\n\t\t\t\ttier === \"cheap\" ? settings.cheapModel : tier === \"medium\" ? settings.mediumModel : settings.expensiveModel;\n\t\t\tif (!pattern) continue;\n\t\t\tconst resolved = resolveCliModel({ cliModel: pattern, modelRegistry: this.deps.getModelRegistry() });\n\t\t\tif (!resolved.model || !this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) continue;\n\t\t\tconst verdict = this._evaluateModelFitness(this._routerSurfaceForTier(tier), resolved.model);\n\t\t\tstatuses[tier] = verdict.fit\n\t\t\t\t? { status: verdict.probed ? \"fit\" : \"unprobed\" }\n\t\t\t\t: verdict.reason === \"unprobed\"\n\t\t\t\t\t? { status: \"unprobed\" }\n\t\t\t\t\t: { status: \"unfit\", lane: verdict.lane, succeeded: verdict.succeeded, total: verdict.total };\n\t\t}\n\t\treturn statuses;\n\t}\n\n\tprivate _resolveExpensiveFallbackRoute(\n\t\tdecision: RouteDecision,\n\t\treasonCode: string,\n\t\treason: string,\n\t): { decision: RouteDecision; model: Model<Api> } | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst expensivePattern = settings.expensiveModel;\n\t\tif (!expensivePattern || !this._isModelAvailableAndAuthed(expensivePattern)) return undefined;\n\t\tconst resolvedExpensive = resolveCliModel({\n\t\t\tcliModel: expensivePattern,\n\t\t\tmodelRegistry: this.deps.getModelRegistry(),\n\t\t});\n\t\tif (!resolvedExpensive.model) return undefined;\n\t\tif (this.deps.isModelExhausted(resolvedExpensive.model)) {\n\t\t\tthis._lastModelRouterSkipReason = \"expensive model exhausted: quota\";\n\t\t\treturn undefined;\n\t\t}\n\t\tif (settings.fitnessGate) {\n\t\t\tconst verdict = this._evaluateModelFitness(\"router_expensive\", resolvedExpensive.model);\n\t\t\tif (!verdict.fit) {\n\t\t\t\tthis._lastModelRouterSkipReason = `expensive model unfit: ${this._formatFitnessFailure(verdict)} (fitness gate)`;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t\tdecision.fallbackFrom = \"medium\";\n\t\tdecision.tier = \"expensive\";\n\t\tdecision.reasonCode = reasonCode;\n\t\tdecision.reasons = [...decision.reasons, reason];\n\t\tdecision.model = formatModelRouterModel(resolvedExpensive.model);\n\t\tthis._lastModelRouterSkipReason = undefined;\n\t\treturn { decision, model: resolvedExpensive.model };\n\t}\n\n\tprivate _resolveExecutorRoute(\n\t\tprompt: string,\n\t\texecutorPattern: string | undefined,\n\t): { decision: RouteDecision; model: Model<Api> } | undefined {\n\t\tif (!executorPattern) return undefined;\n\t\ttry {\n\t\t\tconst verdict = classifyExecutorTurn(prompt, this.deps.getSettingsManager().getToolkitScripts());\n\t\t\tif (!verdict.execute) return undefined;\n\t\t\tconst resolved = resolveCliModel({ cliModel: executorPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\t\tif (!resolved.model || !this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\t\t// Fitness gate: the executor must have PROVEN tool-calling on this host (same\n\t\t\t// canonical-ref discipline as the curation gate).\n\t\t\tif (!this._evaluateModelFitness(\"executor\", resolved.model).fit) return undefined;\n\t\t\tthis._lastModelRouterIntent = \"research\";\n\t\t\treturn {\n\t\t\t\tdecision: {\n\t\t\t\t\ttier: \"cheap\",\n\t\t\t\t\trisk: \"scoped-write\",\n\t\t\t\t\tconfidence: 1,\n\t\t\t\t\treasonCode: \"executor_direct\",\n\t\t\t\t\treasons: [`Executor lane: Level-0 direct hit on toolkit script \"${verdict.scriptName}\"`],\n\t\t\t\t},\n\t\t\t\tmodel: resolved.model,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** True if a run_toolkit_script tool result since `fromIndex` actually EXECUTED (not error/ambiguous). */\n\tprivate _executorTurnExecutedScript(fromIndex: number): boolean {\n\t\tfor (const message of this.deps.getAgent().state.messages.slice(fromIndex)) {\n\t\t\tif ((message as { role?: string }).role !== \"toolResult\") continue;\n\t\t\tif ((message as { toolName?: string }).toolName !== \"run_toolkit_script\") continue;\n\t\t\tif ((message as { isError?: boolean }).isError === true) continue;\n\t\t\tconst outcome = (message as { details?: { outcome?: unknown } }).details?.outcome;\n\t\t\tif (outcome === \"executed\") return true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/** Ask the reflex brain to refine the last user request into an explicit toolkit instruction. */\n\tprivate async _buildExecutorRefinedPrompt(messages: AgentMessage | AgentMessage[]): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\tif (!model) return undefined;\n\t\t\tconst list = Array.isArray(messages) ? messages : [messages];\n\t\t\tconst request = latestUserPromptText(list.filter((m): m is AgentMessage => true));\n\t\t\tif (!request) return undefined;\n\t\t\tconst scripts = this.deps.getSettingsManager().getToolkitScripts();\n\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\tmessages: [\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\tmaxTokens: 256,\n\t\t\t\tcacheRetention: \"short\",\n\t\t\t});\n\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"executor-brain-warmup\" });\n\t\t\t}\n\t\t\tconst plan = parseReflexPlan(completion.text);\n\t\t\tif (!plan || plan.script === \"none\") return undefined;\n\t\t\tconst argHint = plan.args.length > 0 ? ` with args ${JSON.stringify(plan.args)}` : \"\";\n\t\t\treturn `Run the toolkit script \"${plan.script}\"${argHint} using run_toolkit_script, then report its result exactly.`;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate _resolveModelRouterTurnRoute(prompt: string): { decision: RouteDecision; model: Model<Api> } | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._lastModelRouterSkipReason = \"disabled\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// G16 executor lane: a Level-0 DIRECT toolkit hit on a command-shaped prompt routes the\n\t\t// whole turn to the configured local executor (tool-call-fitness-gated) instead of\n\t\t// spending the frontier model on a one-tool reflex. Ambiguity never routes here — it\n\t\t// stays with the big model and the reflex brain. Deterministic, so the judge is skipped.\n\t\tconst executorRoute = this._resolveExecutorRoute(prompt, settings.executorModel);\n\t\tif (executorRoute) return executorRoute;\n\n\t\tconst decision = classifyModelRouterRoute(prompt);\n\t\tthis._lastModelRouterIntent = decision.tier === \"cheap\" ? \"research\" : \"modify\";\n\n\t\t// Learning tier must not be selected for normal user prompts\n\t\tif (decision.tier === \"learning\") {\n\t\t\tthis._lastModelRouterSkipReason = \"learning tier not supported for user prompts\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst modelPattern =\n\t\t\tsettings[\n\t\t\t\tdecision.tier === \"cheap\" ? \"cheapModel\" : decision.tier === \"medium\" ? \"mediumModel\" : \"expensiveModel\"\n\t\t\t];\n\t\tconst label =\n\t\t\tdecision.tier === \"cheap\" ? \"cheap model\" : decision.tier === \"medium\" ? \"medium model\" : \"expensive model\";\n\n\t\tif (decision.tier === \"medium\" && (!modelPattern || !this._isModelAvailableAndAuthed(modelPattern))) {\n\t\t\tconst fallback = this._resolveExpensiveFallbackRoute(\n\t\t\t\tdecision,\n\t\t\t\t\"medium_unavailable_fallback_expensive\",\n\t\t\t\t\"Medium model is unavailable, falling back to expensive model\",\n\t\t\t);\n\t\t\tif (fallback) return fallback;\n\t\t\tthis._lastModelRouterSkipReason ??= \"medium model and expensive fallback are unavailable\";\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (!modelPattern) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} unset`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst resolved = resolveCliModel({ cliModel: modelPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} unresolved: ${modelPattern}`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst resolvedName = formatModelRouterModel(resolved.model);\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) {\n\t\t\tthis._lastModelRouterSkipReason = `${label} missing auth: ${resolvedName}`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (this.deps.isModelExhausted(resolved.model)) {\n\t\t\tif (decision.tier === \"medium\") {\n\t\t\t\tconst fallback = this._resolveExpensiveFallbackRoute(\n\t\t\t\t\tdecision,\n\t\t\t\t\t\"medium_exhausted_fallback_expensive\",\n\t\t\t\t\t\"Medium model exhausted: quota; falling back to expensive model\",\n\t\t\t\t);\n\t\t\t\tif (fallback) return fallback;\n\t\t\t}\n\t\t\tthis._lastModelRouterSkipReason = `${decision.tier} model exhausted: quota`;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (settings.fitnessGate) {\n\t\t\tconst verdict = this._evaluateModelFitness(this._routerSurfaceForTier(decision.tier), resolved.model);\n\t\t\tif (!verdict.fit) {\n\t\t\t\tif (decision.tier === \"medium\") {\n\t\t\t\t\tconst failure = this._formatFitnessFailure(verdict);\n\t\t\t\t\tconst fallback = this._resolveExpensiveFallbackRoute(\n\t\t\t\t\t\tdecision,\n\t\t\t\t\t\t\"medium_unfit_fallback_expensive\",\n\t\t\t\t\t\t`Medium model is unfit (${failure}); falling back to expensive model`,\n\t\t\t\t\t);\n\t\t\t\t\tif (fallback) return fallback;\n\t\t\t\t}\n\t\t\t\tthis._lastModelRouterSkipReason = `${decision.tier} model unfit: ${this._formatFitnessFailure(verdict)} (fitness gate)`;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\tthis._lastModelRouterSkipReason = undefined;\n\t\tdecision.model = resolvedName;\n\t\treturn { decision, model: resolved.model };\n\t}\n\n\tprivate _resolveModelRouterModelForIntent(intent: ModelRouterIntent): Model<Api> | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst modelPattern = intent === \"research\" ? settings.cheapModel : settings.expensiveModel;\n\t\tif (!modelPattern) return undefined;\n\t\tconst resolved = resolveCliModel({ cliModel: modelPattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return undefined;\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\treturn this.deps.isModelExhausted(resolved.model) ? undefined : resolved.model;\n\t}\n\n\tresolveConfiguredTierModel(tier: \"cheap\" | \"medium\" | \"expensive\"): Model<Api> | undefined {\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst pattern =\n\t\t\ttier === \"cheap\" ? settings.cheapModel : tier === \"medium\" ? settings.mediumModel : settings.expensiveModel;\n\t\tif (!pattern) return undefined;\n\t\tconst resolved = resolveCliModel({ cliModel: pattern, modelRegistry: this.deps.getModelRegistry() });\n\t\tif (!resolved.model) return undefined;\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(resolved.model)) return undefined;\n\t\treturn this.deps.isModelExhausted(resolved.model) ? undefined : resolved.model;\n\t}\n\n\t/**\n\t * Router resolution with the routing judge (auto-on with the router): the regex classifier's\n\t * decision is the baseline; when a judge model resolves (judgeModel, else mediumModel), one\n\t * bounded, tool-less completion may move the tier between cheap/medium/expensive — never to\n\t * learning. Core rule encoded in the judge prompt: planning is never cheap unless genuinely\n\t * trivial. Every fallback stays visible in the decision reasons, and judge spend reports\n\t * through spawned-usage accounting.\n\t */\n\tasync resolveTurnRouteJudged(\n\t\tprompt: string,\n\t\toptions?: { skipJudge?: boolean },\n\t): Promise<{ decision: RouteDecision; model: Model<Api> } | undefined> {\n\t\tconst baseline = this._resolveModelRouterTurnRoute(prompt);\n\t\tif (!baseline) return undefined;\n\t\tif (options?.skipJudge) return baseline;\n\t\t// Deterministic executor routes need no judge (Level-0 already decided).\n\t\tif (baseline.decision.reasonCode === \"executor_direct\") return baseline;\n\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tif (!settings.judgeEnabled) return baseline;\n\t\tconst judgePattern = settings.judgeModel ?? settings.mediumModel;\n\t\tif (!judgePattern) return baseline;\n\t\tconst judgeModel = this.deps.resolveLaneModel(judgePattern);\n\t\tif (!judgeModel) return baseline;\n\t\tif (settings.fitnessGate) {\n\t\t\tconst verdict = this._evaluateModelFitness(\"router_judge\", judgeModel);\n\t\t\tif (!verdict.fit) {\n\t\t\t\treturn {\n\t\t\t\t\tdecision: {\n\t\t\t\t\t\t...baseline.decision,\n\t\t\t\t\t\treasons: [\n\t\t\t\t\t\t\t...baseline.decision.reasons,\n\t\t\t\t\t\t\t`routing judge skipped: ${formatModelRouterModel(judgeModel)} unfit (${this._formatFitnessFailure(verdict)})`,\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tmodel: baseline.model,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet spentUsage: Usage | undefined;\n\t\tconst judged = await runRouteJudge({\n\t\t\tprompt,\n\t\t\tbaseline: baseline.decision,\n\t\t\tsignal: this.deps.getReflectionSignal(),\n\t\t\tcomplete: async ({ systemPrompt, userPrompt, signal }) => {\n\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t\tmessages: [{ role: \"user\", content: [{ type: \"text\", text: userPrompt }], timestamp: Date.now() }],\n\t\t\t\t\tmodel: judgeModel,\n\t\t\t\t\t// Per-tier thinking (R1): judgeThinking overrides the judge's own completion; unset\n\t\t\t\t\t// keeps today's \"off\" (the judge is a cheap classification call by default).\n\t\t\t\t\tthinkingLevel: settings.judgeThinking ?? \"off\",\n\t\t\t\t\tmaxTokens: ROUTE_JUDGE_MAX_OUTPUT_TOKENS,\n\t\t\t\t\tsignal,\n\t\t\t\t\t// The judge system prompt is static — the provider can cache the prefix.\n\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t});\n\t\t\t\tspentUsage = completion.usage;\n\t\t\t\treturn {\n\t\t\t\t\ttext: completion.text,\n\t\t\t\t\tcostUsd: completion.usage.cost.total,\n\t\t\t\t\tstopReason: String(completion.stopReason),\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t\tif (spentUsage && (spentUsage.cost.total > 0 || spentUsage.totalTokens > 0)) {\n\t\t\tthis.deps.addSpawnedUsage(spentUsage, { label: \"router-judge\" });\n\t\t}\n\n\t\tif (!judged.verdict || judged.decision.tier === baseline.decision.tier) {\n\t\t\t// Same tier (or judge fell back): keep the baseline model, carry the annotated decision.\n\t\t\treturn { decision: judged.decision, model: baseline.model };\n\t\t}\n\n\t\tconst judgedTier = judged.decision.tier;\n\t\tif (judgedTier !== \"cheap\" && judgedTier !== \"medium\" && judgedTier !== \"expensive\") {\n\t\t\treturn { decision: baseline.decision, model: baseline.model };\n\t\t}\n\t\tconst judgedModel = this.resolveConfiguredTierModel(judgedTier);\n\t\tif (!judgedModel) {\n\t\t\treturn {\n\t\t\t\tdecision: {\n\t\t\t\t\t...baseline.decision,\n\t\t\t\t\treasons: [\n\t\t\t\t\t\t...baseline.decision.reasons,\n\t\t\t\t\t\t`Route judge chose ${judgedTier} but no model resolves for that tier; baseline kept`,\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tmodel: baseline.model,\n\t\t\t};\n\t\t}\n\t\treturn { decision: { ...judged.decision, model: formatModelRouterModel(judgedModel) }, model: judgedModel };\n\t}\n\n\t// biome-ignore lint/correctness/noUnusedPrivateClassMembers: test seam\n\tprivate _resolveModelRouterTurnModel(prompt: string): Model<Api> | undefined {\n\t\tconst resolved = this._resolveModelRouterTurnRoute(prompt);\n\t\treturn resolved?.model;\n\t}\n\n\tgetStatus(formatLabel?: (label: string) => string): string {\n\t\tconst recentDecisions = getRecentModelRouterDecisions(this.deps.getSessionManager().getEntries());\n\t\tconst lastDecision = this._lastModelRouterDecision ?? recentDecisions.at(-1);\n\t\tconst historicalDecisions = this._lastModelRouterDecision ? recentDecisions : recentDecisions.slice(0, -1);\n\t\tconst settings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\tconst lines = [\n\t\t\tformatModelRouterStatus(\n\t\t\t\tsettings,\n\t\t\t\tlastDecision,\n\t\t\t\tformatLabel,\n\t\t\t\thistoricalDecisions,\n\t\t\t\tthis._lastModelRouterSkipReason,\n\t\t\t\tthis._lastModelRouterIntent ?? lastDecision?.intent,\n\t\t\t\tsettings.fitnessGate ? this._getRouterTierFitnessStatuses() : undefined,\n\t\t\t\tthis.deps.getFailoverStatus(),\n\t\t\t),\n\t\t];\n\t\tconst diagnostics = collectModelRouterConfigDiagnostics(\n\t\t\tsettings,\n\t\t\tthis.deps.getModelRegistry(),\n\t\t\tthis.deps.getAgentDir(),\n\t\t);\n\t\tif (diagnostics.length > 0) {\n\t\t\tlines.push(formatLabel ? formatLabel(\"Config diagnostics:\") : \"Config diagnostics:\");\n\t\t\tfor (const diagnostic of diagnostics) {\n\t\t\t\tlines.push(`- ${diagnostic}`);\n\t\t\t}\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tasync runRoutedTurn(\n\t\tmessages: AgentMessage | AgentMessage[],\n\t\troutedModel: Model<Api> | undefined,\n\t\trouteDecision: RouteDecision | undefined,\n\t\tpersistDecision = true,\n\t): Promise<void> {\n\t\tif (!routedModel) {\n\t\t\tawait this.deps.runAgentPrompt(messages);\n\t\t\treturn;\n\t\t}\n\n\t\tconst agent = this.deps.getAgent();\n\t\tconst previousModel = agent.state.model;\n\t\tconst previousThinkingLevel = agent.state.thinkingLevel;\n\t\tconst previousTurnTools = agent.state.tools;\n\t\tconst previousSystemPrompt = agent.state.systemPrompt;\n\t\t// G4 swap bookkeeping (Bug G): the exact references the swap below assigns, so the finally can\n\t\t// restore ONLY what IT put there — never assigned when no swap happens (e.g. a full-class\n\t\t// routed profile).\n\t\tlet swappedTools: typeof previousTurnTools | undefined;\n\t\tlet swappedSystemPrompt: typeof previousSystemPrompt | undefined;\n\t\tconst previousActiveModelRouterIntent = this._activeModelRouterIntent;\n\t\tconst previousActiveModelRouterRoute = this._activeModelRouterRoute;\n\t\tconst previousModelRouterSessionBuffer = this._modelRouterSessionBuffer;\n\t\tconst previousModelRouterEscalationRequested = this._modelRouterEscalationRequested;\n\t\tconst bufferRoutedTurn = routeDecision?.tier === \"cheap\";\n\t\tconst originalHistoryLength = agent.state.messages.length;\n\t\tlet retryModel: Model<Api> | undefined;\n\t\tlet completedDecision: ModelRouterDecisionStatus | undefined = routeDecision\n\t\t\t? {\n\t\t\t\t\troute: routeDecision,\n\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\toutcome: \"routed\",\n\t\t\t\t\tintent: routeDecision.tier === \"cheap\" ? \"research\" : \"modify\",\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tlet thrownError: unknown;\n\t\tif (routeDecision) {\n\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t}\n\t\tthis._activeModelRouterIntent = routeDecision\n\t\t\t? routeDecision.tier === \"cheap\"\n\t\t\t\t? \"research\"\n\t\t\t\t: \"modify\"\n\t\t\t: undefined;\n\t\tthis._activeModelRouterRoute = routeDecision;\n\t\tif (bufferRoutedTurn) {\n\t\t\tthis._modelRouterSessionBuffer = createModelRouterSessionBuffer();\n\t\t\tthis._modelRouterEscalationRequested = false;\n\t\t}\n\t\tif (!modelsAreEqual(this.deps.getModel(), routedModel)) {\n\t\t\tagent.state.model = routedModel;\n\t\t\t// Per-tier thinking (R1): a configured tier/executor thinking level overrides the inherited\n\t\t\t// session thinking for THIS routed turn only; unset falls back to exactly today's\n\t\t\t// inherit-and-clamp behavior. Executor routes carry tier \"cheap\" too, so reasonCode is\n\t\t\t// checked first — otherwise an executor turn would silently pick up cheapThinking instead.\n\t\t\t// The judge's own completion has a separate knob (judgeThinking) applied at its call site.\n\t\t\tconst routerThinkingSettings = this.deps.getSettingsManager().getModelRouterSettings();\n\t\t\tconst configuredThinking = !routeDecision\n\t\t\t\t? undefined\n\t\t\t\t: routeDecision.reasonCode === \"executor_direct\"\n\t\t\t\t\t? routerThinkingSettings.executorThinking\n\t\t\t\t\t: routeDecision.tier === \"cheap\"\n\t\t\t\t\t\t? routerThinkingSettings.cheapThinking\n\t\t\t\t\t\t: routeDecision.tier === \"medium\"\n\t\t\t\t\t\t\t? routerThinkingSettings.mediumThinking\n\t\t\t\t\t\t\t: routeDecision.tier === \"expensive\"\n\t\t\t\t\t\t\t\t? routerThinkingSettings.expensiveThinking\n\t\t\t\t\t\t\t\t: undefined;\n\t\t\tagent.state.thinkingLevel = clampThinkingLevel(\n\t\t\t\troutedModel,\n\t\t\t\tconfiguredThinking ?? previousThinkingLevel,\n\t\t\t) as ThinkingLevel;\n\t\t\t// G4: capability tool-filtering follows the ROUTED model for the turn. Without this a\n\t\t\t// cheap/local routed model inherits the session model's full tool surface — schemas it\n\t\t\t// pays for on every request and may not be able to drive at all.\n\t\t\tconst routedProfile = deriveModelCapabilityProfile({\n\t\t\t\tcontextWindow: routedModel.contextWindow,\n\t\t\t\tmode: this.deps.getSettingsManager().getModelCapabilitySettings().mode,\n\t\t\t});\n\t\t\tif (routedProfile.class !== \"full\") {\n\t\t\t\tconst allowed = new Set(\n\t\t\t\t\tfilterToolNamesForCapability(\n\t\t\t\t\t\tpreviousTurnTools.map((tool) => tool.name),\n\t\t\t\t\t\troutedProfile,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tswappedTools = previousTurnTools.filter((tool) => allowed.has(tool.name));\n\t\t\t\tagent.state.tools = swappedTools;\n\t\t\t\t// G4: the system prompt follows the ROUTED model's filtered surface too — otherwise the\n\t\t\t\t// cheap/local model is billed for (and told about) tool guidelines/snippets it can't call.\n\t\t\t\t// Per-turn only; restored in the finally. A live extension override of the prompt is left\n\t\t\t\t// alone (only shed when we're on the base prompt).\n\t\t\t\tif (agent.state.systemPrompt === this.deps.getBaseSystemPrompt()) {\n\t\t\t\t\tswappedSystemPrompt = this.deps.buildSystemPromptForToolNames(\n\t\t\t\t\t\tagent.state.tools.map((tool) => tool.name),\n\t\t\t\t\t);\n\t\t\t\t\tagent.state.systemPrompt = swappedSystemPrompt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tawait this.deps.runAgentPrompt(messages);\n\t\t\t// Speculative muscle-retry (G16 refinement): an executor-routed turn is a bet that the\n\t\t\t// small model can run the toolkit command directly. If it ends WITHOUT a successful\n\t\t\t// run_toolkit_script execution, retry ONCE on the same executor with the brain's\n\t\t\t// refined instruction injected — the brain warms while the muscle tries, so the retry\n\t\t\t// pays only when the muscle actually missed.\n\t\t\tif (\n\t\t\t\trouteDecision?.reasonCode === \"executor_direct\" &&\n\t\t\t\t!this._isModelRouterRetry &&\n\t\t\t\t!this._executorTurnExecutedScript(originalHistoryLength)\n\t\t\t) {\n\t\t\t\tconst refined = await this._buildExecutorRefinedPrompt(messages);\n\t\t\t\tif (refined) {\n\t\t\t\t\tagent.state.messages.splice(originalHistoryLength);\n\t\t\t\t\tawait this.deps.runAgentPrompt([\n\t\t\t\t\t\t{ role: \"user\", content: [{ type: \"text\", text: refined }], timestamp: Date.now() },\n\t\t\t\t\t]);\n\t\t\t\t\tcompletedDecision = {\n\t\t\t\t\t\troute: {\n\t\t\t\t\t\t\t...routeDecision,\n\t\t\t\t\t\t\treasonCode: \"executor_speculative_retry\",\n\t\t\t\t\t\t\treasons: [\n\t\t\t\t\t\t\t\t...routeDecision.reasons,\n\t\t\t\t\t\t\t\t\"Executor missed on first try; retried with brain-refined instruction\",\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\t\toutcome: \"routed\",\n\t\t\t\t\t\tintent: \"research\",\n\t\t\t\t\t};\n\t\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t\t} else {\n\t\t\t\t\t// The muscle missed AND the reflex brain could not refine the request into a toolkit\n\t\t\t\t\t// instruction (no fit brain model, or no confident plan). There is deliberately NO\n\t\t\t\t\t// frontier fallback here, so surface the miss instead of letting it stand silently —\n\t\t\t\t\t// otherwise the routed turn just ends with an unrun command and no explanation.\n\t\t\t\t\tthis.deps.emit({\n\t\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Executor lane: the toolkit command did not run and the reflex brain could not refine it into an explicit instruction; leaving the turn as-is (no automatic escalation).\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bufferRoutedTurn && this._modelRouterEscalationRequested) {\n\t\t\t\tagent.state.messages.splice(originalHistoryLength);\n\t\t\t\tretryModel = this._resolveModelRouterModelForIntent(\"modify\") ?? previousModel;\n\t\t\t\tcompletedDecision = {\n\t\t\t\t\troute: routeDecision!,\n\t\t\t\t\troutedModel: formatModelRouterModel(routedModel),\n\t\t\t\t\toutcome: \"escalated\",\n\t\t\t\t\tretryModel: formatModelRouterModel(retryModel),\n\t\t\t\t\tintent: routeDecision!.tier === \"cheap\" ? \"research\" : \"modify\",\n\t\t\t\t};\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t} else if (bufferRoutedTurn && this._modelRouterSessionBuffer) {\n\t\t\t\tflushModelRouterSessionBuffer(\n\t\t\t\t\tthis._modelRouterSessionBuffer,\n\t\t\t\t\t(message) => {\n\t\t\t\t\t\tthis.deps.getSessionManager().appendMessage(message);\n\t\t\t\t\t},\n\t\t\t\t\t(customType, content, display, details) => {\n\t\t\t\t\t\tthis.deps.getSessionManager().appendCustomMessageEntry(customType, content, display, details);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrownError = error;\n\t\t\tif (completedDecision) {\n\t\t\t\tcompletedDecision = { ...completedDecision, outcome: \"failed\" };\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t}\n\t\t} finally {\n\t\t\t// Restore the pre-route model ONLY if the routed model is still in place: a command\n\t\t\t// handler may have legitimately changed the session model mid-turn (setModel or a\n\t\t\t// provider re-registration), and clobbering that would silently undo the change.\n\t\t\tif (modelsAreEqual(agent.state.model, routedModel)) {\n\t\t\t\tagent.state.model = previousModel;\n\t\t\t\tagent.state.thinkingLevel = previousThinkingLevel;\n\t\t\t\t// Symmetric restore (Bug G): undo tools/systemPrompt only if each is STILL the exact\n\t\t\t\t// reference/string the G4 swap above assigned (never assigned at all when the routed\n\t\t\t\t// profile was full-class — then there is nothing to restore either). An extension calling\n\t\t\t\t// setActiveToolsByName mid-turn reassigns both to its own values without touching the\n\t\t\t\t// model — the model guard above still passes, but that live change is legitimate and must\n\t\t\t\t// survive rather than being silently reverted to the stale pre-turn snapshot.\n\t\t\t\tif (swappedTools !== undefined && agent.state.tools === swappedTools) {\n\t\t\t\t\tagent.state.tools = previousTurnTools;\n\t\t\t\t}\n\t\t\t\tif (swappedSystemPrompt !== undefined && agent.state.systemPrompt === swappedSystemPrompt) {\n\t\t\t\t\tagent.state.systemPrompt = previousSystemPrompt;\n\t\t\t\t}\n\t\t\t\t// The registry may have changed mid-turn (command-time registerProvider): re-resolve\n\t\t\t\t// the restored model so a provider override is not dropped with the routed model.\n\t\t\t\tthis.deps.refreshCurrentModelFromRegistry();\n\t\t\t}\n\t\t\tthis._activeModelRouterIntent = previousActiveModelRouterIntent;\n\t\t\tthis._activeModelRouterRoute = previousActiveModelRouterRoute;\n\t\t\tthis._modelRouterSessionBuffer = previousModelRouterSessionBuffer;\n\t\t\tthis._modelRouterEscalationRequested = previousModelRouterEscalationRequested;\n\t\t}\n\n\t\tif (retryModel && !thrownError) {\n\t\t\tconst previousIsModelRouterRetry = this._isModelRouterRetry;\n\t\t\ttry {\n\t\t\t\tthis._isModelRouterRetry = true;\n\t\t\t\tconst retryDecision: RouteDecision = {\n\t\t\t\t\ttier: \"expensive\",\n\t\t\t\t\trisk: \"high-impact\",\n\t\t\t\t\tconfidence: 1.0,\n\t\t\t\t\treasonCode: \"cheap_mutating_tool_escalation\",\n\t\t\t\t\treasons: [\"Cheap research turn attempted a mutating tool and escalated\"],\n\t\t\t\t\tfallbackFrom: \"cheap\",\n\t\t\t\t\tmodel: formatModelRouterModel(retryModel),\n\t\t\t\t};\n\t\t\t\tawait this.runRoutedTurn(messages, retryModel, retryDecision, false);\n\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t} catch (error) {\n\t\t\t\tthrownError = error;\n\t\t\t\tif (completedDecision) {\n\t\t\t\t\tcompletedDecision = { ...completedDecision, outcome: \"failed\" };\n\t\t\t\t\tthis._lastModelRouterDecision = completedDecision;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tthis._isModelRouterRetry = previousIsModelRouterRetry;\n\t\t\t}\n\t\t}\n\n\t\tif (persistDecision && completedDecision) {\n\t\t\tpersistModelRouterDecision(this.deps.getSessionManager(), completedDecision);\n\t\t\t// G3: one route event per user-facing routed turn (the escalation retry runs with\n\t\t\t// persistDecision=false, so it does not double-emit). Codes/numbers only — no prompt text.\n\t\t\tthis.deps.emitAutonomyTelemetry({\n\t\t\t\ttype: AUTONOMY_TELEMETRY_EVENT_TYPES.routeDecision,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tpayload: {\n\t\t\t\t\ttier: completedDecision.route.tier,\n\t\t\t\t\trisk: completedDecision.route.risk,\n\t\t\t\t\treasonCode: completedDecision.route.reasonCode,\n\t\t\t\t\tconfidence: completedDecision.route.confidence,\n\t\t\t\t\toutcome: completedDecision.outcome,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (thrownError) {\n\t\t\tthrow thrownError;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -51,12 +51,16 @@ export interface RuntimeBuilderDeps {
|
|
|
51
51
|
getAgent(): Agent;
|
|
52
52
|
/** Workspace root, passed to the tool-definition factory and the extension runner. */
|
|
53
53
|
getCwd(): string;
|
|
54
|
+
/** Agent state root, including the host-keyed fitness store. */
|
|
55
|
+
getAgentDir(): string;
|
|
54
56
|
/** Session log, passed to the extension runner. */
|
|
55
57
|
getSessionManager(): SessionManager;
|
|
56
58
|
/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */
|
|
57
59
|
getSettingsManager(): SettingsManager;
|
|
58
60
|
/** Model registry, passed to the extension runner and profile model re-resolution. */
|
|
59
61
|
getModelRegistry(): ModelRegistry;
|
|
62
|
+
/** Session-scoped provider/model quota exhaustion guard. */
|
|
63
|
+
isModelExhausted(model: Model<Api>): boolean;
|
|
60
64
|
/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */
|
|
61
65
|
getResourceLoader(): ResourceLoader;
|
|
62
66
|
/** Live extension runner (host-owned; pervasive). */
|
|
@@ -172,6 +176,7 @@ export declare class RuntimeBuilder {
|
|
|
172
176
|
private _baseToolDefinitions;
|
|
173
177
|
private readonly deps;
|
|
174
178
|
constructor(deps: RuntimeBuilderDeps);
|
|
179
|
+
private _runContextScout;
|
|
175
180
|
/** Whether a tool name is present in the live wrapped registry. */
|
|
176
181
|
hasTool(name: string): boolean;
|
|
177
182
|
/** The live wrapped tool for a name, if registered (activation lookup). */
|
|
@@ -219,4 +224,15 @@ export declare class RuntimeBuilder {
|
|
|
219
224
|
*/
|
|
220
225
|
reconcileLoadedExtensions(): Promise<void>;
|
|
221
226
|
}
|
|
227
|
+
export declare function resolveScoutModel(modelRegistry: ModelRegistry, modelSetting: string, agentDir: string, isModelExhausted?: (model: Model<Api>) => boolean): Promise<{
|
|
228
|
+
failure: string;
|
|
229
|
+
model?: undefined;
|
|
230
|
+
apiKey?: undefined;
|
|
231
|
+
headers?: undefined;
|
|
232
|
+
} | {
|
|
233
|
+
failure?: undefined;
|
|
234
|
+
model: Model<Api>;
|
|
235
|
+
apiKey: string | undefined;
|
|
236
|
+
headers: Record<string, string> | undefined;
|
|
237
|
+
}>;
|
|
222
238
|
//# sourceMappingURL=runtime-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-builder.d.ts","sourceRoot":"","sources":["../../src/core/runtime-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime build & reload: the session's tool-registry assembly and the self-modification-safe\n * extension reload path. Owns building the base tool definitions, wrapping them into the live tool\n * registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime\n * (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded\n * `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension\n * live load/unload/reconcile operations that rebuild the runtime in place.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry\n * state — the base tool definitions, the wrapped tool registry, the definition registry, and the\n * per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live\n * {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the\n * resource loader, the session/settings managers, the model registry, the profile tool filter and\n * its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many\n * host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors\n * that read and write the SAME storage the host owns today.\n *\n * Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot\n * spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`\n * / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through\n * {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields\n * they mutated before extraction; only the five tool-registry maps are captured by direct field\n * reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into\n * {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at\n * every assignment site), so no observer runs between the two writes.\n *\n * Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public\n * surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays\n * host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};\n * it is host identity, not build logic, and moving it would only re-export ~30 host methods through\n * deps to hand them straight back. The host keeps one-line delegations for the public reload /\n * load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private\n * `_refreshToolRegistry` delegation for its internal callers.\n */\n\nimport type { Agent, AgentContext, AgentMessage, AgentTool } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model, Usage } from \"@caupulican/pi-ai\";\nimport { resetApiProviders } from \"@caupulican/pi-ai\";\nimport type {\n\tIsolatedCompletionOptions,\n\tIsolatedCompletionResult,\n\tWorkerDelegationRunOutcome,\n} from \"./agent-session.ts\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"./context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"./context-gc.ts\";\nimport { createCoreDiagnosticsToolDefinitions } from \"./extensions/builtin.ts\";\nimport {\n\ttype ContextUsage,\n\ttype Extension,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolInfo,\n\twrapRegisteredTools,\n} from \"./extensions/index.ts\";\nimport { disposeExtensionEventSubscriptions } from \"./extensions/loader.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { GoalState } from \"./goals/goal-state.ts\";\nimport type { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport type { ModelFitnessReport } from \"./research/model-fitness.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport {\n\tmatchesResourceProfilePattern,\n\ttype ResourceProfileFilterSettings,\n\ttype SettingsManager,\n} from \"./settings-manager.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\nimport { executeToolkitScript } from \"./toolkit/script-runner.ts\";\nimport { createDelegateToolDefinition } from \"./tools/delegate.ts\";\nimport { createGoalToolDefinition } from \"./tools/goal.ts\";\nimport { createAllToolDefinitions } from \"./tools/index.ts\";\nimport { createModelFitnessToolDefinition } from \"./tools/model-fitness.ts\";\nimport { createRunToolkitScriptToolDefinition } from \"./tools/run-toolkit-script.ts\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.ts\";\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ninterface ReloadRuntimeSnapshot {\n\textensionRunner: ExtensionRunner;\n\tbaseToolDefinitions: Map<string, ToolDefinition>;\n\ttoolRegistry: Map<string, AgentTool>;\n\ttoolDefinitions: Map<string, ToolDefinitionEntry>;\n\ttoolPromptSnippets: Map<string, string>;\n\ttoolPromptGuidelines: Map<string, string[]>;\n\tagentTools: AgentTool[];\n\tagentSystemPrompt: string;\n\tbaseSystemPrompt: string;\n}\n\nexport interface RuntimeBuilderDeps {\n\t/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */\n\tgetAgent(): Agent;\n\t/** Workspace root, passed to the tool-definition factory and the extension runner. */\n\tgetCwd(): string;\n\t/** Session log, passed to the extension runner. */\n\tgetSessionManager(): SessionManager;\n\t/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Model registry, passed to the extension runner and profile model re-resolution. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */\n\tgetResourceLoader(): ResourceLoader;\n\n\t/** Live extension runner (host-owned; pervasive). */\n\tgetExtensionRunner(): ExtensionRunner;\n\t/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */\n\tsetExtensionRunner(runner: ExtensionRunner): void;\n\t/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */\n\tgetBaseSystemPrompt(): string;\n\tsetBaseSystemPrompt(prompt: string): void;\n\n\t/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */\n\tgetCustomTools(): ToolDefinition[];\n\t/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */\n\tgetBaseToolsOverride(): Record<string, AgentTool> | undefined;\n\t/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tsetRequestedActiveToolNames(names: string[] | undefined): void;\n\n\t/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */\n\tgetToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;\n\tsetToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;\n\tgetAllowedToolNames(): Set<string> | undefined;\n\tgetExcludedToolNames(): Set<string> | undefined;\n\t/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */\n\tderiveToolProfileFilter(): Required<ResourceProfileFilterSettings>;\n\t/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */\n\tisToolOrCommandAllowedByProfile(name: string): boolean;\n\t/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */\n\tfilterExtensionsForRuntime(extensions: Extension[]): Extension[];\n\t/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */\n\tsetUnboundToolGrantWarnings(warnings: string[]): void;\n\n\t/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */\n\tgetActiveToolNames(): string[];\n\t/** Apply the recomputed active set (capability filter + companion auto-activation live here). */\n\tsetActiveToolsByName(toolNames: string[]): void;\n\t/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */\n\tnormalizePromptSnippet(text: string | undefined): string | undefined;\n\tnormalizePromptGuidelines(guidelines: string[] | undefined): string[];\n\n\t/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */\n\tbindExtensionCore(runner: ExtensionRunner): void;\n\t/** Re-apply UI context / mode / command-context / error subscription to a runner. */\n\tapplyExtensionBindings(runner: ExtensionRunner): void;\n\t/** Re-run resource discovery for the active extensions (reload only). */\n\textendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void>;\n\t/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */\n\treapplyActiveProfileModelSettings(): Promise<void>;\n\t/** Notify extensions-changed listeners after a single-extension live op. */\n\tnotifyExtensionsChanged(): void;\n\n\t/** Session-scoped tool-output artifact store for grep/find/artifact_retrieve (gated on the profile). */\n\tgetToolArtifactStore(): ArtifactStore;\n\n\t/** Live memory manager — its provider tools join the registry. */\n\tgetMemoryManager(): MemoryManager;\n\t/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */\n\tgetMemoryAuditDiagnostics(): { retrieval: MemoryRetrievalDiagnostics; promptInclusion: MemoryPromptInclusionReport };\n\t/** Drop extension-contributed pending memory providers before a reload re-registers them. */\n\tclearPendingMemoryProviders(): void;\n\t/** (Re)derive the memory subsystem from reloaded settings/providers. */\n\tinitializeMemory(): Promise<void>;\n\n\t/** Goal-tool state accessors. */\n\tgetGoalStateSnapshot(): GoalState | undefined;\n\tsaveGoalStateSnapshot(state: GoalState): string;\n\t/** Context-gc report for the core diagnostics tool. */\n\tgetContextGcReport(messages: AgentMessage[]): ContextGcReport;\n\t/** Worker-delegation runner for the delegate tool. */\n\trunWorkerDelegationOnce(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t}): Promise<WorkerDelegationRunOutcome>;\n\t/** Model-fitness probe for the model_fitness tool. */\n\trunModelFitness(args: {\n\t\tmodel: string;\n\t\ttrials?: number;\n\t}): Promise<{ started: true; model: string; report: ModelFitnessReport } | { started: false; skipReason: string }>;\n\t/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n\t/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Roll reflex-brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\n\t/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */\n\tcreateAgentContextSnapshot(): AgentContext;\n\tgetContextUsage(): ContextUsage | undefined;\n\n\t/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */\n\tisStreaming(): boolean;\n\tisCompacting(): boolean;\n\n\t/** Extension bindings present — gate for re-emitting session_start on reload. */\n\tgetExtensionUIContext(): ExtensionUIContext | undefined;\n\tgetExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;\n\tgetExtensionShutdownHandler(): ShutdownHandler | undefined;\n\tgetExtensionErrorListener(): ExtensionErrorListener | undefined;\n}\n\n/**\n * Owns the tool-registry build and the self-modification-safe extension reload extracted from\n * {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.\n */\nexport class RuntimeBuilder {\n\t// Tool registry for extension getTools/setTools\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\n\tprivate readonly deps: RuntimeBuilderDeps;\n\n\tconstructor(deps: RuntimeBuilderDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** Whether a tool name is present in the live wrapped registry. */\n\thasTool(name: string): boolean {\n\t\treturn this._toolRegistry.has(name);\n\t}\n\n\t/** The live wrapped tool for a name, if registered (activation lookup). */\n\tgetRegisteredTool(name: string): AgentTool | undefined {\n\t\treturn this._toolRegistry.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt snippet, if any. */\n\tgetToolPromptSnippet(name: string): string | undefined {\n\t\treturn this._toolPromptSnippets.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt guidelines, if any. */\n\tgetToolPromptGuidelines(name: string): string[] | undefined {\n\t\treturn this._toolPromptGuidelines.get(name);\n\t}\n\n\t/**\n\t * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.\n\t */\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tpromptGuidelines: definition.promptGuidelines,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\trefreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\t// Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is\n\t\t// capability/profile-filtered, so feeding it back through setActiveToolsByName would\n\t\t// permanently shrink what a later switch to a larger model (or permissive profile) restores.\n\t\tconst previousActiveToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst allowedToolNames = this.deps.getAllowedToolNames();\n\t\tconst excludedToolNames = this.deps.getExcludedToolNames();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst isAllowedTool = (name: string): boolean => {\n\t\t\tif (allowedToolNames && !allowedToolNames.has(name)) return false;\n\t\t\tif (excludedToolNames?.has(name)) return false;\n\t\t\tif (!toolProfileFilter) return true;\n\t\t\tif (toolProfileFilter.allow.length > 0 && !matchesResourceProfilePattern(name, toolProfileFilter.allow)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (matchesResourceProfilePattern(name, toolProfileFilter.block)) return false;\n\t\t\treturn true;\n\t\t};\n\n\t\tconst registeredTools = this.deps.getExtensionRunner().getAllRegisteredTools();\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this.deps.getCustomTools().map((definition) => ({\n\t\t\t\tdefinition,\n\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t})),\n\t\t\t// Memory subsystem provider tools (e.g. file-store's `memory` tool).\n\t\t\t...this.deps\n\t\t\t\t.getMemoryManager()\n\t\t\t\t.getToolDefinitions()\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t\t})),\n\t\t].filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: \"builtin\" }),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this.deps.normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this.deps.normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this.deps.getExtensionRunner();\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\trunner,\n\t\t);\n\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];\n\t\tconst nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));\n\n\t\tconst autoActivated: string[] = [];\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t\tautoActivated.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Strict UAC: the active profile is the COMPLETE grant, so a tool the profile names\n\t\t// explicitly is itself a request for that tool — it must ACTIVATE from the registry even\n\t\t// if the session never requested it. Without this, activation is only ever the requested\n\t\t// defaults ∩ allow-list, and a profile granting non-default tools (a search-only profile's\n\t\t// grep/find) yields an empty or truncated tool set on load and /reload. A blanket \"*\"\n\t\t// stays grant-only: activation then still derives from the request/defaults above.\n\t\tconst explicitAllowPatterns = toolProfileFilter?.allow.filter((pattern) => pattern !== \"*\") ?? [];\n\t\tif (explicitAllowPatterns.length > 0) {\n\t\t\tconst boundPatterns = new Set<string>();\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!isAllowedTool(toolName)) continue;\n\t\t\t\tfor (const pattern of explicitAllowPatterns) {\n\t\t\t\t\tif (matchesResourceProfilePattern(toolName, [pattern])) boundPatterns.add(pattern);\n\t\t\t\t}\n\t\t\t\tif (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd\n\t\t\t// name, or the owning extension is not granted/loaded. Surface it.\n\t\t\tthis.deps.setUnboundToolGrantWarnings(\n\t\t\t\texplicitAllowPatterns\n\t\t\t\t\t.filter((pattern) => !boundPatterns.has(pattern))\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(pattern) =>\n\t\t\t\t\t\t\t`profile tool grant \"${pattern}\" binds to no registered tool (typo, or the owning extension is not granted/loaded)`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.deps.setUnboundToolGrantWarnings([]);\n\t\t}\n\n\t\t// artifact_retrieve companion auto-activation is enforced inside\n\t\t// setActiveToolsByName() itself (not duplicated here), so every activation path --\n\t\t// including the public, extension-exposed setActiveTools() -- gets the same\n\t\t// guarantee, not just this settings/profile refresh flow.\n\t\tthis.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t\t// setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore\n\t\t// the true pre-filter request (plus this refresh's auto-activations) so an internal refresh\n\t\t// can never permanently narrow it.\n\t\tthis.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...autoActivated])]);\n\t}\n\n\tprivate _createReloadRuntimeSnapshot(): ReloadRuntimeSnapshot {\n\t\tconst agent = this.deps.getAgent();\n\t\treturn {\n\t\t\textensionRunner: this.deps.getExtensionRunner(),\n\t\t\tbaseToolDefinitions: this._baseToolDefinitions,\n\t\t\ttoolRegistry: this._toolRegistry,\n\t\t\ttoolDefinitions: this._toolDefinitions,\n\t\t\ttoolPromptSnippets: this._toolPromptSnippets,\n\t\t\ttoolPromptGuidelines: this._toolPromptGuidelines,\n\t\t\tagentTools: agent.state.tools,\n\t\t\tagentSystemPrompt: agent.state.systemPrompt,\n\t\t\tbaseSystemPrompt: this.deps.getBaseSystemPrompt(),\n\t\t};\n\t}\n\n\tprivate _restoreReloadRuntimeSnapshot(snapshot: ReloadRuntimeSnapshot): void {\n\t\t// setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together\n\t\t// (the same field-then-ref pair the host wrote at every assignment site); nothing reads the\n\t\t// ref between the two writes, so folding them is unobservable.\n\t\tthis.deps.setExtensionRunner(snapshot.extensionRunner);\n\t\tthis._baseToolDefinitions = snapshot.baseToolDefinitions;\n\t\tthis._toolRegistry = snapshot.toolRegistry;\n\t\tthis._toolDefinitions = snapshot.toolDefinitions;\n\t\tthis._toolPromptSnippets = snapshot.toolPromptSnippets;\n\t\tthis._toolPromptGuidelines = snapshot.toolPromptGuidelines;\n\t\tconst agent = this.deps.getAgent();\n\t\tagent.state.tools = snapshot.agentTools;\n\t\tagent.state.systemPrompt = snapshot.agentSystemPrompt;\n\t\tthis.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);\n\t\tthis.deps.applyExtensionBindings(snapshot.extensionRunner);\n\t}\n\n\tprivate _doctorReloadRuntime(): void {\n\t\tconst extensionErrors = this.deps.getResourceLoader().getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tconst summary = extensionErrors\n\t\t\t\t.slice(0, 6)\n\t\t\t\t.map((error) => `${error.path}: ${error.error}`)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(`Extension reload failed doctor: ${summary}`);\n\t\t}\n\n\t\tconst missingActiveTools = this.deps.getActiveToolNames().filter((name) => !this._toolRegistry.has(name));\n\t\tif (missingActiveTools.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension reload failed doctor: active tool(s) missing after reload: ${missingActiveTools.join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const tool of this.deps.getAgent().state.tools) {\n\t\t\tif (!this._toolDefinitions.has(tool.name)) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: tool ${tool.name} missing from definition registry`);\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.createAgentContextSnapshot();\n\t\tthis.deps.getContextUsage();\n\t}\n\n\tbuildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t}): void {\n\t\tconst settingsManager = this.deps.getSettingsManager();\n\t\tconst autoResizeImages = settingsManager.getImageAutoResize();\n\t\tconst shellCommandPrefix = settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = settingsManager.getShellPath();\n\t\tconst baseToolsOverride = this.deps.getBaseToolsOverride();\n\t\t// grep/find must not emit a \"Full output: artifact tool-output:<id>\" handle that\n\t\t// nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside\n\t\t// an active allowlist, don't hand grep/find an artifact store at all: they fall\n\t\t// back to their pre-existing bounded preview/truncation behavior, with no\n\t\t// payload/meta files ever written and no retrieval promise made.\n\t\tconst toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile(\"artifact_retrieve\")\n\t\t\t? this.deps.getToolArtifactStore()\n\t\t\t: undefined;\n\t\tconst baseToolDefinitions = baseToolsOverride\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(baseToolsOverride).map(([name, tool]) => [name, createToolDefinitionFromAgentTool(tool)]),\n\t\t\t\t)\n\t\t\t: createAllToolDefinitions(this.deps.getCwd(), {\n\t\t\t\t\tread: { autoResizeImages },\n\t\t\t\t\tbash: { commandPrefix: shellCommandPrefix, shellPath },\n\t\t\t\t\tgrep: { artifactStore: toolArtifactStore },\n\t\t\t\t\tfind: { artifactStore: toolArtifactStore },\n\t\t\t\t\tartifact_retrieve: { artifactStore: toolArtifactStore },\n\t\t\t\t});\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(baseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\t\tif (!baseToolsOverride) {\n\t\t\tfor (const definition of createCoreDiagnosticsToolDefinitions(\n\t\t\t\t() => this.deps.getActiveToolNames(),\n\t\t\t\t() => this.getAllTools(),\n\t\t\t\t(messages) => this.deps.getContextGcReport(messages),\n\t\t\t\t() => this.deps.getMemoryAuditDiagnostics(),\n\t\t\t)) {\n\t\t\t\tthis._baseToolDefinitions.set(definition.name, definition);\n\t\t\t}\n\t\t\tconst goalToolDefinition = createGoalToolDefinition({\n\t\t\t\tgetGoalState: () => this.deps.getGoalStateSnapshot(),\n\t\t\t\tsaveGoalState: (state) => {\n\t\t\t\t\tthis.deps.saveGoalStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);\n\t\t\tconst delegateToolDefinition = createDelegateToolDefinition({\n\t\t\t\trunWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);\n\t\t\t// Registered but not default-active: probes spend tokens on the probed model, so\n\t\t\t// activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).\n\t\t\tconst modelFitnessToolDefinition = createModelFitnessToolDefinition({\n\t\t\t\trunProbe: (args) => this.deps.runModelFitness(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(modelFitnessToolDefinition.name, modelFitnessToolDefinition);\n\t\t\tconst runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({\n\t\t\t\tgetScripts: () => this.deps.getSettingsManager().getToolkitScripts(),\n\t\t\t\texecute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),\n\t\t\t\t// Reflex brain (fitness-gated local model): resolves ambiguous requests into a\n\t\t\t\t// registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.\n\t\t\t\tinterpret: async (request, scripts) => {\n\t\t\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\t\t\tif (!model) return undefined;\n\t\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\t\t\tmessages: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tmaxTokens: 256,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t});\n\t\t\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"toolkit-brain\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn parseReflexPlan(completion.text);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(runToolkitScriptToolDefinition.name, runToolkitScriptToolDefinition);\n\t\t}\n\n\t\tconst extensionsResult = this.deps.getResourceLoader().getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\tconst extensions = this.deps.filterExtensionsForRuntime(extensionsResult.extensions);\n\t\tconst runtimeExtensionPaths = new Set(extensions.map((extension) => extension.path));\n\t\textensionsResult.runtime.pendingProviderRegistrations =\n\t\t\textensionsResult.runtime.pendingProviderRegistrations.filter((registration) =>\n\t\t\t\truntimeExtensionPaths.has(registration.extensionPath),\n\t\t\t);\n\n\t\tconst runner = new ExtensionRunner(\n\t\t\textensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis.deps.getCwd(),\n\t\t\tthis.deps.getSessionManager(),\n\t\t\tthis.deps.getModelRegistry(),\n\t\t);\n\t\tthis.deps.setExtensionRunner(runner);\n\t\tthis.deps.bindExtensionCore(runner);\n\t\tthis.deps.applyExtensionBindings(runner);\n\n\t\tconst defaultActiveToolNames = baseToolsOverride\n\t\t\t? Object.keys(baseToolsOverride)\n\t\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"context_audit\", \"goal\", \"delegate\", \"run_toolkit_script\"];\n\t\tconst baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;\n\t\tthis.refreshToolRegistry({\n\t\t\tactiveToolNames: baseActiveToolNames,\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reload while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reload while context compaction or branch summarization is active\");\n\t\t}\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\tconst snapshot = this._createReloadRuntimeSnapshot();\n\t\t// Preserve the pre-filter tool REQUEST across the rebuild, not the capability/profile-filtered\n\t\t// active set — otherwise a reload under a small model permanently shrinks the restorable set.\n\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\tconst reloadErrors: string[] = [];\n\t\tlet newRunner: ExtensionRunner | undefined;\n\t\ttry {\n\t\t\tawait this.deps.getSettingsManager().reload();\n\t\t\t// Re-derive the resource-profile tool filter from the freshly reloaded settings.\n\t\t\t// Unlike skills/prompts/themes (which re-filter through the resource loader on every\n\t\t\t// reload), the tool filter is held on the session, so without this a live edit to the\n\t\t\t// active profile's tools allow/block — or switching the active profile — would not\n\t\t\t// apply on /reload and allowed tools would stay missing.\n\t\t\tthis.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());\n\t\t\t// Re-apply the active profile's model/thinking from the freshly reloaded settings, so a live\n\t\t\t// profile edit (or switch) takes effect on /reload. Skipped when the launch used an explicit\n\t\t\t// --model/--thinking flag, which must win over the profile across reloads.\n\t\t\tawait this.deps.reapplyActiveProfileModelSettings();\n\t\t\tawait this.deps.getResourceLoader().reload({ failOnExtensionErrors: true, deferExtensionDispose: true });\n\t\t\tresetApiProviders();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tnewRunner = this.deps.getExtensionRunner();\n\t\t\tconst offDoctorErrors = newRunner.onError((error) => {\n\t\t\t\treloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t// Reload starts memory providers fresh; loaded extensions re-register below.\n\t\t\t\tthis.deps.clearPendingMemoryProviders();\n\t\t\t\tconst hasBindings =\n\t\t\t\t\tthis.deps.getExtensionUIContext() ||\n\t\t\t\t\tthis.deps.getExtensionCommandContextActions() ||\n\t\t\t\t\tthis.deps.getExtensionShutdownHandler() ||\n\t\t\t\t\tthis.deps.getExtensionErrorListener();\n\t\t\t\tif (hasBindings) {\n\t\t\t\t\tawait newRunner.emit({ type: \"session_start\", reason: \"reload\" });\n\t\t\t\t\tawait this.deps.extendResourcesFromExtensions(\"reload\");\n\t\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\toffDoctorErrors();\n\t\t\t}\n\t\t\tif (reloadErrors.length > 0) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join(\"; \")}`);\n\t\t\t}\n\t\t\tawait emitSessionShutdownEvent(previousRunner, { type: \"session_shutdown\", reason: \"reload\" });\n\t\t\tpreviousRunner.invalidate();\n\t\t\tthis.deps.getResourceLoader().commitReload?.();\n\t\t\t// Re-derive the memory subsystem from the reloaded settings/providers.\n\t\t\tawait this.deps.initializeMemory();\n\t\t} catch (error) {\n\t\t\tif (newRunner && newRunner !== previousRunner) {\n\t\t\t\tnewRunner.invalidate(\n\t\t\t\t\t\"This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.deps.getResourceLoader().rollbackReload?.();\n\t\t\tthis._restoreReloadRuntimeSnapshot(snapshot);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unload a single extension without full reload.\n\t * Runs the extension's session_shutdown lifecycle, unregisters its providers,\n\t * disposes its event subscriptions, and rebuilds the runtime.\n\t * Falls back to full reload on error.\n\t */\n\tasync unloadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot unload extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot unload extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst ext = this.deps.getResourceLoader().getLoadedExtension(extensionPath);\n\t\tif (!ext) {\n\t\t\treturn; // Nothing to unload\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Run session_shutdown lifecycle for this extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(ext, { type: \"session_shutdown\", reason: \"unload\" });\n\n\t\t\t// Unregister its providers (keyed by the extension's own path, as registered)\n\t\t\tconst runtime = this.deps.getResourceLoader().getExtensions().runtime;\n\t\t\tfor (const name of runtime.getProvidersForExtension(ext.path)) {\n\t\t\t\truntime.unregisterProvider(name, ext.path);\n\t\t\t}\n\n\t\t\t// Dispose its event subscriptions and run disposers\n\t\t\tawait disposeExtensionEventSubscriptions([ext]);\n\n\t\t\t// Remove from loaded extensions\n\t\t\tthis.deps.getResourceLoader().removeLoadedExtension(extensionPath);\n\n\t\t\t// Rebuild runtime with new extension set\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tpreviousRunner.invalidate();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Load a single extension without full reload.\n\t * Loads the extension with fresh import, rebuilds the runtime,\n\t * and runs the extension's session_start lifecycle.\n\t * Falls back to full reload on error.\n\t */\n\tasync loadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot load extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot load extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Load the extension with fresh import\n\t\t\tconst { extension, error } = await this.deps.getResourceLoader().loadSingleExtension(extensionPath);\n\t\t\tif (error || !extension) {\n\t\t\t\tthrow new Error(error || `Failed to load extension: ${extensionPath}`);\n\t\t\t}\n\n\t\t\t// Rebuild runtime to aggregate tools/commands/handlers/providers\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\n\t\t\t// Run session_start lifecycle for the new extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(extension, { type: \"session_start\", reason: \"load\" });\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reconcile loaded extensions with the active profile.\n\t * Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.\n\t * Falls back to full reload if any individual load/unload fails.\n\t */\n\tasync reconcileLoadedExtensions(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while context compaction or branch summarization is active\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Get all discoverable extension paths\n\t\t\tconst allDiscoverablePaths = await this.deps.getResourceLoader().getDiscoverableExtensionPaths();\n\n\t\t\t// Get the target enabled set based on profile filters\n\t\t\tconst targetEnabledSet = new Set<string>();\n\t\t\tfor (const path of allDiscoverablePaths) {\n\t\t\t\tif (this.deps.getSettingsManager().isResourceAllowedByProfile(\"extensions\", path)) {\n\t\t\t\t\ttargetEnabledSet.add(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get currently loaded set\n\t\t\tconst loadedExtensions = this.deps.getResourceLoader().getExtensions().extensions;\n\t\t\tconst loadedSet = new Set<string>();\n\t\t\tfor (const ext of loadedExtensions) {\n\t\t\t\tloadedSet.add(ext.path);\n\t\t\t}\n\n\t\t\t// Collect unloads and loads\n\t\t\tconst toUnload: string[] = [];\n\t\t\tconst toLoad: string[] = [];\n\n\t\t\tfor (const path of loadedSet) {\n\t\t\t\tif (!targetEnabledSet.has(path)) {\n\t\t\t\t\ttoUnload.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of targetEnabledSet) {\n\t\t\t\tif (!loadedSet.has(path)) {\n\t\t\t\t\ttoLoad.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply unloads first, then loads, to minimize churn\n\t\t\t// Collect errors but continue through all operations\n\t\t\tconst errors: Error[] = [];\n\n\t\t\tfor (const path of toUnload) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unloadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of toLoad) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.loadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any errors occurred, throw the first one (already fell back to full reload in load/unload)\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow errors[0];\n\t\t\t}\n\n\t\t\t// Single notification at the end\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runtime-builder.d.ts","sourceRoot":"","sources":["../../src/core/runtime-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime build & reload: the session's tool-registry assembly and the self-modification-safe\n * extension reload path. Owns building the base tool definitions, wrapping them into the live tool\n * registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime\n * (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded\n * `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension\n * live load/unload/reconcile operations that rebuild the runtime in place.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry\n * state — the base tool definitions, the wrapped tool registry, the definition registry, and the\n * per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live\n * {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the\n * resource loader, the session/settings managers, the model registry, the profile tool filter and\n * its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many\n * host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors\n * that read and write the SAME storage the host owns today.\n *\n * Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot\n * spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`\n * / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through\n * {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields\n * they mutated before extraction; only the five tool-registry maps are captured by direct field\n * reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into\n * {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at\n * every assignment site), so no observer runs between the two writes.\n *\n * Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public\n * surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays\n * host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};\n * it is host identity, not build logic, and moving it would only re-export ~30 host methods through\n * deps to hand them straight back. The host keeps one-line delegations for the public reload /\n * load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private\n * `_refreshToolRegistry` delegation for its internal callers.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { Agent, AgentContext, AgentMessage, AgentTool } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model, Usage } from \"@caupulican/pi-ai\";\nimport { resetApiProviders } from \"@caupulican/pi-ai\";\nimport type {\n\tIsolatedCompletionOptions,\n\tIsolatedCompletionResult,\n\tWorkerDelegationRunOutcome,\n} from \"./agent-session.ts\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"./context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"./context-gc.ts\";\nimport { createCoreDiagnosticsToolDefinitions } from \"./extensions/builtin.ts\";\nimport {\n\ttype ContextUsage,\n\ttype Extension,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolInfo,\n\twrapRegisteredTools,\n} from \"./extensions/index.ts\";\nimport { disposeExtensionEventSubscriptions } from \"./extensions/loader.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { GoalState } from \"./goals/goal-state.ts\";\nimport type { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveCliModel } from \"./model-resolver.ts\";\nimport { evaluateSurfaceFitness } from \"./model-router/fitness-gate.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport type { ModelFitnessReport } from \"./research/model-fitness.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { ScoutController } from \"./scout-controller.ts\";\nimport {\n\tmatchesResourceProfilePattern,\n\ttype ResourceProfileFilterSettings,\n\ttype SettingsManager,\n} from \"./settings-manager.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\nimport { executeToolkitScript } from \"./toolkit/script-runner.ts\";\nimport { createContextScoutToolDefinition } from \"./tools/context-scout.ts\";\nimport { createDelegateToolDefinition } from \"./tools/delegate.ts\";\nimport { createFindTool } from \"./tools/find.ts\";\nimport { createGoalToolDefinition } from \"./tools/goal.ts\";\nimport { createGrepTool } from \"./tools/grep.ts\";\nimport { createAllToolDefinitions } from \"./tools/index.ts\";\nimport { createModelFitnessToolDefinition } from \"./tools/model-fitness.ts\";\nimport { createReadTool } from \"./tools/read.ts\";\nimport { createRunToolkitScriptToolDefinition } from \"./tools/run-toolkit-script.ts\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.ts\";\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ninterface ReloadRuntimeSnapshot {\n\textensionRunner: ExtensionRunner;\n\tbaseToolDefinitions: Map<string, ToolDefinition>;\n\ttoolRegistry: Map<string, AgentTool>;\n\ttoolDefinitions: Map<string, ToolDefinitionEntry>;\n\ttoolPromptSnippets: Map<string, string>;\n\ttoolPromptGuidelines: Map<string, string[]>;\n\tagentTools: AgentTool[];\n\tagentSystemPrompt: string;\n\tbaseSystemPrompt: string;\n}\n\nexport interface RuntimeBuilderDeps {\n\t/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */\n\tgetAgent(): Agent;\n\t/** Workspace root, passed to the tool-definition factory and the extension runner. */\n\tgetCwd(): string;\n\t/** Agent state root, including the host-keyed fitness store. */\n\tgetAgentDir(): string;\n\t/** Session log, passed to the extension runner. */\n\tgetSessionManager(): SessionManager;\n\t/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Model registry, passed to the extension runner and profile model re-resolution. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Session-scoped provider/model quota exhaustion guard. */\n\tisModelExhausted(model: Model<Api>): boolean;\n\t/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */\n\tgetResourceLoader(): ResourceLoader;\n\n\t/** Live extension runner (host-owned; pervasive). */\n\tgetExtensionRunner(): ExtensionRunner;\n\t/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */\n\tsetExtensionRunner(runner: ExtensionRunner): void;\n\t/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */\n\tgetBaseSystemPrompt(): string;\n\tsetBaseSystemPrompt(prompt: string): void;\n\n\t/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */\n\tgetCustomTools(): ToolDefinition[];\n\t/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */\n\tgetBaseToolsOverride(): Record<string, AgentTool> | undefined;\n\t/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tsetRequestedActiveToolNames(names: string[] | undefined): void;\n\n\t/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */\n\tgetToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;\n\tsetToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;\n\tgetAllowedToolNames(): Set<string> | undefined;\n\tgetExcludedToolNames(): Set<string> | undefined;\n\t/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */\n\tderiveToolProfileFilter(): Required<ResourceProfileFilterSettings>;\n\t/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */\n\tisToolOrCommandAllowedByProfile(name: string): boolean;\n\t/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */\n\tfilterExtensionsForRuntime(extensions: Extension[]): Extension[];\n\t/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */\n\tsetUnboundToolGrantWarnings(warnings: string[]): void;\n\n\t/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */\n\tgetActiveToolNames(): string[];\n\t/** Apply the recomputed active set (capability filter + companion auto-activation live here). */\n\tsetActiveToolsByName(toolNames: string[]): void;\n\t/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */\n\tnormalizePromptSnippet(text: string | undefined): string | undefined;\n\tnormalizePromptGuidelines(guidelines: string[] | undefined): string[];\n\n\t/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */\n\tbindExtensionCore(runner: ExtensionRunner): void;\n\t/** Re-apply UI context / mode / command-context / error subscription to a runner. */\n\tapplyExtensionBindings(runner: ExtensionRunner): void;\n\t/** Re-run resource discovery for the active extensions (reload only). */\n\textendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void>;\n\t/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */\n\treapplyActiveProfileModelSettings(): Promise<void>;\n\t/** Notify extensions-changed listeners after a single-extension live op. */\n\tnotifyExtensionsChanged(): void;\n\n\t/** Session-scoped tool-output artifact store for grep/find/artifact_retrieve (gated on the profile). */\n\tgetToolArtifactStore(): ArtifactStore;\n\n\t/** Live memory manager — its provider tools join the registry. */\n\tgetMemoryManager(): MemoryManager;\n\t/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */\n\tgetMemoryAuditDiagnostics(): { retrieval: MemoryRetrievalDiagnostics; promptInclusion: MemoryPromptInclusionReport };\n\t/** Drop extension-contributed pending memory providers before a reload re-registers them. */\n\tclearPendingMemoryProviders(): void;\n\t/** (Re)derive the memory subsystem from reloaded settings/providers. */\n\tinitializeMemory(): Promise<void>;\n\n\t/** Goal-tool state accessors. */\n\tgetGoalStateSnapshot(): GoalState | undefined;\n\tsaveGoalStateSnapshot(state: GoalState): string;\n\t/** Context-gc report for the core diagnostics tool. */\n\tgetContextGcReport(messages: AgentMessage[]): ContextGcReport;\n\t/** Worker-delegation runner for the delegate tool. */\n\trunWorkerDelegationOnce(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t}): Promise<WorkerDelegationRunOutcome>;\n\t/** Model-fitness probe for the model_fitness tool. */\n\trunModelFitness(args: {\n\t\tmodel: string;\n\t\ttrials?: number;\n\t}): Promise<{ started: true; model: string; report: ModelFitnessReport } | { started: false; skipReason: string }>;\n\t/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n\t/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Roll reflex-brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\n\t/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */\n\tcreateAgentContextSnapshot(): AgentContext;\n\tgetContextUsage(): ContextUsage | undefined;\n\n\t/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */\n\tisStreaming(): boolean;\n\tisCompacting(): boolean;\n\n\t/** Extension bindings present — gate for re-emitting session_start on reload. */\n\tgetExtensionUIContext(): ExtensionUIContext | undefined;\n\tgetExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;\n\tgetExtensionShutdownHandler(): ShutdownHandler | undefined;\n\tgetExtensionErrorListener(): ExtensionErrorListener | undefined;\n}\n\n/**\n * Owns the tool-registry build and the self-modification-safe extension reload extracted from\n * {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.\n */\nexport class RuntimeBuilder {\n\t// Tool registry for extension getTools/setTools\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\n\tprivate readonly deps: RuntimeBuilderDeps;\n\n\tconstructor(deps: RuntimeBuilderDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate async _runContextScout(\n\t\tquery: string,\n\t\tmaxTurns: number | undefined,\n\t\tartifactStore: ArtifactStore | undefined,\n\t) {\n\t\tconst cwd = this.deps.getCwd();\n\t\tconst controller = new ScoutController({\n\t\t\tresolveScoutModel: async () =>\n\t\t\t\tresolveScoutModel(\n\t\t\t\t\tthis.deps.getModelRegistry(),\n\t\t\t\t\tthis.deps.getSettingsManager().getScoutSettings().model,\n\t\t\t\t\tthis.deps.getAgentDir(),\n\t\t\t\t\t(model) => this.deps.isModelExhausted(model),\n\t\t\t\t),\n\t\t\tgetCwd: () => cwd,\n\t\t\tbuildReadOnlyTools: (toolCwd) => [\n\t\t\t\tcreateReadTool(toolCwd),\n\t\t\t\tcreateGrepTool(toolCwd, { artifactStore }),\n\t\t\t\tcreateFindTool(toolCwd, { artifactStore }),\n\t\t\t],\n\t\t\tstreamFn: this.deps.getAgent().streamFn,\n\t\t\tfileExists: (path) => existsSync(resolveCwdPath(cwd, path)),\n\t\t\tcountLines: (path) => countFileLines(resolveCwdPath(cwd, path)),\n\t\t});\n\t\treturn controller.run(query, maxTurns);\n\t}\n\n\t/** Whether a tool name is present in the live wrapped registry. */\n\thasTool(name: string): boolean {\n\t\treturn this._toolRegistry.has(name);\n\t}\n\n\t/** The live wrapped tool for a name, if registered (activation lookup). */\n\tgetRegisteredTool(name: string): AgentTool | undefined {\n\t\treturn this._toolRegistry.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt snippet, if any. */\n\tgetToolPromptSnippet(name: string): string | undefined {\n\t\treturn this._toolPromptSnippets.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt guidelines, if any. */\n\tgetToolPromptGuidelines(name: string): string[] | undefined {\n\t\treturn this._toolPromptGuidelines.get(name);\n\t}\n\n\t/**\n\t * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.\n\t */\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tpromptGuidelines: definition.promptGuidelines,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\trefreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\t// Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is\n\t\t// capability/profile-filtered, so feeding it back through setActiveToolsByName would\n\t\t// permanently shrink what a later switch to a larger model (or permissive profile) restores.\n\t\tconst previousActiveToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst allowedToolNames = this.deps.getAllowedToolNames();\n\t\tconst excludedToolNames = this.deps.getExcludedToolNames();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst isAllowedTool = (name: string): boolean => {\n\t\t\tif (allowedToolNames && !allowedToolNames.has(name)) return false;\n\t\t\tif (excludedToolNames?.has(name)) return false;\n\t\t\tif (!toolProfileFilter) return true;\n\t\t\tif (toolProfileFilter.allow.length > 0 && !matchesResourceProfilePattern(name, toolProfileFilter.allow)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (matchesResourceProfilePattern(name, toolProfileFilter.block)) return false;\n\t\t\treturn true;\n\t\t};\n\n\t\tconst registeredTools = this.deps.getExtensionRunner().getAllRegisteredTools();\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this.deps.getCustomTools().map((definition) => ({\n\t\t\t\tdefinition,\n\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t})),\n\t\t\t// Memory subsystem provider tools (e.g. file-store's `memory` tool).\n\t\t\t...this.deps\n\t\t\t\t.getMemoryManager()\n\t\t\t\t.getToolDefinitions()\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t\t})),\n\t\t].filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: \"builtin\" }),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this.deps.normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this.deps.normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this.deps.getExtensionRunner();\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\trunner,\n\t\t);\n\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];\n\t\tconst nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));\n\n\t\tconst autoActivated: string[] = [];\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t\tautoActivated.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Strict UAC: the active profile is the COMPLETE grant, so a tool the profile names\n\t\t// explicitly is itself a request for that tool — it must ACTIVATE from the registry even\n\t\t// if the session never requested it. Without this, activation is only ever the requested\n\t\t// defaults ∩ allow-list, and a profile granting non-default tools (a search-only profile's\n\t\t// grep/find) yields an empty or truncated tool set on load and /reload. A blanket \"*\"\n\t\t// stays grant-only: activation then still derives from the request/defaults above.\n\t\tconst explicitAllowPatterns = toolProfileFilter?.allow.filter((pattern) => pattern !== \"*\") ?? [];\n\t\tif (explicitAllowPatterns.length > 0) {\n\t\t\tconst boundPatterns = new Set<string>();\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!isAllowedTool(toolName)) continue;\n\t\t\t\tfor (const pattern of explicitAllowPatterns) {\n\t\t\t\t\tif (matchesResourceProfilePattern(toolName, [pattern])) boundPatterns.add(pattern);\n\t\t\t\t}\n\t\t\t\tif (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd\n\t\t\t// name, or the owning extension is not granted/loaded. Surface it.\n\t\t\tthis.deps.setUnboundToolGrantWarnings(\n\t\t\t\texplicitAllowPatterns\n\t\t\t\t\t.filter((pattern) => !boundPatterns.has(pattern))\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(pattern) =>\n\t\t\t\t\t\t\t`profile tool grant \"${pattern}\" binds to no registered tool (typo, or the owning extension is not granted/loaded)`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.deps.setUnboundToolGrantWarnings([]);\n\t\t}\n\n\t\t// artifact_retrieve companion auto-activation is enforced inside\n\t\t// setActiveToolsByName() itself (not duplicated here), so every activation path --\n\t\t// including the public, extension-exposed setActiveTools() -- gets the same\n\t\t// guarantee, not just this settings/profile refresh flow.\n\t\tthis.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t\t// setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore\n\t\t// the true pre-filter request (plus this refresh's auto-activations) so an internal refresh\n\t\t// can never permanently narrow it.\n\t\tthis.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...autoActivated])]);\n\t}\n\n\tprivate _createReloadRuntimeSnapshot(): ReloadRuntimeSnapshot {\n\t\tconst agent = this.deps.getAgent();\n\t\treturn {\n\t\t\textensionRunner: this.deps.getExtensionRunner(),\n\t\t\tbaseToolDefinitions: this._baseToolDefinitions,\n\t\t\ttoolRegistry: this._toolRegistry,\n\t\t\ttoolDefinitions: this._toolDefinitions,\n\t\t\ttoolPromptSnippets: this._toolPromptSnippets,\n\t\t\ttoolPromptGuidelines: this._toolPromptGuidelines,\n\t\t\tagentTools: agent.state.tools,\n\t\t\tagentSystemPrompt: agent.state.systemPrompt,\n\t\t\tbaseSystemPrompt: this.deps.getBaseSystemPrompt(),\n\t\t};\n\t}\n\n\tprivate _restoreReloadRuntimeSnapshot(snapshot: ReloadRuntimeSnapshot): void {\n\t\t// setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together\n\t\t// (the same field-then-ref pair the host wrote at every assignment site); nothing reads the\n\t\t// ref between the two writes, so folding them is unobservable.\n\t\tthis.deps.setExtensionRunner(snapshot.extensionRunner);\n\t\tthis._baseToolDefinitions = snapshot.baseToolDefinitions;\n\t\tthis._toolRegistry = snapshot.toolRegistry;\n\t\tthis._toolDefinitions = snapshot.toolDefinitions;\n\t\tthis._toolPromptSnippets = snapshot.toolPromptSnippets;\n\t\tthis._toolPromptGuidelines = snapshot.toolPromptGuidelines;\n\t\tconst agent = this.deps.getAgent();\n\t\tagent.state.tools = snapshot.agentTools;\n\t\tagent.state.systemPrompt = snapshot.agentSystemPrompt;\n\t\tthis.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);\n\t\tthis.deps.applyExtensionBindings(snapshot.extensionRunner);\n\t}\n\n\tprivate _doctorReloadRuntime(): void {\n\t\tconst extensionErrors = this.deps.getResourceLoader().getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tconst summary = extensionErrors\n\t\t\t\t.slice(0, 6)\n\t\t\t\t.map((error) => `${error.path}: ${error.error}`)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(`Extension reload failed doctor: ${summary}`);\n\t\t}\n\n\t\tconst missingActiveTools = this.deps.getActiveToolNames().filter((name) => !this._toolRegistry.has(name));\n\t\tif (missingActiveTools.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension reload failed doctor: active tool(s) missing after reload: ${missingActiveTools.join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const tool of this.deps.getAgent().state.tools) {\n\t\t\tif (!this._toolDefinitions.has(tool.name)) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: tool ${tool.name} missing from definition registry`);\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.createAgentContextSnapshot();\n\t\tthis.deps.getContextUsage();\n\t}\n\n\tbuildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t}): void {\n\t\tconst settingsManager = this.deps.getSettingsManager();\n\t\tconst autoResizeImages = settingsManager.getImageAutoResize();\n\t\tconst shellCommandPrefix = settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = settingsManager.getShellPath();\n\t\tconst baseToolsOverride = this.deps.getBaseToolsOverride();\n\t\t// grep/find must not emit a \"Full output: artifact tool-output:<id>\" handle that\n\t\t// nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside\n\t\t// an active allowlist, don't hand grep/find an artifact store at all: they fall\n\t\t// back to their pre-existing bounded preview/truncation behavior, with no\n\t\t// payload/meta files ever written and no retrieval promise made.\n\t\tconst toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile(\"artifact_retrieve\")\n\t\t\t? this.deps.getToolArtifactStore()\n\t\t\t: undefined;\n\t\tconst baseToolDefinitions = baseToolsOverride\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(baseToolsOverride).map(([name, tool]) => [name, createToolDefinitionFromAgentTool(tool)]),\n\t\t\t\t)\n\t\t\t: createAllToolDefinitions(this.deps.getCwd(), {\n\t\t\t\t\tread: { autoResizeImages },\n\t\t\t\t\tbash: { commandPrefix: shellCommandPrefix, shellPath },\n\t\t\t\t\tgrep: { artifactStore: toolArtifactStore },\n\t\t\t\t\tfind: { artifactStore: toolArtifactStore },\n\t\t\t\t\tartifact_retrieve: { artifactStore: toolArtifactStore },\n\t\t\t\t});\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(baseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\t\tif (!baseToolsOverride) {\n\t\t\tfor (const definition of createCoreDiagnosticsToolDefinitions(\n\t\t\t\t() => this.deps.getActiveToolNames(),\n\t\t\t\t() => this.getAllTools(),\n\t\t\t\t(messages) => this.deps.getContextGcReport(messages),\n\t\t\t\t() => this.deps.getMemoryAuditDiagnostics(),\n\t\t\t)) {\n\t\t\t\tthis._baseToolDefinitions.set(definition.name, definition);\n\t\t\t}\n\t\t\tconst goalToolDefinition = createGoalToolDefinition({\n\t\t\t\tgetGoalState: () => this.deps.getGoalStateSnapshot(),\n\t\t\t\tsaveGoalState: (state) => {\n\t\t\t\t\tthis.deps.saveGoalStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);\n\t\t\tconst delegateToolDefinition = createDelegateToolDefinition({\n\t\t\t\trunWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);\n\t\t\t// Registered but not default-active: probes spend tokens on the probed model, so\n\t\t\t// activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).\n\t\t\tconst modelFitnessToolDefinition = createModelFitnessToolDefinition({\n\t\t\t\trunProbe: (args) => this.deps.runModelFitness(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(modelFitnessToolDefinition.name, modelFitnessToolDefinition);\n\t\t\tif (settingsManager.getScoutSettings().enabled) {\n\t\t\t\tconst contextScoutToolDefinition = createContextScoutToolDefinition({\n\t\t\t\t\trunScout: (input) => this._runContextScout(input.query, input.maxTurns, toolArtifactStore),\n\t\t\t\t});\n\t\t\t\tthis._baseToolDefinitions.set(contextScoutToolDefinition.name, contextScoutToolDefinition);\n\t\t\t}\n\t\t\tconst runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({\n\t\t\t\tgetScripts: () => this.deps.getSettingsManager().getToolkitScripts(),\n\t\t\t\texecute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),\n\t\t\t\t// Reflex brain (fitness-gated local model): resolves ambiguous requests into a\n\t\t\t\t// registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.\n\t\t\t\tinterpret: async (request, scripts) => {\n\t\t\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\t\t\tif (!model) return undefined;\n\t\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\t\t\tmessages: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tmaxTokens: 256,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t});\n\t\t\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"toolkit-brain\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn parseReflexPlan(completion.text);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(runToolkitScriptToolDefinition.name, runToolkitScriptToolDefinition);\n\t\t}\n\n\t\tconst extensionsResult = this.deps.getResourceLoader().getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\tconst extensions = this.deps.filterExtensionsForRuntime(extensionsResult.extensions);\n\t\tconst runtimeExtensionPaths = new Set(extensions.map((extension) => extension.path));\n\t\textensionsResult.runtime.pendingProviderRegistrations =\n\t\t\textensionsResult.runtime.pendingProviderRegistrations.filter((registration) =>\n\t\t\t\truntimeExtensionPaths.has(registration.extensionPath),\n\t\t\t);\n\n\t\tconst runner = new ExtensionRunner(\n\t\t\textensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis.deps.getCwd(),\n\t\t\tthis.deps.getSessionManager(),\n\t\t\tthis.deps.getModelRegistry(),\n\t\t);\n\t\tthis.deps.setExtensionRunner(runner);\n\t\tthis.deps.bindExtensionCore(runner);\n\t\tthis.deps.applyExtensionBindings(runner);\n\n\t\tconst defaultActiveToolNames = baseToolsOverride\n\t\t\t? Object.keys(baseToolsOverride)\n\t\t\t: [\n\t\t\t\t\t\"read\",\n\t\t\t\t\t\"bash\",\n\t\t\t\t\t\"edit\",\n\t\t\t\t\t\"write\",\n\t\t\t\t\t\"context_audit\",\n\t\t\t\t\t\"goal\",\n\t\t\t\t\t\"delegate\",\n\t\t\t\t\t\"run_toolkit_script\",\n\t\t\t\t\t...(settingsManager.getScoutSettings().enabled ? [\"context_scout\"] : []),\n\t\t\t\t];\n\t\tconst baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;\n\t\tthis.refreshToolRegistry({\n\t\t\tactiveToolNames: baseActiveToolNames,\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reload while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reload while context compaction or branch summarization is active\");\n\t\t}\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\tconst snapshot = this._createReloadRuntimeSnapshot();\n\t\t// Preserve the pre-filter tool REQUEST across the rebuild, not the capability/profile-filtered\n\t\t// active set — otherwise a reload under a small model permanently shrinks the restorable set.\n\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\tconst reloadErrors: string[] = [];\n\t\tlet newRunner: ExtensionRunner | undefined;\n\t\ttry {\n\t\t\tawait this.deps.getSettingsManager().reload();\n\t\t\t// Re-derive the resource-profile tool filter from the freshly reloaded settings.\n\t\t\t// Unlike skills/prompts/themes (which re-filter through the resource loader on every\n\t\t\t// reload), the tool filter is held on the session, so without this a live edit to the\n\t\t\t// active profile's tools allow/block — or switching the active profile — would not\n\t\t\t// apply on /reload and allowed tools would stay missing.\n\t\t\tthis.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());\n\t\t\t// Re-apply the active profile's model/thinking from the freshly reloaded settings, so a live\n\t\t\t// profile edit (or switch) takes effect on /reload. Skipped when the launch used an explicit\n\t\t\t// --model/--thinking flag, which must win over the profile across reloads.\n\t\t\tawait this.deps.reapplyActiveProfileModelSettings();\n\t\t\tawait this.deps.getResourceLoader().reload({ failOnExtensionErrors: true, deferExtensionDispose: true });\n\t\t\tresetApiProviders();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tnewRunner = this.deps.getExtensionRunner();\n\t\t\tconst offDoctorErrors = newRunner.onError((error) => {\n\t\t\t\treloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t// Reload starts memory providers fresh; loaded extensions re-register below.\n\t\t\t\tthis.deps.clearPendingMemoryProviders();\n\t\t\t\tconst hasBindings =\n\t\t\t\t\tthis.deps.getExtensionUIContext() ||\n\t\t\t\t\tthis.deps.getExtensionCommandContextActions() ||\n\t\t\t\t\tthis.deps.getExtensionShutdownHandler() ||\n\t\t\t\t\tthis.deps.getExtensionErrorListener();\n\t\t\t\tif (hasBindings) {\n\t\t\t\t\tawait newRunner.emit({ type: \"session_start\", reason: \"reload\" });\n\t\t\t\t\tawait this.deps.extendResourcesFromExtensions(\"reload\");\n\t\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\toffDoctorErrors();\n\t\t\t}\n\t\t\tif (reloadErrors.length > 0) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join(\"; \")}`);\n\t\t\t}\n\t\t\tawait emitSessionShutdownEvent(previousRunner, { type: \"session_shutdown\", reason: \"reload\" });\n\t\t\tpreviousRunner.invalidate();\n\t\t\tthis.deps.getResourceLoader().commitReload?.();\n\t\t\t// Re-derive the memory subsystem from the reloaded settings/providers.\n\t\t\tawait this.deps.initializeMemory();\n\t\t} catch (error) {\n\t\t\tif (newRunner && newRunner !== previousRunner) {\n\t\t\t\tnewRunner.invalidate(\n\t\t\t\t\t\"This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.deps.getResourceLoader().rollbackReload?.();\n\t\t\tthis._restoreReloadRuntimeSnapshot(snapshot);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unload a single extension without full reload.\n\t * Runs the extension's session_shutdown lifecycle, unregisters its providers,\n\t * disposes its event subscriptions, and rebuilds the runtime.\n\t * Falls back to full reload on error.\n\t */\n\tasync unloadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot unload extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot unload extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst ext = this.deps.getResourceLoader().getLoadedExtension(extensionPath);\n\t\tif (!ext) {\n\t\t\treturn; // Nothing to unload\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Run session_shutdown lifecycle for this extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(ext, { type: \"session_shutdown\", reason: \"unload\" });\n\n\t\t\t// Unregister its providers (keyed by the extension's own path, as registered)\n\t\t\tconst runtime = this.deps.getResourceLoader().getExtensions().runtime;\n\t\t\tfor (const name of runtime.getProvidersForExtension(ext.path)) {\n\t\t\t\truntime.unregisterProvider(name, ext.path);\n\t\t\t}\n\n\t\t\t// Dispose its event subscriptions and run disposers\n\t\t\tawait disposeExtensionEventSubscriptions([ext]);\n\n\t\t\t// Remove from loaded extensions\n\t\t\tthis.deps.getResourceLoader().removeLoadedExtension(extensionPath);\n\n\t\t\t// Rebuild runtime with new extension set\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tpreviousRunner.invalidate();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Load a single extension without full reload.\n\t * Loads the extension with fresh import, rebuilds the runtime,\n\t * and runs the extension's session_start lifecycle.\n\t * Falls back to full reload on error.\n\t */\n\tasync loadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot load extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot load extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Load the extension with fresh import\n\t\t\tconst { extension, error } = await this.deps.getResourceLoader().loadSingleExtension(extensionPath);\n\t\t\tif (error || !extension) {\n\t\t\t\tthrow new Error(error || `Failed to load extension: ${extensionPath}`);\n\t\t\t}\n\n\t\t\t// Rebuild runtime to aggregate tools/commands/handlers/providers\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\n\t\t\t// Run session_start lifecycle for the new extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(extension, { type: \"session_start\", reason: \"load\" });\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reconcile loaded extensions with the active profile.\n\t * Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.\n\t * Falls back to full reload if any individual load/unload fails.\n\t */\n\tasync reconcileLoadedExtensions(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while context compaction or branch summarization is active\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Get all discoverable extension paths\n\t\t\tconst allDiscoverablePaths = await this.deps.getResourceLoader().getDiscoverableExtensionPaths();\n\n\t\t\t// Get the target enabled set based on profile filters\n\t\t\tconst targetEnabledSet = new Set<string>();\n\t\t\tfor (const path of allDiscoverablePaths) {\n\t\t\t\tif (this.deps.getSettingsManager().isResourceAllowedByProfile(\"extensions\", path)) {\n\t\t\t\t\ttargetEnabledSet.add(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get currently loaded set\n\t\t\tconst loadedExtensions = this.deps.getResourceLoader().getExtensions().extensions;\n\t\t\tconst loadedSet = new Set<string>();\n\t\t\tfor (const ext of loadedExtensions) {\n\t\t\t\tloadedSet.add(ext.path);\n\t\t\t}\n\n\t\t\t// Collect unloads and loads\n\t\t\tconst toUnload: string[] = [];\n\t\t\tconst toLoad: string[] = [];\n\n\t\t\tfor (const path of loadedSet) {\n\t\t\t\tif (!targetEnabledSet.has(path)) {\n\t\t\t\t\ttoUnload.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of targetEnabledSet) {\n\t\t\t\tif (!loadedSet.has(path)) {\n\t\t\t\t\ttoLoad.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply unloads first, then loads, to minimize churn\n\t\t\t// Collect errors but continue through all operations\n\t\t\tconst errors: Error[] = [];\n\n\t\t\tfor (const path of toUnload) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unloadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of toLoad) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.loadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any errors occurred, throw the first one (already fell back to full reload in load/unload)\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow errors[0];\n\t\t\t}\n\n\t\t\t// Single notification at the end\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nexport async function resolveScoutModel(\n\tmodelRegistry: ModelRegistry,\n\tmodelSetting: string,\n\tagentDir: string,\n\tisModelExhausted: (model: Model<Api>) => boolean = () => false,\n) {\n\tconst model =\n\t\tmodelSetting === \"auto\"\n\t\t\t? findFastContextModel(modelRegistry)\n\t\t\t: resolveCliModel({ cliModel: modelSetting, modelRegistry }).model;\n\tif (!model) {\n\t\treturn { failure: `no scout model matched ${modelSetting}` };\n\t}\n\tif (isModelExhausted(model)) {\n\t\treturn { failure: `${model.provider}/${model.id} exhausted: quota` };\n\t}\n\tif (modelSetting === \"auto\") {\n\t\tconst modelRef = `${model.provider}/${model.id}`;\n\t\tconst fitness = FitnessStore.forAgentDir(agentDir)\n\t\t\t.getForHost()\n\t\t\t.find((entry) => entry.model === modelRef);\n\t\tconst verdict = evaluateSurfaceFitness(\"scout_auto\", fitness?.report);\n\t\tif (!verdict.fit) {\n\t\t\treturn verdict.reason === \"unprobed\"\n\t\t\t\t? { failure: `${modelRef} unprobed — run /fitness before auto-selection` }\n\t\t\t\t: { failure: `${modelRef} unfit (${verdict.lane} ${verdict.succeeded}/${verdict.total})` };\n\t\t}\n\t}\n\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok) {\n\t\treturn { failure: auth.error ?? `no usable auth for scout model ${model.provider}/${model.id}` };\n\t}\n\treturn { model, apiKey: auth.apiKey, headers: auth.headers };\n}\n\nfunction findFastContextModel(modelRegistry: ModelRegistry) {\n\treturn modelRegistry.getAll().find((model) => {\n\t\tconst text = `${model.provider}/${model.id} ${model.name}`.toLowerCase();\n\t\treturn text.includes(\"fastcontext\");\n\t});\n}\n\nfunction resolveCwdPath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : join(cwd, path);\n}\n\nfunction countFileLines(path: string): number | undefined {\n\ttry {\n\t\treturn readFileSync(path, \"utf8\").split(/\\r?\\n/).length;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|