omk-agent-core 0.80.8 → 0.90.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/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +34 -6
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +16 -1
- package/dist/agent.js.map +1 -1
- package/dist/harness/reverse-skill.d.ts +86 -0
- package/dist/harness/reverse-skill.d.ts.map +1 -0
- package/dist/harness/reverse-skill.js +647 -0
- package/dist/harness/reverse-skill.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,YAAY,GAIZ,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAoBrE,SAAS,mBAAmB,CAAC,QAAwB,EAAa;IACjE,OAAO,QAAQ,CAAC,MAAM,CACrB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CACrG,CAAC;AAAA,CACF;AAED,MAAM,WAAW,GAAG;IACnB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;CACpE,CAAC;AAEF,MAAM,aAAa,GAAG;IACrB,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;IAC1D,aAAa,EAAE,CAAC;IAChB,SAAS,EAAE,CAAC;CACS,CAAC;AASvB,SAAS,uBAAuB,CAC/B,YAAkH,EAC9F;IACpB,IAAI,KAAK,GAAG,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAI,QAAQ,GAAG,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAErD,OAAO;QACN,YAAY,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE;QAC9C,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,aAAa;QAC3C,aAAa,EAAE,YAAY,EAAE,aAAa,IAAI,KAAK;QACnD,IAAI,KAAK,GAAG;YACX,OAAO,KAAK,CAAC;QAAA,CACb;QACD,IAAI,KAAK,CAAC,SAA2B,EAAE;YACtC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;QAAA,CAC1B;QACD,IAAI,QAAQ,GAAG;YACd,OAAO,QAAQ,CAAC;QAAA,CAChB;QACD,IAAI,QAAQ,CAAC,YAA4B,EAAE;YAC1C,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC;QAAA,CAChC;QACD,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,SAAS;QAC3B,gBAAgB,EAAE,IAAI,GAAG,EAAU;QACnC,YAAY,EAAE,SAAS;KACvB,CAAC;AAAA,CACF;AAyBD,MAAM,mBAAmB;IAChB,QAAQ,GAAmB,EAAE,CAAC;IAC/B,IAAI,CAAY;IAEvB,YAAY,IAAe,EAAE;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAAA,CACjB;IAED,OAAO,CAAC,OAAqB,EAAQ;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAAA,CAC5B;IAED,QAAQ,GAAY;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAAA,CAChC;IAED,KAAK,GAAmB;QACvB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACnB,OAAO,OAAO,CAAC;QAChB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,CAAC;IAAA,CACf;IAED,KAAK,GAAS;QACb,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IAAA,CACnB;CACD;AAQD;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IACT,MAAM,CAAoB;IACjB,SAAS,GAAG,IAAI,GAAG,EAAoE,CAAC;IACxF,aAAa,CAAsB;IACnC,aAAa,CAAsB;IAE7C,YAAY,CAA+D;IAC3E,gBAAgB,CAA+E;IAC/F,QAAQ,CAAW;IACnB,SAAS,CAA0E;IACnF,SAAS,CAAoC;IAC7C,UAAU,CAAqC;IAC/C,cAAc,CAG0B;IACxC,aAAa,CAG0B;IACvC,eAAe,CAE0D;IACxE,SAAS,CAAa;IAC9B,0EAA0E;IACnE,SAAS,CAAU;IAC1B,kFAAkF;IAC3E,eAAe,CAAmB;IACzC,4DAA4D;IACrD,SAAS,CAAY;IAC5B,wDAAwD;IACjD,eAAe,CAAU;IAChC,uFAAuF;IAChF,aAAa,CAAoB;IAExC,YAAY,OAAO,GAAiB,EAAE,EAAE;QACvC,IAAI,CAAC,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5D,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC;QAChE,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;QACjD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC,CAAC;QACtF,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC,CAAC;QACtF,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,UAAU,CAAC;IAAA,CACzD;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,QAA0E,EAAc;QACjG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAAA,CAC7C;IAED;;;;OAIG;IACH,IAAI,KAAK,GAAe;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC;IAAA,CACnB;IAED,yDAAyD;IACzD,IAAI,YAAY,CAAC,IAAe,EAAE;QACjC,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;IAAA,CAC/B;IAED,IAAI,YAAY,GAAc;QAC7B,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IAAA,CAC/B;IAED,0DAA0D;IAC1D,IAAI,YAAY,CAAC,IAAe,EAAE;QACjC,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;IAAA,CAC/B;IAED,IAAI,YAAY,GAAc;QAC7B,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IAAA,CAC/B;IAED,gFAAgF;IAChF,KAAK,CAAC,OAAqB,EAAQ;QAClC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAAA,CACpC;IAED,wEAAwE;IACxE,QAAQ,CAAC,OAAqB,EAAQ;QACrC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAAA,CACpC;IAED,2CAA2C;IAC3C,kBAAkB,GAAS;QAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAAA,CAC3B;IAED,4CAA4C;IAC5C,kBAAkB,GAAS;QAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAAA,CAC3B;IAED,yDAAyD;IACzD,cAAc,GAAS;QACtB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAAA,CAC1B;IAED,sEAAsE;IACtE,iBAAiB,GAAY;QAC5B,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;IAAA,CACtE;IAED,uDAAuD;IACvD,IAAI,MAAM,GAA4B;QACrC,OAAO,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC;IAAA,CAC9C;IAED,+CAA+C;IAC/C,KAAK,GAAS;QACb,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,KAAK,EAAE,CAAC;IAAA,CACxC;IAED;;;;OAIG;IACH,WAAW,GAAkB;QAC5B,OAAO,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAAA,CACpD;IAED,kEAAkE;IAClE,KAAK,GAAS;QACb,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;QACrC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAAA,CAC1B;IAKD,KAAK,CAAC,MAAM,CAAC,KAA6C,EAAE,MAAuB,EAAiB;QACnG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACd,4GAA4G,CAC5G,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAAA,CACvC;IAED,oGAAoG;IACpG,KAAK,CAAC,QAAQ,GAAkB;QAC/B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAClD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChF,OAAO;YACR,CAAC;YAED,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YACnD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;gBAC9C,OAAO;YACR,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IAAA,CAC7B;IAEO,oBAAoB,CAC3B,KAA6C,EAC7C,MAAuB,EACN;QACjB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GAAsC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAAA,CAC1D;IAEO,KAAK,CAAC,iBAAiB,CAC9B,QAAwB,EACxB,OAAO,GAA0C,EAAE,EACnC;QAChB,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;YAC7C,MAAM,YAAY,CACjB,QAAQ,EACR,IAAI,CAAC,qBAAqB,EAAE,EAC5B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EACpC,MAAM,EACN,IAAI,CAAC,QAAQ,CACb,CAAC;QAAA,CACF,CAAC,CAAC;IAAA,CACH;IAEO,KAAK,CAAC,eAAe,GAAkB;QAC9C,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;YAC7C,MAAM,oBAAoB,CACzB,IAAI,CAAC,qBAAqB,EAAE,EAC5B,IAAI,CAAC,gBAAgB,EAAE,EACvB,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EACpC,MAAM,EACN,IAAI,CAAC,QAAQ,CACb,CAAC;QAAA,CACF,CAAC,CAAC;IAAA,CACH;IAEO,qBAAqB,GAAiB;QAC7C,OAAO;YACN,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;YACtC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE;YACtC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;SAChC,CAAC;IAAA,CACF;IAEO,gBAAgB,CAAC,OAAO,GAA0C,EAAE,EAAmB;QAC9F,IAAI,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,KAAK,IAAI,CAAC;QACvE,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;YACtF,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YACzG,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,mBAAmB,EAAE,KAAK,IAAI,EAAE,CAAC;gBAChC,IAAI,uBAAuB,EAAE,CAAC;oBAC7B,uBAAuB,GAAG,KAAK,CAAC;oBAChC,OAAO,EAAE,CAAC;gBACX,CAAC;gBACD,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAAA,CAClC;YACD,mBAAmB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;SAC3D,CAAC;IAAA,CACF;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgD,EAAiB;QAC/F,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,IAAI,cAAc,GAAG,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9C,cAAc,GAAG,OAAO,CAAC;QAAA,CACzB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;QAEvE,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;QAErC,IAAI,CAAC;YACJ,MAAM,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpE,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,SAAS,EAAE,CAAC;QAClB,CAAC;IAAA,CACD;IAEO,KAAK,CAAC,gBAAgB,CAAC,KAAc,EAAE,OAAgB,EAAiB;QAC/E,MAAM,cAAc,GAAG;YACtB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YACrC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;YAC1B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ;YACpC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC3B,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;YACzC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YACpE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACE,CAAC;QACzB,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7E,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3E,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QACzF,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAAA,CAC5E;IAEO,SAAS,GAAS;QACzB,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAAA,CAC3B;IAED;;;;;;OAMG;IACK,KAAK,CAAC,aAAa,CAAC,KAAiB,EAAiB;QAC7D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,eAAe;gBACnB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC7C,MAAM;YAEP,KAAK,gBAAgB;gBACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC7C,MAAM;YAEP,KAAK,aAAa;gBACjB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzC,MAAM;YAEP,KAAK,sBAAsB,EAAE,CAAC;gBAC7B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBAC/D,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;gBAChD,MAAM;YACP,CAAC;YAED,KAAK,oBAAoB,EAAE,CAAC;gBAC3B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBAC/D,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;gBAChD,MAAM;YACP,CAAC;YAED,KAAK,UAAU;gBACd,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;oBACtE,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;gBACvD,CAAC;gBACD,MAAM;YAEP,KAAK,WAAW;gBACf,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBACzC,MAAM;QACR,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC;QACtD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC9D,CAAC;QACD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;IAAA,CACD;CACD","sourcesContent":["import {\n\ttype ImageContent,\n\ttype Message,\n\ttype Model,\n\ttype SimpleStreamOptions,\n\tstreamSimple,\n\ttype TextContent,\n\ttype ThinkingBudgets,\n\ttype Transport,\n} from \"omk-ai\";\nimport { runAgentLoop, runAgentLoopContinue } from \"./agent-loop.ts\";\nimport type {\n\tAfterToolCallContext,\n\tAfterToolCallResult,\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentLoopTurnUpdate,\n\tAgentMessage,\n\tAgentState,\n\tAgentTool,\n\tBeforeToolCallContext,\n\tBeforeToolCallResult,\n\tQueueMode,\n\tStreamFn,\n\tToolExecutionMode,\n} from \"./types.ts\";\n\nexport type { QueueMode } from \"./types.ts\";\n\nfunction defaultConvertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(\n\t\t(message) => message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\",\n\t);\n}\n\nconst EMPTY_USAGE = {\n\tinput: 0,\n\toutput: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n};\n\nconst DEFAULT_MODEL = {\n\tid: \"unknown\",\n\tname: \"unknown\",\n\tapi: \"unknown\",\n\tprovider: \"unknown\",\n\tbaseUrl: \"\",\n\treasoning: false,\n\tinput: [],\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\tcontextWindow: 0,\n\tmaxTokens: 0,\n} satisfies Model<any>;\n\ntype MutableAgentState = Omit<AgentState, \"isStreaming\" | \"streamingMessage\" | \"pendingToolCalls\" | \"errorMessage\"> & {\n\tisStreaming: boolean;\n\tstreamingMessage?: AgentMessage;\n\tpendingToolCalls: Set<string>;\n\terrorMessage?: string;\n};\n\nfunction createMutableAgentState(\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>,\n): MutableAgentState {\n\tlet tools = initialState?.tools?.slice() ?? [];\n\tlet messages = initialState?.messages?.slice() ?? [];\n\n\treturn {\n\t\tsystemPrompt: initialState?.systemPrompt ?? \"\",\n\t\tmodel: initialState?.model ?? DEFAULT_MODEL,\n\t\tthinkingLevel: initialState?.thinkingLevel ?? \"off\",\n\t\tget tools() {\n\t\t\treturn tools;\n\t\t},\n\t\tset tools(nextTools: AgentTool<any>[]) {\n\t\t\ttools = nextTools.slice();\n\t\t},\n\t\tget messages() {\n\t\t\treturn messages;\n\t\t},\n\t\tset messages(nextMessages: AgentMessage[]) {\n\t\t\tmessages = nextMessages.slice();\n\t\t},\n\t\tisStreaming: false,\n\t\tstreamingMessage: undefined,\n\t\tpendingToolCalls: new Set<string>(),\n\t\terrorMessage: undefined,\n\t};\n}\n\n/** Options for constructing an {@link Agent}. */\nexport interface AgentOptions {\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>;\n\tconvertToLlm?: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\ttransformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tstreamFn?: StreamFn;\n\tgetApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tonPayload?: SimpleStreamOptions[\"onPayload\"];\n\tonResponse?: SimpleStreamOptions[\"onResponse\"];\n\tbeforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise<BeforeToolCallResult | undefined>;\n\tafterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise<AfterToolCallResult | undefined>;\n\tprepareNextTurn?: (\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentLoopTurnUpdate | undefined> | AgentLoopTurnUpdate | undefined;\n\tsteeringMode?: QueueMode;\n\tfollowUpMode?: QueueMode;\n\tsessionId?: string;\n\tthinkingBudgets?: ThinkingBudgets;\n\ttransport?: Transport;\n\tmaxRetryDelayMs?: number;\n\ttoolExecution?: ToolExecutionMode;\n}\n\nclass PendingMessageQueue {\n\tprivate messages: AgentMessage[] = [];\n\tpublic mode: QueueMode;\n\n\tconstructor(mode: QueueMode) {\n\t\tthis.mode = mode;\n\t}\n\n\tenqueue(message: AgentMessage): void {\n\t\tthis.messages.push(message);\n\t}\n\n\thasItems(): boolean {\n\t\treturn this.messages.length > 0;\n\t}\n\n\tdrain(): AgentMessage[] {\n\t\tif (this.mode === \"all\") {\n\t\t\tconst drained = this.messages.slice();\n\t\t\tthis.messages = [];\n\t\t\treturn drained;\n\t\t}\n\n\t\tconst first = this.messages[0];\n\t\tif (!first) {\n\t\t\treturn [];\n\t\t}\n\t\tthis.messages = this.messages.slice(1);\n\t\treturn [first];\n\t}\n\n\tclear(): void {\n\t\tthis.messages = [];\n\t}\n}\n\ntype ActiveRun = {\n\tpromise: Promise<void>;\n\tresolve: () => void;\n\tabortController: AbortController;\n};\n\n/**\n * Stateful wrapper around the low-level agent loop.\n *\n * `Agent` owns the current transcript, emits lifecycle events, executes tools,\n * and exposes queueing APIs for steering and follow-up messages.\n */\nexport class Agent {\n\tprivate _state: MutableAgentState;\n\tprivate readonly listeners = new Set<(event: AgentEvent, signal: AbortSignal) => Promise<void> | void>();\n\tprivate readonly steeringQueue: PendingMessageQueue;\n\tprivate readonly followUpQueue: PendingMessageQueue;\n\n\tpublic convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\tpublic transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tpublic streamFn: StreamFn;\n\tpublic getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tpublic onPayload?: SimpleStreamOptions[\"onPayload\"];\n\tpublic onResponse?: SimpleStreamOptions[\"onResponse\"];\n\tpublic beforeToolCall?: (\n\t\tcontext: BeforeToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<BeforeToolCallResult | undefined>;\n\tpublic afterToolCall?: (\n\t\tcontext: AfterToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AfterToolCallResult | undefined>;\n\tpublic prepareNextTurn?: (\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentLoopTurnUpdate | undefined> | AgentLoopTurnUpdate | undefined;\n\tprivate activeRun?: ActiveRun;\n\t/** Session identifier forwarded to providers for cache-aware backends. */\n\tpublic sessionId?: string;\n\t/** Optional per-level thinking token budgets forwarded to the stream function. */\n\tpublic thinkingBudgets?: ThinkingBudgets;\n\t/** Preferred transport forwarded to the stream function. */\n\tpublic transport: Transport;\n\t/** Optional cap for provider-requested retry delays. */\n\tpublic maxRetryDelayMs?: number;\n\t/** Tool execution strategy for assistant messages that contain multiple tool calls. */\n\tpublic toolExecution: ToolExecutionMode;\n\n\tconstructor(options: AgentOptions = {}) {\n\t\tthis._state = createMutableAgentState(options.initialState);\n\t\tthis.convertToLlm = options.convertToLlm ?? defaultConvertToLlm;\n\t\tthis.transformContext = options.transformContext;\n\t\tthis.streamFn = options.streamFn ?? streamSimple;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.onPayload = options.onPayload;\n\t\tthis.onResponse = options.onResponse;\n\t\tthis.beforeToolCall = options.beforeToolCall;\n\t\tthis.afterToolCall = options.afterToolCall;\n\t\tthis.prepareNextTurn = options.prepareNextTurn;\n\t\tthis.steeringQueue = new PendingMessageQueue(options.steeringMode ?? \"one-at-a-time\");\n\t\tthis.followUpQueue = new PendingMessageQueue(options.followUpMode ?? \"one-at-a-time\");\n\t\tthis.sessionId = options.sessionId;\n\t\tthis.thinkingBudgets = options.thinkingBudgets;\n\t\tthis.transport = options.transport ?? \"auto\";\n\t\tthis.maxRetryDelayMs = options.maxRetryDelayMs;\n\t\tthis.toolExecution = options.toolExecution ?? \"parallel\";\n\t}\n\n\t/**\n\t * Subscribe to agent lifecycle events.\n\t *\n\t * Listener promises are awaited in subscription order and are included in\n\t * the current run's settlement. Listeners also receive the active abort\n\t * signal for the current run.\n\t *\n\t * `agent_end` is the final emitted event for a run, but the agent does not\n\t * become idle until all awaited listeners for that event have settled.\n\t */\n\tsubscribe(listener: (event: AgentEvent, signal: AbortSignal) => Promise<void> | void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/**\n\t * Current agent state.\n\t *\n\t * Assigning `state.tools` or `state.messages` copies the provided top-level array.\n\t */\n\tget state(): AgentState {\n\t\treturn this._state;\n\t}\n\n\t/** Controls how queued steering messages are drained. */\n\tset steeringMode(mode: QueueMode) {\n\t\tthis.steeringQueue.mode = mode;\n\t}\n\n\tget steeringMode(): QueueMode {\n\t\treturn this.steeringQueue.mode;\n\t}\n\n\t/** Controls how queued follow-up messages are drained. */\n\tset followUpMode(mode: QueueMode) {\n\t\tthis.followUpQueue.mode = mode;\n\t}\n\n\tget followUpMode(): QueueMode {\n\t\treturn this.followUpQueue.mode;\n\t}\n\n\t/** Queue a message to be injected after the current assistant turn finishes. */\n\tsteer(message: AgentMessage): void {\n\t\tthis.steeringQueue.enqueue(message);\n\t}\n\n\t/** Queue a message to run only after the agent would otherwise stop. */\n\tfollowUp(message: AgentMessage): void {\n\t\tthis.followUpQueue.enqueue(message);\n\t}\n\n\t/** Remove all queued steering messages. */\n\tclearSteeringQueue(): void {\n\t\tthis.steeringQueue.clear();\n\t}\n\n\t/** Remove all queued follow-up messages. */\n\tclearFollowUpQueue(): void {\n\t\tthis.followUpQueue.clear();\n\t}\n\n\t/** Remove all queued steering and follow-up messages. */\n\tclearAllQueues(): void {\n\t\tthis.clearSteeringQueue();\n\t\tthis.clearFollowUpQueue();\n\t}\n\n\t/** Returns true when either queue still contains pending messages. */\n\thasQueuedMessages(): boolean {\n\t\treturn this.steeringQueue.hasItems() || this.followUpQueue.hasItems();\n\t}\n\n\t/** Active abort signal for the current run, if any. */\n\tget signal(): AbortSignal | undefined {\n\t\treturn this.activeRun?.abortController.signal;\n\t}\n\n\t/** Abort the current run, if one is active. */\n\tabort(): void {\n\t\tthis.activeRun?.abortController.abort();\n\t}\n\n\t/**\n\t * Resolve when the current run and all awaited event listeners have finished.\n\t *\n\t * This resolves after `agent_end` listeners settle.\n\t */\n\twaitForIdle(): Promise<void> {\n\t\treturn this.activeRun?.promise ?? Promise.resolve();\n\t}\n\n\t/** Clear transcript state, runtime state, and queued messages. */\n\treset(): void {\n\t\tthis._state.messages = [];\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis._state.errorMessage = undefined;\n\t\tthis.clearFollowUpQueue();\n\t\tthis.clearSteeringQueue();\n\t}\n\n\t/** Start a new prompt from text, a single message, or a batch of messages. */\n\tasync prompt(message: AgentMessage | AgentMessage[]): Promise<void>;\n\tasync prompt(input: string, images?: ImageContent[]): Promise<void>;\n\tasync prompt(input: string | AgentMessage | AgentMessage[], images?: ImageContent[]): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.\",\n\t\t\t);\n\t\t}\n\t\tconst messages = this.normalizePromptInput(input, images);\n\t\tawait this.runPromptMessages(messages);\n\t}\n\n\t/** Continue from the current transcript. The last message must be a user or tool-result message. */\n\tasync continue(): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\"Agent is already processing. Wait for completion before continuing.\");\n\t\t}\n\n\t\tconst lastMessage = this._state.messages[this._state.messages.length - 1];\n\t\tif (!lastMessage) {\n\t\t\tthrow new Error(\"No messages to continue from\");\n\t\t}\n\n\t\tif (lastMessage.role === \"assistant\") {\n\t\t\tconst queuedSteering = this.steeringQueue.drain();\n\t\t\tif (queuedSteering.length > 0) {\n\t\t\t\tawait this.runPromptMessages(queuedSteering, { skipInitialSteeringPoll: true });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst queuedFollowUps = this.followUpQueue.drain();\n\t\t\tif (queuedFollowUps.length > 0) {\n\t\t\t\tawait this.runPromptMessages(queuedFollowUps);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t\t}\n\n\t\tawait this.runContinuation();\n\t}\n\n\tprivate normalizePromptInput(\n\t\tinput: string | AgentMessage | AgentMessage[],\n\t\timages?: ImageContent[],\n\t): AgentMessage[] {\n\t\tif (Array.isArray(input)) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input !== \"string\") {\n\t\t\treturn [input];\n\t\t}\n\n\t\tconst content: Array<TextContent | ImageContent> = [{ type: \"text\", text: input }];\n\t\tif (images && images.length > 0) {\n\t\t\tcontent.push(...images);\n\t\t}\n\t\treturn [{ role: \"user\", content, timestamp: Date.now() }];\n\t}\n\n\tprivate async runPromptMessages(\n\t\tmessages: AgentMessage[],\n\t\toptions: { skipInitialSteeringPoll?: boolean } = {},\n\t): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoop(\n\t\t\t\tmessages,\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(options),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async runContinuation(): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoopContinue(\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate createContextSnapshot(): AgentContext {\n\t\treturn {\n\t\t\tsystemPrompt: this._state.systemPrompt,\n\t\t\tmessages: this._state.messages.slice(),\n\t\t\ttools: this._state.tools.slice(),\n\t\t};\n\t}\n\n\tprivate createLoopConfig(options: { skipInitialSteeringPoll?: boolean } = {}): AgentLoopConfig {\n\t\tlet skipInitialSteeringPoll = options.skipInitialSteeringPoll === true;\n\t\treturn {\n\t\t\tmodel: this._state.model,\n\t\t\treasoning: this._state.thinkingLevel === \"off\" ? undefined : this._state.thinkingLevel,\n\t\t\tsessionId: this.sessionId,\n\t\t\tonPayload: this.onPayload,\n\t\t\tonResponse: this.onResponse,\n\t\t\ttransport: this.transport,\n\t\t\tthinkingBudgets: this.thinkingBudgets,\n\t\t\tmaxRetryDelayMs: this.maxRetryDelayMs,\n\t\t\ttoolExecution: this.toolExecution,\n\t\t\tbeforeToolCall: this.beforeToolCall,\n\t\t\tafterToolCall: this.afterToolCall,\n\t\t\tprepareNextTurn: this.prepareNextTurn ? async () => await this.prepareNextTurn?.(this.signal) : undefined,\n\t\t\tconvertToLlm: this.convertToLlm,\n\t\t\ttransformContext: this.transformContext,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tgetSteeringMessages: async () => {\n\t\t\t\tif (skipInitialSteeringPoll) {\n\t\t\t\t\tskipInitialSteeringPoll = false;\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn this.steeringQueue.drain();\n\t\t\t},\n\t\t\tgetFollowUpMessages: async () => this.followUpQueue.drain(),\n\t\t};\n\t}\n\n\tprivate async runWithLifecycle(executor: (signal: AbortSignal) => Promise<void>): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\"Agent is already processing.\");\n\t\t}\n\n\t\tconst abortController = new AbortController();\n\t\tlet resolvePromise = () => {};\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolvePromise = resolve;\n\t\t});\n\t\tthis.activeRun = { promise, resolve: resolvePromise, abortController };\n\n\t\tthis._state.isStreaming = true;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.errorMessage = undefined;\n\n\t\ttry {\n\t\t\tawait executor(abortController.signal);\n\t\t} catch (error) {\n\t\t\tawait this.handleRunFailure(error, abortController.signal.aborted);\n\t\t} finally {\n\t\t\tthis.finishRun();\n\t\t}\n\t}\n\n\tprivate async handleRunFailure(error: unknown, aborted: boolean): Promise<void> {\n\t\tconst failureMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\t\tapi: this._state.model.api,\n\t\t\tprovider: this._state.model.provider,\n\t\t\tmodel: this._state.model.id,\n\t\t\tusage: EMPTY_USAGE,\n\t\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies AgentMessage;\n\t\tawait this.processEvents({ type: \"message_start\", message: failureMessage });\n\t\tawait this.processEvents({ type: \"message_end\", message: failureMessage });\n\t\tawait this.processEvents({ type: \"turn_end\", message: failureMessage, toolResults: [] });\n\t\tawait this.processEvents({ type: \"agent_end\", messages: [failureMessage] });\n\t}\n\n\tprivate finishRun(): void {\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis.activeRun?.resolve();\n\t\tthis.activeRun = undefined;\n\t}\n\n\t/**\n\t * Reduce internal state for a loop event, then await listeners.\n\t *\n\t * `agent_end` only means no further loop events will be emitted. The run is\n\t * considered idle later, after all awaited listeners for `agent_end` finish\n\t * and `finishRun()` clears runtime-owned state.\n\t */\n\tprivate async processEvents(event: AgentEvent): Promise<void> {\n\t\tswitch (event.type) {\n\t\t\tcase \"message_start\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_update\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tthis._state.messages.push(event.message);\n\t\t\t\tbreak;\n\n\t\t\tcase \"tool_execution_start\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.add(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"tool_execution_end\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.delete(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"turn_end\":\n\t\t\t\tif (event.message.role === \"assistant\" && event.message.errorMessage) {\n\t\t\t\t\tthis._state.errorMessage = event.message.errorMessage;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"agent_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst signal = this.activeRun?.abortController.signal;\n\t\tif (!signal) {\n\t\t\tthrow new Error(\"Agent listener invoked outside active run\");\n\t\t}\n\t\tfor (const listener of this.listeners) {\n\t\t\tawait listener(event, signal);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ImageContent,\n\ttype Message,\n\ttype Model,\n\ttype SimpleStreamOptions,\n\tstreamSimple,\n\ttype TextContent,\n\ttype ThinkingBudgets,\n\ttype Transport,\n} from \"omk-ai\";\nimport { runAgentLoop, runAgentLoopContinue } from \"./agent-loop.ts\";\nimport type {\n\tAfterToolCallContext,\n\tAfterToolCallResult,\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentLoopTurnUpdate,\n\tAgentMessage,\n\tAgentState,\n\tAgentTool,\n\tBeforeToolCallContext,\n\tBeforeToolCallResult,\n\tQueueMode,\n\tStreamFn,\n\tToolExecutionMode,\n} from \"./types.ts\";\n\nexport type { QueueMode } from \"./types.ts\";\n\nfunction defaultConvertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(\n\t\t(message) => message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\",\n\t);\n}\n\nconst EMPTY_USAGE = {\n\tinput: 0,\n\toutput: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n};\n\nconst DEFAULT_MODEL = {\n\tid: \"unknown\",\n\tname: \"unknown\",\n\tapi: \"unknown\",\n\tprovider: \"unknown\",\n\tbaseUrl: \"\",\n\treasoning: false,\n\tinput: [],\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\tcontextWindow: 0,\n\tmaxTokens: 0,\n} satisfies Model<any>;\n\ntype MutableAgentState = Omit<AgentState, \"isStreaming\" | \"streamingMessage\" | \"pendingToolCalls\" | \"errorMessage\"> & {\n\tisStreaming: boolean;\n\tstreamingMessage?: AgentMessage;\n\tpendingToolCalls: Set<string>;\n\terrorMessage?: string;\n};\n\nfunction createMutableAgentState(\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>,\n): MutableAgentState {\n\tlet tools = initialState?.tools?.slice() ?? [];\n\tlet messages = initialState?.messages?.slice() ?? [];\n\n\treturn {\n\t\tsystemPrompt: initialState?.systemPrompt ?? \"\",\n\t\tmodel: initialState?.model ?? DEFAULT_MODEL,\n\t\tthinkingLevel: initialState?.thinkingLevel ?? \"off\",\n\t\tget tools() {\n\t\t\treturn tools;\n\t\t},\n\t\tset tools(nextTools: AgentTool<any>[]) {\n\t\t\ttools = nextTools.slice();\n\t\t},\n\t\tget messages() {\n\t\t\treturn messages;\n\t\t},\n\t\tset messages(nextMessages: AgentMessage[]) {\n\t\t\tmessages = nextMessages.slice();\n\t\t},\n\t\tisStreaming: false,\n\t\tstreamingMessage: undefined,\n\t\tpendingToolCalls: new Set<string>(),\n\t\terrorMessage: undefined,\n\t};\n}\n\n/** Options for constructing an {@link Agent}. */\nexport interface AgentOptions {\n\tinitialState?: Partial<Omit<AgentState, \"pendingToolCalls\" | \"isStreaming\" | \"streamingMessage\" | \"errorMessage\">>;\n\tconvertToLlm?: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\ttransformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tstreamFn?: StreamFn;\n\tgetApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tonPayload?: SimpleStreamOptions[\"onPayload\"];\n\tonResponse?: SimpleStreamOptions[\"onResponse\"];\n\tbeforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise<BeforeToolCallResult | undefined>;\n\tafterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise<AfterToolCallResult | undefined>;\n\tprepareNextTurn?: (\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentLoopTurnUpdate | undefined> | AgentLoopTurnUpdate | undefined;\n\tsteeringMode?: QueueMode;\n\tfollowUpMode?: QueueMode;\n\tsessionId?: string;\n\tthinkingBudgets?: ThinkingBudgets;\n\ttransport?: Transport;\n\tmaxRetryDelayMs?: number;\n\ttoolExecution?: ToolExecutionMode;\n}\n\nclass PendingMessageQueue {\n\tprivate messages: AgentMessage[] = [];\n\tpublic mode: QueueMode;\n\n\tconstructor(mode: QueueMode) {\n\t\tthis.mode = mode;\n\t}\n\n\tenqueue(message: AgentMessage): void {\n\t\tthis.messages.push(message);\n\t}\n\n\thasItems(): boolean {\n\t\treturn this.messages.length > 0;\n\t}\n\n\tdrain(): AgentMessage[] {\n\t\tif (this.mode === \"all\") {\n\t\t\tconst drained = this.messages.slice();\n\t\t\tthis.messages = [];\n\t\t\treturn drained;\n\t\t}\n\n\t\tconst first = this.messages[0];\n\t\tif (!first) {\n\t\t\treturn [];\n\t\t}\n\t\tthis.messages = this.messages.slice(1);\n\t\treturn [first];\n\t}\n\n\tclear(): void {\n\t\tthis.messages = [];\n\t}\n}\n\ntype ActiveRun = {\n\tpromise: Promise<void>;\n\tresolve: () => void;\n\tabortController: AbortController;\n};\n\n/**\n * Stateful wrapper around the low-level agent loop.\n *\n * `Agent` owns the current transcript, emits lifecycle events, executes tools,\n * and exposes queueing APIs for steering and follow-up messages.\n */\nexport class Agent {\n\tprivate _state: MutableAgentState;\n\tprivate readonly listeners = new Set<(event: AgentEvent, signal: AbortSignal) => Promise<void> | void>();\n\tprivate readonly steeringQueue: PendingMessageQueue;\n\tprivate readonly followUpQueue: PendingMessageQueue;\n\n\tpublic convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\tpublic transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;\n\tpublic streamFn: StreamFn;\n\tpublic getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\tpublic onPayload?: SimpleStreamOptions[\"onPayload\"];\n\tpublic onResponse?: SimpleStreamOptions[\"onResponse\"];\n\tpublic beforeToolCall?: (\n\t\tcontext: BeforeToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<BeforeToolCallResult | undefined>;\n\tpublic afterToolCall?: (\n\t\tcontext: AfterToolCallContext,\n\t\tsignal?: AbortSignal,\n\t) => Promise<AfterToolCallResult | undefined>;\n\tpublic prepareNextTurn?: (\n\t\tsignal?: AbortSignal,\n\t) => Promise<AgentLoopTurnUpdate | undefined> | AgentLoopTurnUpdate | undefined;\n\tprivate activeRun?: ActiveRun;\n\t/** Session identifier forwarded to providers for cache-aware backends. */\n\tpublic sessionId?: string;\n\t/** Optional per-level thinking token budgets forwarded to the stream function. */\n\tpublic thinkingBudgets?: ThinkingBudgets;\n\t/** Preferred transport forwarded to the stream function. */\n\tpublic transport: Transport;\n\t/** Optional cap for provider-requested retry delays. */\n\tpublic maxRetryDelayMs?: number;\n\t/** Tool execution strategy for assistant messages that contain multiple tool calls. */\n\tpublic toolExecution: ToolExecutionMode;\n\n\tconstructor(options: AgentOptions = {}) {\n\t\tthis._state = createMutableAgentState(options.initialState);\n\t\tthis.convertToLlm = options.convertToLlm ?? defaultConvertToLlm;\n\t\tthis.transformContext = options.transformContext;\n\t\tthis.streamFn = options.streamFn ?? streamSimple;\n\t\tthis.getApiKey = options.getApiKey;\n\t\tthis.onPayload = options.onPayload;\n\t\tthis.onResponse = options.onResponse;\n\t\tthis.beforeToolCall = options.beforeToolCall;\n\t\tthis.afterToolCall = options.afterToolCall;\n\t\tthis.prepareNextTurn = options.prepareNextTurn;\n\t\tthis.steeringQueue = new PendingMessageQueue(options.steeringMode ?? \"one-at-a-time\");\n\t\tthis.followUpQueue = new PendingMessageQueue(options.followUpMode ?? \"one-at-a-time\");\n\t\tthis.sessionId = options.sessionId;\n\t\tthis.thinkingBudgets = options.thinkingBudgets;\n\t\tthis.transport = options.transport ?? \"auto\";\n\t\tthis.maxRetryDelayMs = options.maxRetryDelayMs;\n\t\tthis.toolExecution = options.toolExecution ?? \"parallel\";\n\t}\n\n\t/**\n\t * Subscribe to agent lifecycle events.\n\t *\n\t * Listener promises are awaited in subscription order and are included in\n\t * the current run's settlement. Listeners also receive the active abort\n\t * signal for the current run.\n\t *\n\t * `agent_end` is the final emitted event for a run, but the agent does not\n\t * become idle until all awaited listeners for that event have settled.\n\t */\n\tsubscribe(listener: (event: AgentEvent, signal: AbortSignal) => Promise<void> | void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/**\n\t * Current agent state.\n\t *\n\t * Assigning `state.tools` or `state.messages` copies the provided top-level array.\n\t */\n\tget state(): AgentState {\n\t\treturn this._state;\n\t}\n\n\t/** Controls how queued steering messages are drained. */\n\tset steeringMode(mode: QueueMode) {\n\t\tthis.steeringQueue.mode = mode;\n\t}\n\n\tget steeringMode(): QueueMode {\n\t\treturn this.steeringQueue.mode;\n\t}\n\n\t/** Controls how queued follow-up messages are drained. */\n\tset followUpMode(mode: QueueMode) {\n\t\tthis.followUpQueue.mode = mode;\n\t}\n\n\tget followUpMode(): QueueMode {\n\t\treturn this.followUpQueue.mode;\n\t}\n\n\t/** Queue a message to be injected after the current assistant turn finishes. */\n\tsteer(message: AgentMessage): void {\n\t\tthis.steeringQueue.enqueue(message);\n\t}\n\n\t/** Queue a message to run only after the agent would otherwise stop. */\n\tfollowUp(message: AgentMessage): void {\n\t\tthis.followUpQueue.enqueue(message);\n\t}\n\n\t/** Remove all queued steering messages. */\n\tclearSteeringQueue(): void {\n\t\tthis.steeringQueue.clear();\n\t}\n\n\t/** Remove all queued follow-up messages. */\n\tclearFollowUpQueue(): void {\n\t\tthis.followUpQueue.clear();\n\t}\n\n\t/** Remove all queued steering and follow-up messages. */\n\tclearAllQueues(): void {\n\t\tthis.clearSteeringQueue();\n\t\tthis.clearFollowUpQueue();\n\t}\n\n\t/** Returns true when either queue still contains pending messages. */\n\thasQueuedMessages(): boolean {\n\t\treturn this.steeringQueue.hasItems() || this.followUpQueue.hasItems();\n\t}\n\n\t/** Active abort signal for the current run, if any. */\n\tget signal(): AbortSignal | undefined {\n\t\treturn this.activeRun?.abortController.signal;\n\t}\n\n\t/** Abort the current run, if one is active. */\n\tabort(): void {\n\t\tthis.activeRun?.abortController.abort();\n\t}\n\n\t/**\n\t * Resolve when the current run and all awaited event listeners have finished.\n\t *\n\t * This resolves after `agent_end` listeners settle.\n\t */\n\twaitForIdle(): Promise<void> {\n\t\treturn this.activeRun?.promise ?? Promise.resolve();\n\t}\n\n\t/** Clear transcript state, runtime state, and queued messages. */\n\treset(): void {\n\t\tthis._state.messages = [];\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis._state.errorMessage = undefined;\n\t\tthis.clearFollowUpQueue();\n\t\tthis.clearSteeringQueue();\n\t}\n\n\t/** Start a new prompt from text, a single message, or a batch of messages. */\n\tasync prompt(message: AgentMessage | AgentMessage[]): Promise<void>;\n\tasync prompt(input: string, images?: ImageContent[]): Promise<void>;\n\tasync prompt(input: string | AgentMessage | AgentMessage[], images?: ImageContent[]): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.\",\n\t\t\t);\n\t\t}\n\t\tconst messages = this.normalizePromptInput(input, images);\n\t\tawait this.runPromptMessages(messages);\n\t}\n\n\t/** Continue from the current transcript. The last message must be a user or tool-result message. */\n\tasync continue(): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\"Agent is already processing. Wait for completion before continuing.\");\n\t\t}\n\n\t\tconst lastMessage = this._state.messages[this._state.messages.length - 1];\n\t\tif (!lastMessage) {\n\t\t\tthrow new Error(\"No messages to continue from\");\n\t\t}\n\n\t\tif (lastMessage.role === \"assistant\") {\n\t\t\tconst queuedSteering = this.steeringQueue.drain();\n\t\t\tif (queuedSteering.length > 0) {\n\t\t\t\tawait this.runPromptMessages(queuedSteering, { skipInitialSteeringPoll: true });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst queuedFollowUps = this.followUpQueue.drain();\n\t\t\tif (queuedFollowUps.length > 0) {\n\t\t\t\tawait this.runPromptMessages(queuedFollowUps);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Last message is a completed assistant turn. Two sub-cases:\n\t\t\t// 1. The assistant message carries pending tool calls without matching\n\t\t\t// tool results -> the provider will reject this, so fail fast with a\n\t\t\t// clear, actionable error.\n\t\t\t// 2. The assistant message is plain text/thinking (no tool calls). This is\n\t\t\t// a finished turn (e.g. after compaction, session resume, or an\n\t\t\t// explicit \"continue\" request). We honour it by injecting an empty\n\t\t\t// user prompt so the model can extend its previous answer rather than\n\t\t\t// throwing the opaque \"Cannot continue from message role: assistant\".\n\t\t\tconst hasPendingToolCalls = lastMessage.content.some((c) => c.type === \"toolCall\");\n\t\t\tif (hasPendingToolCalls) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cannot continue: the last assistant message has pending tool calls without results. \" +\n\t\t\t\t\t\t\"Provide tool results (or a new user message) before continuing.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait this.runPromptMessages([{ role: \"user\", content: [{ type: \"text\", text: \"\" }], timestamp: Date.now() }]);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runContinuation();\n\t}\n\n\tprivate normalizePromptInput(\n\t\tinput: string | AgentMessage | AgentMessage[],\n\t\timages?: ImageContent[],\n\t): AgentMessage[] {\n\t\tif (Array.isArray(input)) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input !== \"string\") {\n\t\t\treturn [input];\n\t\t}\n\n\t\tconst content: Array<TextContent | ImageContent> = [{ type: \"text\", text: input }];\n\t\tif (images && images.length > 0) {\n\t\t\tcontent.push(...images);\n\t\t}\n\t\treturn [{ role: \"user\", content, timestamp: Date.now() }];\n\t}\n\n\tprivate async runPromptMessages(\n\t\tmessages: AgentMessage[],\n\t\toptions: { skipInitialSteeringPoll?: boolean } = {},\n\t): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoop(\n\t\t\t\tmessages,\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(options),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async runContinuation(): Promise<void> {\n\t\tawait this.runWithLifecycle(async (signal) => {\n\t\t\tawait runAgentLoopContinue(\n\t\t\t\tthis.createContextSnapshot(),\n\t\t\t\tthis.createLoopConfig(),\n\t\t\t\t(event) => this.processEvents(event),\n\t\t\t\tsignal,\n\t\t\t\tthis.streamFn,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate createContextSnapshot(): AgentContext {\n\t\treturn {\n\t\t\tsystemPrompt: this._state.systemPrompt,\n\t\t\tmessages: this._state.messages.slice(),\n\t\t\ttools: this._state.tools.slice(),\n\t\t};\n\t}\n\n\tprivate createLoopConfig(options: { skipInitialSteeringPoll?: boolean } = {}): AgentLoopConfig {\n\t\tlet skipInitialSteeringPoll = options.skipInitialSteeringPoll === true;\n\t\treturn {\n\t\t\tmodel: this._state.model,\n\t\t\treasoning: this._state.thinkingLevel === \"off\" ? undefined : this._state.thinkingLevel,\n\t\t\tsessionId: this.sessionId,\n\t\t\tonPayload: this.onPayload,\n\t\t\tonResponse: this.onResponse,\n\t\t\ttransport: this.transport,\n\t\t\tthinkingBudgets: this.thinkingBudgets,\n\t\t\tmaxRetryDelayMs: this.maxRetryDelayMs,\n\t\t\ttoolExecution: this.toolExecution,\n\t\t\tbeforeToolCall: this.beforeToolCall,\n\t\t\tafterToolCall: this.afterToolCall,\n\t\t\tprepareNextTurn: this.prepareNextTurn ? async () => await this.prepareNextTurn?.(this.signal) : undefined,\n\t\t\tconvertToLlm: this.convertToLlm,\n\t\t\ttransformContext: this.transformContext,\n\t\t\tgetApiKey: this.getApiKey,\n\t\t\tgetSteeringMessages: async () => {\n\t\t\t\tif (skipInitialSteeringPoll) {\n\t\t\t\t\tskipInitialSteeringPoll = false;\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn this.steeringQueue.drain();\n\t\t\t},\n\t\t\tgetFollowUpMessages: async () => this.followUpQueue.drain(),\n\t\t};\n\t}\n\n\tprivate async runWithLifecycle(executor: (signal: AbortSignal) => Promise<void>): Promise<void> {\n\t\tif (this.activeRun) {\n\t\t\tthrow new Error(\"Agent is already processing.\");\n\t\t}\n\n\t\tconst abortController = new AbortController();\n\t\tlet resolvePromise = () => {};\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolvePromise = resolve;\n\t\t});\n\t\tthis.activeRun = { promise, resolve: resolvePromise, abortController };\n\n\t\tthis._state.isStreaming = true;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.errorMessage = undefined;\n\n\t\ttry {\n\t\t\tawait executor(abortController.signal);\n\t\t} catch (error) {\n\t\t\tawait this.handleRunFailure(error, abortController.signal.aborted);\n\t\t} finally {\n\t\t\tthis.finishRun();\n\t\t}\n\t}\n\n\tprivate async handleRunFailure(error: unknown, aborted: boolean): Promise<void> {\n\t\tconst failureMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\t\tapi: this._state.model.api,\n\t\t\tprovider: this._state.model.provider,\n\t\t\tmodel: this._state.model.id,\n\t\t\tusage: EMPTY_USAGE,\n\t\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies AgentMessage;\n\t\tawait this.processEvents({ type: \"message_start\", message: failureMessage });\n\t\tawait this.processEvents({ type: \"message_end\", message: failureMessage });\n\t\tawait this.processEvents({ type: \"turn_end\", message: failureMessage, toolResults: [] });\n\t\tawait this.processEvents({ type: \"agent_end\", messages: [failureMessage] });\n\t}\n\n\tprivate finishRun(): void {\n\t\tthis._state.isStreaming = false;\n\t\tthis._state.streamingMessage = undefined;\n\t\tthis._state.pendingToolCalls = new Set<string>();\n\t\tthis.activeRun?.resolve();\n\t\tthis.activeRun = undefined;\n\t}\n\n\t/**\n\t * Reduce internal state for a loop event, then await listeners.\n\t *\n\t * `agent_end` only means no further loop events will be emitted. The run is\n\t * considered idle later, after all awaited listeners for `agent_end` finish\n\t * and `finishRun()` clears runtime-owned state.\n\t */\n\tprivate async processEvents(event: AgentEvent): Promise<void> {\n\t\tswitch (event.type) {\n\t\t\tcase \"message_start\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_update\":\n\t\t\t\tthis._state.streamingMessage = event.message;\n\t\t\t\tbreak;\n\n\t\t\tcase \"message_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tthis._state.messages.push(event.message);\n\t\t\t\tbreak;\n\n\t\t\tcase \"tool_execution_start\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.add(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"tool_execution_end\": {\n\t\t\t\tconst pendingToolCalls = new Set(this._state.pendingToolCalls);\n\t\t\t\tpendingToolCalls.delete(event.toolCallId);\n\t\t\t\tthis._state.pendingToolCalls = pendingToolCalls;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"turn_end\":\n\t\t\t\tif (event.message.role === \"assistant\" && event.message.errorMessage) {\n\t\t\t\t\tthis._state.errorMessage = event.message.errorMessage;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"agent_end\":\n\t\t\t\tthis._state.streamingMessage = undefined;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst signal = this.activeRun?.abortController.signal;\n\t\tif (!signal) {\n\t\t\tthrow new Error(\"Agent listener invoked outside active run\");\n\t\t}\n\t\tfor (const listener of this.listeners) {\n\t\t\tawait listener(event, signal);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export type ReverseSkillPlatform = "windows" | "linux" | "macos" | "kali" | "unknown";
|
|
2
|
+
export type ReverseSkillRisk = "passive-analysis" | "local-tooling" | "active-security" | "exploit-development";
|
|
3
|
+
export interface ReverseSkillRoute {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
skillPath: string;
|
|
7
|
+
targetPatterns: string[];
|
|
8
|
+
intentPatterns: string[];
|
|
9
|
+
toolPatterns: string[];
|
|
10
|
+
keywords: string[];
|
|
11
|
+
requiredTools: string[];
|
|
12
|
+
optionalTools: string[];
|
|
13
|
+
skillHints: string[];
|
|
14
|
+
mcpHints: string[];
|
|
15
|
+
hookHints: string[];
|
|
16
|
+
acceptance: string[];
|
|
17
|
+
firstActions: string[];
|
|
18
|
+
risk: ReverseSkillRisk;
|
|
19
|
+
}
|
|
20
|
+
export interface ReverseSkillRouteInput {
|
|
21
|
+
query: string;
|
|
22
|
+
targetType?: string;
|
|
23
|
+
intent?: string;
|
|
24
|
+
toolchain?: string;
|
|
25
|
+
platform?: ReverseSkillPlatform;
|
|
26
|
+
maxAlternatives?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ReverseSkillRouteScore {
|
|
29
|
+
route: ReverseSkillRoute;
|
|
30
|
+
score: number;
|
|
31
|
+
confidence: number;
|
|
32
|
+
matched: {
|
|
33
|
+
target: string[];
|
|
34
|
+
intent: string[];
|
|
35
|
+
toolchain: string[];
|
|
36
|
+
keywords: string[];
|
|
37
|
+
};
|
|
38
|
+
missingDimensions: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface ReverseSkillRouteDecision {
|
|
41
|
+
query: string;
|
|
42
|
+
platform: ReverseSkillPlatform;
|
|
43
|
+
normalizedQuery: string;
|
|
44
|
+
primary?: ReverseSkillRouteScore;
|
|
45
|
+
alternatives: ReverseSkillRouteScore[];
|
|
46
|
+
unmatched: boolean;
|
|
47
|
+
nextAction: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ReverseSkillSpecInput {
|
|
50
|
+
name: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
triggerSummary: string;
|
|
53
|
+
routeIds?: string[];
|
|
54
|
+
workflowSteps?: string[];
|
|
55
|
+
tools?: string[];
|
|
56
|
+
mcpServers?: string[];
|
|
57
|
+
hooks?: string[];
|
|
58
|
+
acceptance?: string[];
|
|
59
|
+
references?: string[];
|
|
60
|
+
safetyNotes?: string[];
|
|
61
|
+
}
|
|
62
|
+
export interface ReverseSkillSourceFacts {
|
|
63
|
+
headings: string[];
|
|
64
|
+
skillPaths: string[];
|
|
65
|
+
scriptPaths: string[];
|
|
66
|
+
tools: string[];
|
|
67
|
+
mcpServers: string[];
|
|
68
|
+
triggerTerms: string[];
|
|
69
|
+
}
|
|
70
|
+
export interface ReverseSkillSourceInput {
|
|
71
|
+
name?: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
sourceText: string;
|
|
74
|
+
triggerSummary?: string;
|
|
75
|
+
}
|
|
76
|
+
export declare const REVERSE_SKILL_ROUTES: ReverseSkillRoute[];
|
|
77
|
+
export declare function getReverseSkillToolAliases(tool: string): string[];
|
|
78
|
+
export declare function normalizeReverseSkillText(text: string | undefined): string;
|
|
79
|
+
export declare function routeReverseSkill(input: ReverseSkillRouteInput): ReverseSkillRouteDecision;
|
|
80
|
+
export declare function formatReverseSkillRouteDecision(decision: ReverseSkillRouteDecision): string;
|
|
81
|
+
export declare function planReverseSkillToolChecks(decision: ReverseSkillRouteDecision, maxTools?: number): string[];
|
|
82
|
+
export declare function normalizeReverseSkillName(name: string): string;
|
|
83
|
+
export declare function formatReverseSkillMarkdown(input: ReverseSkillSpecInput): string;
|
|
84
|
+
export declare function extractReverseSkillFactsFromMarkdown(sourceText: string): ReverseSkillSourceFacts;
|
|
85
|
+
export declare function formatReverseSkillFromSource(input: ReverseSkillSourceInput): string;
|
|
86
|
+
//# sourceMappingURL=reverse-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverse-skill.d.ts","sourceRoot":"","sources":["../../src/harness/reverse-skill.ts"],"names":[],"mappings":"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","sourcesContent":["export type ReverseSkillPlatform = \"windows\" | \"linux\" | \"macos\" | \"kali\" | \"unknown\";\n\nexport type ReverseSkillRisk = \"passive-analysis\" | \"local-tooling\" | \"active-security\" | \"exploit-development\";\n\nexport interface ReverseSkillRoute {\n\tid: string;\n\tlabel: string;\n\tskillPath: string;\n\ttargetPatterns: string[];\n\tintentPatterns: string[];\n\ttoolPatterns: string[];\n\tkeywords: string[];\n\trequiredTools: string[];\n\toptionalTools: string[];\n\tskillHints: string[];\n\tmcpHints: string[];\n\thookHints: string[];\n\tacceptance: string[];\n\tfirstActions: string[];\n\trisk: ReverseSkillRisk;\n}\n\nexport interface ReverseSkillRouteInput {\n\tquery: string;\n\ttargetType?: string;\n\tintent?: string;\n\ttoolchain?: string;\n\tplatform?: ReverseSkillPlatform;\n\tmaxAlternatives?: number;\n}\n\nexport interface ReverseSkillRouteScore {\n\troute: ReverseSkillRoute;\n\tscore: number;\n\tconfidence: number;\n\tmatched: {\n\t\ttarget: string[];\n\t\tintent: string[];\n\t\ttoolchain: string[];\n\t\tkeywords: string[];\n\t};\n\tmissingDimensions: string[];\n}\n\nexport interface ReverseSkillRouteDecision {\n\tquery: string;\n\tplatform: ReverseSkillPlatform;\n\tnormalizedQuery: string;\n\tprimary?: ReverseSkillRouteScore;\n\talternatives: ReverseSkillRouteScore[];\n\tunmatched: boolean;\n\tnextAction: string;\n}\n\nexport interface ReverseSkillSpecInput {\n\tname: string;\n\tdescription?: string;\n\ttriggerSummary: string;\n\trouteIds?: string[];\n\tworkflowSteps?: string[];\n\ttools?: string[];\n\tmcpServers?: string[];\n\thooks?: string[];\n\tacceptance?: string[];\n\treferences?: string[];\n\tsafetyNotes?: string[];\n}\n\nexport interface ReverseSkillSourceFacts {\n\theadings: string[];\n\tskillPaths: string[];\n\tscriptPaths: string[];\n\ttools: string[];\n\tmcpServers: string[];\n\ttriggerTerms: string[];\n}\n\nexport interface ReverseSkillSourceInput {\n\tname?: string;\n\tdescription?: string;\n\tsourceText: string;\n\ttriggerSummary?: string;\n}\n\nconst ROUTE_SCORE_TARGET_WEIGHT = 4;\nconst ROUTE_SCORE_INTENT_WEIGHT = 3;\nconst ROUTE_SCORE_TOOL_WEIGHT = 2;\nconst ROUTE_SCORE_KEYWORD_WEIGHT = 1;\nconst ROUTE_SCORE_FULL_TRIAD_BONUS = 4;\nconst ROUTE_SCORE_CONFIDENCE_DENOMINATOR = 14;\n\nexport const REVERSE_SKILL_ROUTES: ReverseSkillRoute[] = [\n\t{\n\t\tid: \"apk-reverse\",\n\t\tlabel: \"APK / Android reverse engineering\",\n\t\tskillPath: \"skills/apk-reverse/SKILL.md\",\n\t\ttargetPatterns: [\"apk\", \"android\", \"aab\", \"smali\", \"jni\", \"dex\", \"안드로이드\", \"反编译\"],\n\t\tintentPatterns: [\n\t\t\t\"decompile\",\n\t\t\t\"unpack\",\n\t\t\t\"repack\",\n\t\t\t\"manifest\",\n\t\t\t\"frida\",\n\t\t\t\"hook\",\n\t\t\t\"ssl pinning\",\n\t\t\t\"root detection\",\n\t\t\t\"rebuild\",\n\t\t\t\"sign\",\n\t\t\t\"설치\",\n\t\t\t\"리패키징\",\n\t\t],\n\t\ttoolPatterns: [\"jadx\", \"apktool\", \"adb\", \"frida\", \"apksigner\", \"zipalign\", \"objection\"],\n\t\tkeywords: [\"classes.dex\", \"androidmanifest\", \"native library\", \"lib/\", \".so\", \"certificate pinning\", \"smali\"],\n\t\trequiredTools: [\"jadx\", \"apktool\"],\n\t\toptionalTools: [\"adb\", \"frida\", \"apksigner\", \"zipalign\", \"objection\"],\n\t\tskillHints: [\"apk-reverse\", \"reverse-engineering\", \"docs-generator\"],\n\t\tmcpHints: [\"filesystem\", \"playwright for app docs only\", \"idapro if native .so becomes dominant\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\", \"subagent-stop-audit\"],\n\t\tacceptance: [\n\t\t\t\"Target package structure is identified\",\n\t\t\t\"Static findings cite class/method/file paths\",\n\t\t\t\"Any dynamic step is scoped to a local test device or emulator\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Confirm target artifact path\",\n\t\t\t\"Decode APK metadata\",\n\t\t\t\"Route native .so files to binary analysis when needed\",\n\t\t],\n\t\trisk: \"local-tooling\",\n\t},\n\t{\n\t\tid: \"ida-reverse\",\n\t\tlabel: \"Binary reverse engineering with decompiler-first workflow\",\n\t\tskillPath: \"skills/ida-reverse/SKILL.md\",\n\t\ttargetPatterns: [\n\t\t\t\"exe\",\n\t\t\t\"dll\",\n\t\t\t\"elf\",\n\t\t\t\"so\",\n\t\t\t\"dylib\",\n\t\t\t\"macho\",\n\t\t\t\"pe\",\n\t\t\t\"binary\",\n\t\t\t\"firmware blob\",\n\t\t\t\"바이너리\",\n\t\t\t\"二进制\",\n\t\t],\n\t\tintentPatterns: [\n\t\t\t\"decompile\",\n\t\t\t\"disassemble\",\n\t\t\t\"xref\",\n\t\t\t\"call graph\",\n\t\t\t\"data flow\",\n\t\t\t\"rename\",\n\t\t\t\"symbol\",\n\t\t\t\"recover\",\n\t\t\t\"pseudocode\",\n\t\t\t\"함수\",\n\t\t\t\"反汇编\",\n\t\t],\n\t\ttoolPatterns: [\"ida\", \"idapro\", \"idalib\", \"ida-pro-mcp\", \"ghidra\", \"r2\", \"radare2\"],\n\t\tkeywords: [\"imports\", \"exports\", \"strings\", \"function\", \"offset\", \"xref\", \"pdb\", \"symbols\"],\n\t\trequiredTools: [\"idapro\"],\n\t\toptionalTools: [\"idalib-mcp\", \"ghidra\", \"radare2\", \"rabin2\"],\n\t\tskillHints: [\"ida-reverse\", \"radare2\", \"reverse-engineering\", \"binary-diff\"],\n\t\tmcpHints: [\"idapro\", \"filesystem\", \"serena\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"],\n\t\tacceptance: [\n\t\t\t\"Functions are cited by address/name\",\n\t\t\t\"Hypotheses cite disassembly, decompiler, xref, or string evidence\",\n\t\t\t\"Output distinguishes evidence from inference\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Collect file metadata\",\n\t\t\t\"Run strings/imports reconnaissance\",\n\t\t\t\"Choose IDA or CLI path based on available tools\",\n\t\t],\n\t\trisk: \"passive-analysis\",\n\t},\n\t{\n\t\tid: \"radare2\",\n\t\tlabel: \"Binary reconnaissance with radare2 CLI\",\n\t\tskillPath: \"skills/radare2/SKILL.md\",\n\t\ttargetPatterns: [\"binary\", \"elf\", \"pe\", \"macho\", \"so\", \"dll\", \"firmware\", \"바이너리\"],\n\t\tintentPatterns: [\"quick recon\", \"strings\", \"imports\", \"exports\", \"patch\", \"offset\", \"cli\", \"headless\"],\n\t\ttoolPatterns: [\"radare2\", \"r2\", \"rabin2\", \"rasm2\", \"radiff2\"],\n\t\tkeywords: [\"entrypoint\", \"section\", \"symbol\", \"hex\", \"disassembly\", \"patch bytes\"],\n\t\trequiredTools: [\"radare2\", \"rabin2\"],\n\t\toptionalTools: [\"rasm2\", \"radiff2\", \"r2pipe\"],\n\t\tskillHints: [\"radare2\", \"ida-reverse\", \"reverse-engineering\"],\n\t\tmcpHints: [\"filesystem\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\"],\n\t\tacceptance: [\n\t\t\t\"Recon output names sections, imports, symbols, and notable strings\",\n\t\t\t\"Patch guidance includes offset and before/after bytes\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Run file metadata\",\n\t\t\t\"Run rabin2-style reconnaissance\",\n\t\t\t\"Escalate to decompiler if CLI evidence is insufficient\",\n\t\t],\n\t\trisk: \"passive-analysis\",\n\t},\n\t{\n\t\tid: \"js-reverse\",\n\t\tlabel: \"Frontend JavaScript signature and request reconstruction\",\n\t\tskillPath: \"skills/js-reverse/SKILL.md\",\n\t\ttargetPatterns: [\n\t\t\t\"javascript\",\n\t\t\t\"js\",\n\t\t\t\"frontend\",\n\t\t\t\"webpack\",\n\t\t\t\"source map\",\n\t\t\t\"sourcemap\",\n\t\t\t\"web\",\n\t\t\t\"browser\",\n\t\t\t\"前端\",\n\t\t\t\"프론트\",\n\t\t],\n\t\tintentPatterns: [\n\t\t\t\"signature\",\n\t\t\t\"encrypted params\",\n\t\t\t\"request replay\",\n\t\t\t\"token\",\n\t\t\t\"decrypt\",\n\t\t\t\"environment patch\",\n\t\t\t\"ast\",\n\t\t\t\"breakpoint\",\n\t\t\t\"hook\",\n\t\t\t\"서명\",\n\t\t\t\"암호화\",\n\t\t],\n\t\ttoolPatterns: [\"playwright\", \"chrome\", \"cdp\", \"jshook\", \"jshookmcp\", \"node\", \"anything-analyzer\"],\n\t\tkeywords: [\n\t\t\t\"sign\",\n\t\t\t\"nonce\",\n\t\t\t\"timestamp\",\n\t\t\t\"crypto\",\n\t\t\t\"axios\",\n\t\t\t\"fetch\",\n\t\t\t\"xhr\",\n\t\t\t\"webpackJsonp\",\n\t\t\t\"localStorage\",\n\t\t\t\"cookie\",\n\t\t],\n\t\trequiredTools: [\"node\"],\n\t\toptionalTools: [\"playwright\", \"jshookmcp\", \"anything-analyzer\", \"chrome\"],\n\t\tskillHints: [\"js-reverse\", \"browser-automation\", \"docs-generator\"],\n\t\tmcpHints: [\"chrome-devtools\", \"playwright\", \"fetch\", \"filesystem\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\", \"session-context\"],\n\t\tacceptance: [\n\t\t\t\"Target request and parameter names are identified\",\n\t\t\t\"Recovered algorithm has a local reproduction or explicit blocker\",\n\t\t\t\"Browser/runtime observations are tied to request evidence\",\n\t\t],\n\t\tfirstActions: [\"Identify target request\", \"Find producer function\", \"Rebuild the minimum local reproduction\"],\n\t\trisk: \"local-tooling\",\n\t},\n\t{\n\t\tid: \"browser-automation\",\n\t\tlabel: \"Browser or desktop evidence collection\",\n\t\tskillPath: \"skills/browser-automation/SKILL.md\",\n\t\ttargetPatterns: [\"website\", \"browser\", \"web app\", \"desktop app\", \"page\", \"form\", \"웹\", \"브라우저\"],\n\t\tintentPatterns: [\n\t\t\t\"open\",\n\t\t\t\"screenshot\",\n\t\t\t\"fill\",\n\t\t\t\"crawl\",\n\t\t\t\"capture\",\n\t\t\t\"network\",\n\t\t\t\"login\",\n\t\t\t\"observe\",\n\t\t\t\"click\",\n\t\t\t\"샷\",\n\t\t\t\"스크린샷\",\n\t\t],\n\t\ttoolPatterns: [\"playwright\", \"chrome-devtools\", \"agent-browser\", \"openreverse\", \"anything-analyzer\"],\n\t\tkeywords: [\"dom\", \"selector\", \"network log\", \"console\", \"cookie\", \"screenshot\", \"trace\"],\n\t\trequiredTools: [\"playwright\"],\n\t\toptionalTools: [\"chrome\", \"agent-browser\", \"anything-analyzer\"],\n\t\tskillHints: [\"browser-automation\", \"js-reverse\", \"docs-generator\"],\n\t\tmcpHints: [\"playwright\", \"chrome-devtools\", \"filesystem\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\"],\n\t\tacceptance: [\n\t\t\t\"Browser state is captured with URL and selector evidence\",\n\t\t\t\"Screenshots or logs are saved as artifacts when visual proof matters\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Open the target in an isolated browser context\",\n\t\t\t\"Capture visible state\",\n\t\t\t\"Record console/network evidence\",\n\t\t],\n\t\trisk: \"local-tooling\",\n\t},\n\t{\n\t\tid: \"ctf-sandbox-orchestrator\",\n\t\tlabel: \"CTF challenge routing\",\n\t\tskillPath: \"../CTF-Sandbox-Orchestrator/ctf-sandbox-orchestrator/SKILL.md\",\n\t\ttargetPatterns: [\"ctf\", \"challenge\", \"flag\", \"pwn\", \"crypto challenge\", \"forensics\", \"misc\", \"rev\", \"대회\"],\n\t\tintentPatterns: [\"solve\", \"find flag\", \"exploit\", \"writeup\", \"sandbox\", \"analyze challenge\"],\n\t\ttoolPatterns: [\"pwntools\", \"gdb\", \"python\", \"sage\", \"z3\", \"binwalk\", \"wireshark\"],\n\t\tkeywords: [\"flag{\", \"ctf\", \"nc \", \"remote\", \"proof\", \"challenge files\"],\n\t\trequiredTools: [],\n\t\toptionalTools: [\"python\", \"gdb\", \"pwntools\", \"z3\", \"binwalk\"],\n\t\tskillHints: [\"ctf-sandbox-orchestrator\", \"reverse-engineering\", \"pwn-chain\", \"docs-generator\"],\n\t\tmcpHints: [\"filesystem\", \"memory\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"],\n\t\tacceptance: [\n\t\t\t\"Challenge category is justified by evidence\",\n\t\t\t\"Solution artifacts are reproducible\",\n\t\t\t\"Writeup includes the shortest verified path\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Inventory challenge files\",\n\t\t\t\"Classify dominant evidence\",\n\t\t\t\"Dispatch to the narrowest CTF sub-skill\",\n\t\t],\n\t\trisk: \"exploit-development\",\n\t},\n\t{\n\t\tid: \"api-security\",\n\t\tlabel: \"API security review and authorized test planning\",\n\t\tskillPath: \"skills/api-security/SKILL.md\",\n\t\ttargetPatterns: [\"api\", \"rest\", \"graphql\", \"websocket\", \"jwt\", \"oauth\", \"endpoint\"],\n\t\tintentPatterns: [\"review\", \"test\", \"auth\", \"idor\", \"bola\", \"bfla\", \"rate limit\", \"schema\", \"권한\", \"越权\"],\n\t\ttoolPatterns: [\"burp\", \"postman\", \"nuclei\", \"zap\", \"curl\", \"graphql\"],\n\t\tkeywords: [\"authorization\", \"authentication\", \"tenant\", \"object id\", \"jwt\", \"scope\", \"graphql\"],\n\t\trequiredTools: [],\n\t\toptionalTools: [\"burpsuite\", \"nuclei\", \"zap\", \"node\", \"python\"],\n\t\tskillHints: [\"api-security\", \"pentest-tools\", \"docs-generator\"],\n\t\tmcpHints: [\"filesystem\", \"github\", \"playwright\"],\n\t\thookHints: [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"],\n\t\tacceptance: [\n\t\t\t\"Scope boundary is explicit\",\n\t\t\t\"Findings include request/response evidence or code references\",\n\t\t\t\"High-risk active steps require explicit target scope\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Identify API surface\",\n\t\t\t\"Map auth and tenant boundaries\",\n\t\t\t\"Choose static review or scoped dynamic testing\",\n\t\t],\n\t\trisk: \"active-security\",\n\t},\n\t{\n\t\tid: \"supply-chain-security\",\n\t\tlabel: \"Supply-chain and CI/CD security analysis\",\n\t\tskillPath: \"skills/supply-chain-security/SKILL.md\",\n\t\ttargetPatterns: [\n\t\t\t\"dependency\",\n\t\t\t\"package\",\n\t\t\t\"sbom\",\n\t\t\t\"container\",\n\t\t\t\"docker\",\n\t\t\t\"ci\",\n\t\t\t\"workflow\",\n\t\t\t\"github actions\",\n\t\t\t\"supply chain\",\n\t\t],\n\t\tintentPatterns: [\"scan\", \"audit\", \"gitleaks\", \"trivy\", \"osv\", \"syft\", \"secret\", \"provenance\", \"attestation\"],\n\t\ttoolPatterns: [\"trivy\", \"syft\", \"gitleaks\", \"osv-scanner\", \"npm audit\", \"semgrep\"],\n\t\tkeywords: [\"package-lock\", \"npm-shrinkwrap\", \"dockerfile\", \"workflow\", \"actions\", \"secret\", \"sbom\"],\n\t\trequiredTools: [],\n\t\toptionalTools: [\"trivy\", \"syft\", \"gitleaks\", \"osv-scanner\", \"semgrep\"],\n\t\tskillHints: [\"supply-chain-security\", \"security-review\", \"docs-generator\"],\n\t\tmcpHints: [\"filesystem\", \"github\"],\n\t\thookHints: [\"protect-secrets\", \"pre-shell-guard\", \"npm-audit-summary\"],\n\t\tacceptance: [\n\t\t\t\"Dependency, workflow, and secret surfaces are separated\",\n\t\t\t\"Findings cite exact files and lockfile evidence\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Inventory package managers and workflows\",\n\t\t\t\"Run non-mutating scans first\",\n\t\t\t\"Triangulate tool output with source evidence\",\n\t\t],\n\t\trisk: \"passive-analysis\",\n\t},\n\t{\n\t\tid: \"docs-generator\",\n\t\tlabel: \"Security or reverse-engineering report generation\",\n\t\tskillPath: \"skills/docs-generator/SKILL.md\",\n\t\ttargetPatterns: [\"report\", \"writeup\", \"documentation\", \"diagram\", \"flowchart\", \"보고서\", \"문서\"],\n\t\tintentPatterns: [\"write\", \"summarize\", \"generate\", \"document\", \"explain\", \"diagram\", \"publish\"],\n\t\ttoolPatterns: [\"markdown\", \"mermaid\", \"graphviz\", \"plantuml\", \"pdf\"],\n\t\tkeywords: [\"executive summary\", \"reproduction\", \"impact\", \"timeline\", \"artifact\", \"evidence\"],\n\t\trequiredTools: [],\n\t\toptionalTools: [\"graphviz\", \"plantuml\", \"pandoc\"],\n\t\tskillHints: [\"docs-generator\", \"diagram-generator\"],\n\t\tmcpHints: [\"filesystem\"],\n\t\thookHints: [\"protect-secrets\"],\n\t\tacceptance: [\n\t\t\t\"Report separates facts, analysis, and recommendations\",\n\t\t\t\"Artifacts and commands are reproducible\",\n\t\t\t\"Sensitive values are redacted\",\n\t\t],\n\t\tfirstActions: [\n\t\t\t\"Collect evidence paths\",\n\t\t\t\"Choose report template\",\n\t\t\t\"Add at least one flow or evidence diagram when useful\",\n\t\t],\n\t\trisk: \"passive-analysis\",\n\t},\n];\n\nconst TOOL_ALIASES: Record<string, string[]> = {\n\t\"anything-analyzer\": [\"anything-analyzer\"],\n\tadb: [\"adb\"],\n\tapktool: [\"apktool\"],\n\tapksigner: [\"apksigner\"],\n\tbinwalk: [\"binwalk\"],\n\tburpsuite: [\"burpsuite\"],\n\tchrome: [\"google-chrome\", \"chromium\", \"chrome\"],\n\tfrida: [\"frida\", \"frida-ps\"],\n\tgdb: [\"gdb\"],\n\tghidra: [\"ghidraRun\", \"analyzeHeadless\"],\n\tgitleaks: [\"gitleaks\"],\n\tgraphviz: [\"dot\"],\n\tidapro: [\"ida\", \"idat\", \"idat64\"],\n\t\"idalib-mcp\": [\"ida-pro-mcp\", \"idalib-mcp\"],\n\tjadx: [\"jadx\"],\n\tjshookmcp: [\"jshook\", \"npx\"],\n\tnode: [\"node\"],\n\tnuclei: [\"nuclei\"],\n\tpandoc: [\"pandoc\"],\n\tplantuml: [\"plantuml\"],\n\tplaywright: [\"playwright\", \"npx\"],\n\tpwntools: [\"python\"],\n\tpython: [\"python3\", \"python\"],\n\tradare2: [\"radare2\", \"r2\"],\n\trabin2: [\"rabin2\"],\n\tradiff2: [\"radiff2\"],\n\trasm2: [\"rasm2\"],\n\tsemgrep: [\"semgrep\"],\n\tsyft: [\"syft\"],\n\ttrivy: [\"trivy\"],\n\tzap: [\"zap.sh\", \"zap-baseline.py\"],\n\tzipalign: [\"zipalign\"],\n\tz3: [\"z3\"],\n};\n\nexport function getReverseSkillToolAliases(tool: string): string[] {\n\treturn TOOL_ALIASES[tool] ?? [tool];\n}\n\nexport function normalizeReverseSkillText(text: string | undefined): string {\n\treturn (text ?? \"\")\n\t\t.normalize(\"NFKC\")\n\t\t.toLowerCase()\n\t\t.replace(/[\\u2018\\u2019]/g, \"'\")\n\t\t.replace(/[\\u201c\\u201d]/g, '\"')\n\t\t.replace(/[_./\\\\:-]+/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction findPatternMatches(text: string, patterns: string[]): string[] {\n\tconst matches: string[] = [];\n\tfor (const pattern of patterns) {\n\t\tconst normalizedPattern = normalizeReverseSkillText(pattern);\n\t\tif (!normalizedPattern) continue;\n\t\tif (text.includes(normalizedPattern)) matches.push(pattern);\n\t}\n\treturn matches;\n}\n\nfunction unique(items: string[]): string[] {\n\treturn Array.from(new Set(items.filter((item) => item.trim().length > 0)));\n}\n\nfunction clampConfidence(score: number): number {\n\tif (score <= 0) return 0;\n\treturn Math.min(0.99, Number((score / ROUTE_SCORE_CONFIDENCE_DENOMINATOR).toFixed(2)));\n}\n\nfunction scoreRoute(\n\troute: ReverseSkillRoute,\n\tinput: ReverseSkillRouteInput,\n\tnormalizedQuery: string,\n): ReverseSkillRouteScore {\n\tconst targetText = normalizeReverseSkillText(`${input.targetType ?? \"\"} ${normalizedQuery}`);\n\tconst intentText = normalizeReverseSkillText(`${input.intent ?? \"\"} ${normalizedQuery}`);\n\tconst toolText = normalizeReverseSkillText(`${input.toolchain ?? \"\"} ${normalizedQuery}`);\n\n\tconst target = findPatternMatches(targetText, route.targetPatterns);\n\tconst intent = findPatternMatches(intentText, route.intentPatterns);\n\tconst toolchain = findPatternMatches(toolText, route.toolPatterns);\n\tconst keywords = findPatternMatches(normalizedQuery, route.keywords);\n\n\tlet score =\n\t\ttarget.length * ROUTE_SCORE_TARGET_WEIGHT +\n\t\tintent.length * ROUTE_SCORE_INTENT_WEIGHT +\n\t\ttoolchain.length * ROUTE_SCORE_TOOL_WEIGHT +\n\t\tkeywords.length * ROUTE_SCORE_KEYWORD_WEIGHT;\n\n\tif (target.length > 0 && intent.length > 0 && toolchain.length > 0) {\n\t\tscore += ROUTE_SCORE_FULL_TRIAD_BONUS;\n\t}\n\n\tconst missingDimensions: string[] = [];\n\tif (target.length === 0) missingDimensions.push(\"target\");\n\tif (intent.length === 0) missingDimensions.push(\"intent\");\n\tif (toolchain.length === 0) missingDimensions.push(\"toolchain\");\n\n\treturn {\n\t\troute,\n\t\tscore,\n\t\tconfidence: clampConfidence(score),\n\t\tmatched: { target, intent, toolchain, keywords },\n\t\tmissingDimensions,\n\t};\n}\n\nexport function routeReverseSkill(input: ReverseSkillRouteInput): ReverseSkillRouteDecision {\n\tconst normalizedQuery = normalizeReverseSkillText(input.query);\n\tconst platform = input.platform ?? \"unknown\";\n\tconst maxAlternatives = input.maxAlternatives ?? 3;\n\tconst scored = REVERSE_SKILL_ROUTES.map((route) => scoreRoute(route, input, normalizedQuery))\n\t\t.filter((candidate) => candidate.score > 0)\n\t\t.sort(\n\t\t\t(a, b) => b.score - a.score || REVERSE_SKILL_ROUTES.indexOf(a.route) - REVERSE_SKILL_ROUTES.indexOf(b.route),\n\t\t);\n\n\tconst primary = scored[0];\n\tconst alternatives = scored.slice(1, maxAlternatives + 1);\n\tconst unmatched = !primary || primary.score < ROUTE_SCORE_TARGET_WEIGHT || primary.confidence < 0.18;\n\tconst nextAction = unmatched\n\t\t? \"No strong route matched. Create or extend a reverse-skill route before executing specialized tooling.\"\n\t\t: `Read ${primary.route.skillPath}, then execute first action: ${primary.route.firstActions[0] ?? \"classify target\"}.`;\n\n\treturn {\n\t\tquery: input.query,\n\t\tplatform,\n\t\tnormalizedQuery,\n\t\tprimary: unmatched ? undefined : primary,\n\t\talternatives,\n\t\tunmatched,\n\t\tnextAction,\n\t};\n}\n\nfunction formatMatches(score: ReverseSkillRouteScore): string {\n\tconst parts = [\n\t\t`target=${score.matched.target.join(\", \") || \"—\"}`,\n\t\t`intent=${score.matched.intent.join(\", \") || \"—\"}`,\n\t\t`toolchain=${score.matched.toolchain.join(\", \") || \"—\"}`,\n\t\t`keywords=${score.matched.keywords.join(\", \") || \"—\"}`,\n\t];\n\treturn parts.join(\"; \");\n}\n\nexport function formatReverseSkillRouteDecision(decision: ReverseSkillRouteDecision): string {\n\tif (decision.unmatched || !decision.primary) {\n\t\treturn [\n\t\t\t\"# Reverse Skill Route\",\n\t\t\t\"\",\n\t\t\t`Query: ${decision.query}`,\n\t\t\t\"\",\n\t\t\t\"No strong route matched.\",\n\t\t\t\"Next action: create or extend a route before specialized execution.\",\n\t\t].join(\"\\n\");\n\t}\n\n\tconst primary = decision.primary;\n\tconst lines = [\n\t\t\"# Reverse Skill Route\",\n\t\t\"\",\n\t\t`Query: ${decision.query}`,\n\t\t`Platform: ${decision.platform}`,\n\t\t\"\",\n\t\t`## Primary: ${primary.route.label}`,\n\t\t`- Route ID: ${primary.route.id}`,\n\t\t`- Skill path: ${primary.route.skillPath}`,\n\t\t`- Confidence: ${primary.confidence}`,\n\t\t`- Score: ${primary.score}`,\n\t\t`- Matches: ${formatMatches(primary)}`,\n\t\t`- Risk: ${primary.route.risk}`,\n\t\t`- Required tools: ${primary.route.requiredTools.join(\", \") || \"none\"}`,\n\t\t`- Optional tools: ${primary.route.optionalTools.join(\", \") || \"none\"}`,\n\t\t`- Skill hints: ${primary.route.skillHints.join(\", \")}`,\n\t\t`- MCP hints: ${primary.route.mcpHints.join(\", \")}`,\n\t\t`- Hooks: ${primary.route.hookHints.join(\", \")}`,\n\t\t\"\",\n\t\t\"## First actions\",\n\t\t...primary.route.firstActions.map((action, index) => `${index + 1}. ${action}`),\n\t\t\"\",\n\t\t\"## Acceptance\",\n\t\t...primary.route.acceptance.map((item) => `- ${item}`),\n\t];\n\n\tif (decision.alternatives.length > 0) {\n\t\tlines.push(\"\", \"## Alternatives\");\n\t\tfor (const alternative of decision.alternatives) {\n\t\t\tlines.push(`- ${alternative.route.id} (${alternative.confidence}): ${formatMatches(alternative)}`);\n\t\t}\n\t}\n\n\tlines.push(\"\", `Next action: ${decision.nextAction}`);\n\treturn lines.join(\"\\n\");\n}\n\nexport function planReverseSkillToolChecks(decision: ReverseSkillRouteDecision, maxTools = 12): string[] {\n\tconst routes = [decision.primary, ...decision.alternatives].filter((score): score is ReverseSkillRouteScore =>\n\t\tBoolean(score),\n\t);\n\tconst tools: string[] = [];\n\tfor (const score of routes) {\n\t\ttools.push(...score.route.requiredTools, ...score.route.optionalTools);\n\t}\n\treturn unique(tools).slice(0, maxTools);\n}\n\nexport function normalizeReverseSkillName(name: string): string {\n\tconst normalized = normalizeReverseSkillText(name)\n\t\t.replace(/[^a-z0-9-]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\")\n\t\t.slice(0, 64)\n\t\t.replace(/-$/g, \"\");\n\treturn normalized || \"reverse-skill\";\n}\n\nfunction yamlString(value: string): string {\n\treturn JSON.stringify(value);\n}\n\nfunction compactDescription(input: ReverseSkillSpecInput, routes: ReverseSkillRoute[]): string {\n\tconst fallback = `Use when ${input.triggerSummary}`;\n\tconst base = input.description?.trim() || fallback;\n\tconst routeNames = routes.map((route) => route.id).join(\", \");\n\tconst suffix = routeNames ? ` Routes through ${routeNames}.` : \"\";\n\tconst description = `${base}${suffix}`;\n\treturn description.length <= 1024 ? description : `${description.slice(0, 1021).trimEnd()}...`;\n}\n\nfunction routesFromIds(routeIds: string[] | undefined): ReverseSkillRoute[] {\n\tif (!routeIds) return [];\n\treturn routeIds\n\t\t.map((routeId) => REVERSE_SKILL_ROUTES.find((route) => route.id === routeId))\n\t\t.filter((route): route is ReverseSkillRoute => Boolean(route));\n}\n\nexport function formatReverseSkillMarkdown(input: ReverseSkillSpecInput): string {\n\tconst routes = routesFromIds(input.routeIds);\n\tconst name = normalizeReverseSkillName(input.name);\n\tconst description = compactDescription(input, routes);\n\tconst workflowSteps = input.workflowSteps?.length\n\t\t? input.workflowSteps\n\t\t: [\n\t\t\t\t\"Classify target, intent, and available toolchain before execution\",\n\t\t\t\t\"Read the routed sub-skill or reference\",\n\t\t\t\t\"Collect evidence and record blockers\",\n\t\t\t\t\"Verify output against acceptance criteria\",\n\t\t\t];\n\tconst tools = unique([\n\t\t...(input.tools ?? []),\n\t\t...routes.flatMap((route) => [...route.requiredTools, ...route.optionalTools]),\n\t]);\n\tconst mcpServers = unique([...(input.mcpServers ?? []), ...routes.flatMap((route) => route.mcpHints)]);\n\tconst hooks = unique([...(input.hooks ?? []), ...routes.flatMap((route) => route.hookHints)]);\n\tconst acceptance = unique([...(input.acceptance ?? []), ...routes.flatMap((route) => route.acceptance)]);\n\tconst safetyNotes = input.safetyNotes?.length\n\t\t? input.safetyNotes\n\t\t: [\n\t\t\t\t\"Operate only on user-provided local artifacts or explicitly scoped targets\",\n\t\t\t\t\"Do not write secrets, tokens, credentials, or raw private data into skill artifacts\",\n\t\t\t];\n\n\tconst lines = [\n\t\t\"---\",\n\t\t`name: ${name}`,\n\t\t`description: ${yamlString(description)}`,\n\t\t\"---\",\n\t\t\"\",\n\t\t`# ${name}`,\n\t\t\"\",\n\t\t\"## Routing contract\",\n\t\t\"\",\n\t\t`Trigger this skill when ${input.triggerSummary}.`,\n\t\t\"\",\n\t\t\"1. Classify the target type, user intent, and toolchain signals before choosing tools.\",\n\t\t\"2. Read the narrowest referenced sub-skill or reference before running specialized tooling.\",\n\t\t\"3. Prefer passive/local evidence collection first; escalate only when the task scope requires it.\",\n\t\t\"4. Save evidence paths and blockers in the final response.\",\n\t\t\"\",\n\t\t\"## Workflow\",\n\t\t\"\",\n\t\t...workflowSteps.map((step, index) => `${index + 1}. ${step}`),\n\t\t\"\",\n\t\t\"## Tool selection\",\n\t\t\"\",\n\t\t`- Tools: ${tools.join(\", \") || \"none required\"}`,\n\t\t`- MCP: ${mcpServers.join(\", \") || \"filesystem/read-only\"}`,\n\t\t`- Hooks: ${hooks.join(\", \") || \"pre-shell-guard, protect-secrets\"}`,\n\t\t\"\",\n\t\t\"## Acceptance\",\n\t\t\"\",\n\t\t...(acceptance.length > 0\n\t\t\t? acceptance.map((item) => `- ${item}`)\n\t\t\t: [\"- Output includes routed skill, evidence, commands, and remaining blockers\"]),\n\t\t\"\",\n\t\t\"## Safety constraints\",\n\t\t\"\",\n\t\t...safetyNotes.map((note) => `- ${note}`),\n\t];\n\n\tif (routes.length > 0) {\n\t\tlines.push(\"\", \"## Built-in routes\", \"\");\n\t\tfor (const route of routes) {\n\t\t\tlines.push(`- ${route.id}: ${route.skillPath}`);\n\t\t}\n\t}\n\n\tif (input.references?.length) {\n\t\tlines.push(\"\", \"## References\", \"\");\n\t\tfor (const reference of input.references) lines.push(`- ${reference}`);\n\t}\n\n\treturn `${lines.join(\"\\n\").trimEnd()}\\n`;\n}\n\nexport function extractReverseSkillFactsFromMarkdown(sourceText: string): ReverseSkillSourceFacts {\n\tconst headings = unique(\n\t\tArray.from(sourceText.matchAll(/^#{1,4}\\s+(.+)$/gm)).map((match) => match[1]?.trim() ?? \"\"),\n\t).slice(0, 24);\n\tconst skillPaths = unique(\n\t\tArray.from(sourceText.matchAll(/[`(\\s]([^`\\s)]+SKILL\\.md)/g)).map((match) => match[1] ?? \"\"),\n\t);\n\tconst scriptPaths = unique(\n\t\tArray.from(sourceText.matchAll(/[`(\\s]([^`\\s)]+\\.(?:ps1|sh|py|js|ts))/g)).map((match) => match[1] ?? \"\"),\n\t);\n\tconst knownTools = Object.keys(TOOL_ALIASES);\n\tconst normalizedSource = normalizeReverseSkillText(sourceText);\n\tconst tools = knownTools.filter((tool) => normalizedSource.includes(normalizeReverseSkillText(tool)));\n\tconst mcpServers = unique(\n\t\tArray.from(sourceText.matchAll(/\\b([a-z0-9-]+)\\s+MCP\\b/gi)).map((match) => match[1]?.toLowerCase() ?? \"\"),\n\t);\n\tconst triggerTerms = unique(\n\t\tREVERSE_SKILL_ROUTES.flatMap((route) => [\n\t\t\t...route.targetPatterns,\n\t\t\t...route.intentPatterns,\n\t\t\t...route.toolPatterns,\n\t\t]).filter((term) => normalizedSource.includes(normalizeReverseSkillText(term))),\n\t).slice(0, 40);\n\n\treturn { headings, skillPaths, scriptPaths, tools, mcpServers, triggerTerms };\n}\n\nexport function formatReverseSkillFromSource(input: ReverseSkillSourceInput): string {\n\tconst facts = extractReverseSkillFactsFromMarkdown(input.sourceText);\n\tconst query = [input.triggerSummary, facts.triggerTerms.slice(0, 12).join(\" \"), facts.headings.slice(0, 8).join(\" \")]\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n\tconst decision = routeReverseSkill({ query: query || input.sourceText.slice(0, 500) });\n\tconst routeIds = [decision.primary?.route.id, ...decision.alternatives.map((item) => item.route.id)].filter(\n\t\t(routeId): routeId is string => Boolean(routeId),\n\t);\n\tconst name = input.name ?? (decision.primary ? `${decision.primary.route.id}-workflow` : \"reverse-skill-workflow\");\n\tconst triggerSummary =\n\t\tinput.triggerSummary ??\n\t\t(facts.triggerTerms.slice(0, 8).join(\", \") || \"reverse-engineering or security routing is needed\");\n\tconst workflowSteps = [\n\t\t\"Classify the incoming request against target, intent, and toolchain signals\",\n\t\t\"Load the routed sub-skill before running specialized tooling\",\n\t\t\"Check local tool availability only for tools required by the selected route\",\n\t\t\"Return evidence paths, commands, confidence, and blockers\",\n\t];\n\n\treturn formatReverseSkillMarkdown({\n\t\tname,\n\t\tdescription: input.description,\n\t\ttriggerSummary,\n\t\trouteIds,\n\t\tworkflowSteps,\n\t\ttools: facts.tools,\n\t\tmcpServers: facts.mcpServers,\n\t\treferences: unique([...facts.skillPaths, ...facts.scriptPaths]).slice(0, 20),\n\t});\n}\n"]}
|