@fgv/ts-extras 5.1.0-34 → 5.1.0-35

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.
Files changed (69) hide show
  1. package/dist/packlets/ai-assist/apiClient.js +54 -108
  2. package/dist/packlets/ai-assist/apiClient.js.map +1 -1
  3. package/dist/packlets/ai-assist/chatRequestBuilders.js +55 -42
  4. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -1
  5. package/dist/packlets/ai-assist/embeddingClient.js +346 -0
  6. package/dist/packlets/ai-assist/embeddingClient.js.map +1 -0
  7. package/dist/packlets/ai-assist/http.js +75 -0
  8. package/dist/packlets/ai-assist/http.js.map +1 -0
  9. package/dist/packlets/ai-assist/index.js +3 -2
  10. package/dist/packlets/ai-assist/index.js.map +1 -1
  11. package/dist/packlets/ai-assist/jsonCompletion.js +6 -8
  12. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -1
  13. package/dist/packlets/ai-assist/model.js +36 -1
  14. package/dist/packlets/ai-assist/model.js.map +1 -1
  15. package/dist/packlets/ai-assist/registry.js +77 -7
  16. package/dist/packlets/ai-assist/registry.js.map +1 -1
  17. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +22 -5
  18. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -1
  19. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -1
  20. package/dist/packlets/ai-assist/streamingAdapters/proxy.js +15 -8
  21. package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -1
  22. package/dist/packlets/ai-assist/streamingClient.js +11 -5
  23. package/dist/packlets/ai-assist/streamingClient.js.map +1 -1
  24. package/dist/ts-extras.d.ts +349 -51
  25. package/lib/packlets/ai-assist/apiClient.d.ts +24 -34
  26. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -1
  27. package/lib/packlets/ai-assist/apiClient.js +64 -118
  28. package/lib/packlets/ai-assist/apiClient.js.map +1 -1
  29. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +56 -20
  30. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -1
  31. package/lib/packlets/ai-assist/chatRequestBuilders.js +55 -40
  32. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -1
  33. package/lib/packlets/ai-assist/embeddingClient.d.ts +69 -0
  34. package/lib/packlets/ai-assist/embeddingClient.d.ts.map +1 -0
  35. package/lib/packlets/ai-assist/embeddingClient.js +350 -0
  36. package/lib/packlets/ai-assist/embeddingClient.js.map +1 -0
  37. package/lib/packlets/ai-assist/http.d.ts +24 -0
  38. package/lib/packlets/ai-assist/http.d.ts.map +1 -0
  39. package/lib/packlets/ai-assist/http.js +78 -0
  40. package/lib/packlets/ai-assist/http.js.map +1 -0
  41. package/lib/packlets/ai-assist/index.d.ts +3 -2
  42. package/lib/packlets/ai-assist/index.d.ts.map +1 -1
  43. package/lib/packlets/ai-assist/index.js +7 -1
  44. package/lib/packlets/ai-assist/index.js.map +1 -1
  45. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -1
  46. package/lib/packlets/ai-assist/jsonCompletion.js +6 -8
  47. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -1
  48. package/lib/packlets/ai-assist/model.d.ts +194 -2
  49. package/lib/packlets/ai-assist/model.d.ts.map +1 -1
  50. package/lib/packlets/ai-assist/model.js +37 -2
  51. package/lib/packlets/ai-assist/model.js.map +1 -1
  52. package/lib/packlets/ai-assist/registry.d.ts +23 -1
  53. package/lib/packlets/ai-assist/registry.d.ts.map +1 -1
  54. package/lib/packlets/ai-assist/registry.js +79 -7
  55. package/lib/packlets/ai-assist/registry.js.map +1 -1
  56. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts +21 -7
  57. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts.map +1 -1
  58. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +22 -5
  59. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -1
  60. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +8 -11
  61. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -1
  62. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -1
  63. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -1
  64. package/lib/packlets/ai-assist/streamingAdapters/proxy.js +14 -7
  65. package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -1
  66. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -1
  67. package/lib/packlets/ai-assist/streamingClient.js +11 -5
  68. package/lib/packlets/ai-assist/streamingClient.js.map +1 -1
  69. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/registry.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAmRZ,wDAEC;AAQD,sDAMC;AAUD,0DAEC;AAgBD,wDAUC;AAvUD;;;GAGG;AAEH,4CAAsD;AAStD,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,iBAAiB,GAAyC;IAC9D;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,aAAa;KAC5B;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,WAAW;QACtB,OAAO,EAAE,8BAA8B;QACvC,YAAY,EAAE,4BAA4B;QAC1C,cAAc,EAAE,CAAC,YAAY,CAAC;QAC9B,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,UAAU;KACzB;IACD;QACE,EAAE,EAAE,eAAe;QACnB,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,kDAAkD;QAC3D,YAAY,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,wBAAwB,EAAE;QAC3E,cAAc,EAAE,CAAC,YAAY,CAAC;QAC9B,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,UAAU;QACxB,eAAe,EAAE;YACf;gBACE,8BAA8B;gBAC9B,WAAW,EAAE,mBAAmB;gBAChC,MAAM,EAAE,eAAe;gBACvB,0BAA0B,EAAE,KAAK;gBACjC,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,CAAC;gBACX,gBAAgB,EAAE,MAAM;gBACxB,qBAAqB,EAAE,WAAW;aACnC;YACD;gBACE,0CAA0C;gBAC1C,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,eAAe;gBACvB,0BAA0B,EAAE,KAAK;gBACjC,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,CAAC;gBACX,gBAAgB,EAAE,MAAM;gBACxB,qBAAqB,EAAE,WAAW;aACnC;YACD;gBACE,iDAAiD;gBACjD,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,kBAAkB;gBAC1B,0BAA0B,EAAE,IAAI;gBAChC,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,CAAC;gBACX,gBAAgB,EAAE,MAAM;gBACxB,qBAAqB,EAAE,YAAY;aACpC;SACF;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,MAAM;QACb,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,gCAAgC;QACzC,YAAY,EAAE,yBAAyB;QACvC,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,aAAa;KAC5B;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,qBAAqB;QAClC,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,2BAA2B;QACpC,YAAY,EAAE,sBAAsB;QACpC,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,aAAa;KAC5B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,2BAA2B;QACpC,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,aAAa;KAC5B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,2BAA2B;QACpC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE;QACnD,cAAc,EAAE,CAAC,YAAY,CAAC;QAC9B,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,UAAU;QACxB,eAAe,EAAE;YACf;gBACE,WAAW,EAAE,YAAY;gBACzB,MAAM,EAAE,eAAe;gBACvB,0BAA0B,EAAE,IAAI;gBAChC,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC;gBAC9D,oBAAoB,EAAE,IAAI;gBAC1B,iBAAiB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;gBACpD,QAAQ,EAAE,EAAE;gBACZ,gBAAgB,EAAE,eAAe;gBACjC,qBAAqB,EAAE,WAAW;aACnC;YACD;gBACE,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,eAAe;gBACvB,0BAA0B,EAAE,KAAK;gBACjC,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC;gBACtD,oBAAoB,EAAE,IAAI;gBAC1B,iBAAiB,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC;gBACrC,QAAQ,EAAE,CAAC;gBACX,gBAAgB,EAAE,iBAAiB;gBACnC,qBAAqB,EAAE,WAAW;aACnC;YACD;gBACE,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,eAAe;gBACvB,0BAA0B,EAAE,KAAK;gBACjC,aAAa,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC;gBAClD,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,EAAE;gBACZ,gBAAgB,EAAE,iBAAiB;gBACnC,qBAAqB,EAAE,WAAW;aACnC;YACD;gBACE,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,eAAe;gBACvB,gBAAgB,EAAE,iBAAiB;gBACnC,qBAAqB,EAAE,WAAW;aACnC;SACF;KACF;IACD;QACE,EAAE,EAAE,eAAe;QACnB,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,2BAA2B;QACxC,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,KAAK;QACrB,uBAAuB,EAAE,KAAK;QAC9B,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,aAAa;KAC5B;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,qBAAqB;QAC9B,YAAY,EAAE;YACZ,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,4BAA4B;SACpC;QACD,cAAc,EAAE,CAAC,YAAY,CAAC;QAC9B,cAAc,EAAE,IAAI;QACpB,uBAAuB,EAAE,IAAI;QAC7B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,UAAU;QACxB,eAAe,EAAE;YACf;gBACE,oFAAoF;gBACpF,WAAW,EAAE,eAAe;gBAC5B,MAAM,EAAE,kBAAkB;gBAC1B,0BAA0B,EAAE,IAAI;gBAChC,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,EAAE;gBACZ,gBAAgB,EAAE,iBAAiB;gBACnC,qBAAqB,EAAE,YAAY;aACpC;YACD;gBACE,uCAAuC;gBACvC,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,YAAY;gBACpB,0BAA0B,EAAE,KAAK;gBACjC,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,EAAE;gBACZ,gBAAgB,EAAE,iBAAiB;gBACnC,qBAAqB,EAAE,YAAY;aACpC;SACF;KACF;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,cAAc,GAA+C,IAAI,GAAG,CACxE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;AAEF,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;GAGG;AACU,QAAA,cAAc,GAAgC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE9F;;;;GAIG;AACH,SAAgB,sBAAsB;IACpC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,EAAU;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAA,eAAI,EAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAA,kBAAO,EAAC,UAAU,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,UAAiC;;IACvE,OAAO,CAAC,MAAA,MAAA,UAAU,CAAC,eAAe,0CAAE,MAAM,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,sBAAsB,CACpC,UAAiC,EACjC,OAAe;;IAEf,OAAO,CAAC,MAAA,UAAU,CAAC,eAAe,mCAAI,EAAE,CAAC;SACtC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;SACpD,MAAM,CACL,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EACvF,SAAS,CACV,CAAC;AACN,CAAC;AAED,+EAA+E;AAC/E,kCAAkC;AAClC,+EAA+E;AAE/E;;;;;;;GAOG;AACU,QAAA,+BAA+B,GAA6B;IACvE,WAAW,EAAE;QACX,MAAM,EAAE;YACN,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,kBAAkB,CAAC,EAAE;YAC5D,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,kBAAkB,CAAC,EAAE;YAC/D,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE;YAC9E,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE;YAClE,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE;YAClD,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;SACnE;QACD,UAAU,EAAE;YACV,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,kBAAkB,CAAC,EAAE;YAC3D,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;YACxE,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;YACtE,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE;YACnE,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;YAC1E,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YACzD,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;SAC3D;QACD,eAAe,EAAE;YACf,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,kBAAkB,CAAC,EAAE;YAC5D,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAC,kBAAkB,CAAC,EAAE;YACrE,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE;YACpF,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE;SACrE;QACD,SAAS,EAAE;YACT,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE;YACtF,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE;YACxF,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE;SACrE;QACD,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;KACtD;CACF,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Centralized provider registry — single source of truth for all AI provider metadata.\n * @packageDocumentation\n */\n\nimport { fail, Result, succeed } from '@fgv/ts-utils';\n\nimport {\n type AiProviderId,\n type IAiImageModelCapability,\n type IAiModelCapabilityConfig,\n type IAiProviderDescriptor\n} from './model';\n\n// ============================================================================\n// Built-in providers\n// ============================================================================\n\n/**\n * All known AI provider descriptors. Copy-paste first, then alphabetical.\n * @internal\n */\nconst BUILTIN_PROVIDERS: ReadonlyArray<IAiProviderDescriptor> = [\n {\n id: 'copy-paste',\n label: 'Copy / Paste',\n buttonLabel: 'AI Assist | Copy',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: '',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'anthropic',\n label: 'Anthropic Claude',\n buttonLabel: 'AI Assist | Claude',\n needsSecret: true,\n apiFormat: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n defaultModel: 'claude-sonnet-4-5-20250929',\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional'\n },\n {\n id: 'google-gemini',\n label: 'Google Gemini',\n buttonLabel: 'AI Assist | Gemini',\n needsSecret: true,\n apiFormat: 'gemini',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n defaultModel: { base: 'gemini-2.5-flash', image: 'gemini-2.5-flash-image' },\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n imageGeneration: [\n {\n // Imagen 4 Ultra: max 1 image\n modelPrefix: 'imagen-4.0-ultra-',\n format: 'gemini-imagen',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 1,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/png'\n },\n {\n // All other Imagen 4 models: max 4 images\n modelPrefix: 'imagen-',\n format: 'gemini-imagen',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 4,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/png'\n },\n {\n // Gemini Flash Image: chat-style generateContent\n modelPrefix: '',\n format: 'gemini-image-out',\n acceptsImageReferenceInput: true,\n supportsQualityParam: false,\n maxCount: 1,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/jpeg'\n }\n ]\n },\n {\n id: 'groq',\n label: 'Groq',\n buttonLabel: 'AI Assist | Groq',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.groq.com/openai/v1',\n defaultModel: 'llama-3.3-70b-versatile',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'mistral',\n label: 'Mistral',\n buttonLabel: 'AI Assist | Mistral',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.mistral.ai/v1',\n defaultModel: 'mistral-large-latest',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'ollama',\n label: 'Ollama (self-hosted)',\n buttonLabel: 'AI Assist | Ollama',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: 'http://localhost:11434/v1',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'openai',\n label: 'OpenAI',\n buttonLabel: 'AI Assist | OpenAI',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n defaultModel: { base: 'gpt-4o', image: 'dall-e-3' },\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n imageGeneration: [\n {\n modelPrefix: 'gpt-image-',\n format: 'openai-images',\n acceptsImageReferenceInput: true,\n acceptedSizes: ['1024x1024', '1536x1024', '1024x1536', 'auto'],\n supportsQualityParam: true,\n acceptedQualities: ['low', 'medium', 'high', 'auto'],\n maxCount: 10,\n outputParamStyle: 'output-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: 'dall-e-3',\n format: 'openai-images',\n acceptsImageReferenceInput: false,\n acceptedSizes: ['1024x1024', '1792x1024', '1024x1792'],\n supportsQualityParam: true,\n acceptedQualities: ['standard', 'hd'],\n maxCount: 1,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: 'dall-e-2',\n format: 'openai-images',\n acceptsImageReferenceInput: false,\n acceptedSizes: ['256x256', '512x512', '1024x1024'],\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: '',\n format: 'openai-images',\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n }\n ]\n },\n {\n id: 'openai-compat',\n label: 'OpenAI-compatible (self-hosted)',\n buttonLabel: 'AI Assist | OpenAI-compat',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: '',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'xai-grok',\n label: 'xAI Grok',\n buttonLabel: 'AI Assist | Grok',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.x.ai/v1',\n defaultModel: {\n base: 'grok-4.3',\n tools: 'grok-4.3',\n thinking: 'grok-4.3',\n image: 'grok-imagine-image-quality'\n },\n supportedTools: ['web_search'],\n corsRestricted: true,\n streamingCorsRestricted: true,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n imageGeneration: [\n {\n // grok-imagine models use JSON edits with image_url objects (different wire format)\n modelPrefix: 'grok-imagine-',\n format: 'xai-images-edits',\n acceptsImageReferenceInput: true,\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/jpeg'\n },\n {\n // catch-all for other xai image models\n modelPrefix: '',\n format: 'xai-images',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/jpeg'\n }\n ]\n }\n];\n\n/**\n * Index for O(1) lookup by id.\n * @internal\n */\nconst PROVIDER_BY_ID: ReadonlyMap<string, IAiProviderDescriptor> = new Map(\n BUILTIN_PROVIDERS.map((d) => [d.id, d])\n);\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * All valid provider ID values, in the same order as the registry.\n * @public\n */\nexport const allProviderIds: ReadonlyArray<AiProviderId> = BUILTIN_PROVIDERS.map((d) => d.id);\n\n/**\n * Get all known provider descriptors. Copy-paste first, then alphabetical.\n * @returns All built-in provider descriptors\n * @public\n */\nexport function getProviderDescriptors(): ReadonlyArray<IAiProviderDescriptor> {\n return BUILTIN_PROVIDERS;\n}\n\n/**\n * Get a provider descriptor by id.\n * @param id - The provider identifier\n * @returns The descriptor, or a failure if the provider is unknown\n * @public\n */\nexport function getProviderDescriptor(id: string): Result<IAiProviderDescriptor> {\n const descriptor = PROVIDER_BY_ID.get(id);\n if (!descriptor) {\n return fail(`unknown AI provider: ${id}`);\n }\n return succeed(descriptor);\n}\n\n/**\n * Whether a provider declares any image-generation capability at all.\n *\n * @param descriptor - The provider descriptor\n * @returns `true` when {@link IAiProviderDescriptor.imageGeneration} has at\n * least one entry; `false` otherwise.\n * @public\n */\nexport function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean {\n return (descriptor.imageGeneration?.length ?? 0) > 0;\n}\n\n/**\n * Resolve the image-generation capability that applies to a given model id\n * for a provider. Returns the entry from\n * {@link IAiProviderDescriptor.imageGeneration} whose `modelPrefix` is the\n * longest prefix of `modelId`. Ties are broken by first-encountered, so rule\n * order does not matter for correctness — only for tie-breaking among rules\n * with identical-length prefixes (an unusual case).\n *\n * @param descriptor - The provider descriptor\n * @param modelId - The resolved image model id\n * @returns The matching capability, or `undefined` when no rule matches or\n * the provider declares no image-generation capabilities.\n * @public\n */\nexport function resolveImageCapability(\n descriptor: IAiProviderDescriptor,\n modelId: string\n): IAiImageModelCapability | undefined {\n return (descriptor.imageGeneration ?? [])\n .filter((cap) => modelId.startsWith(cap.modelPrefix))\n .reduce<IAiImageModelCapability | undefined>(\n (best, cap) => (best && best.modelPrefix.length >= cap.modelPrefix.length ? best : cap),\n undefined\n );\n}\n\n// ============================================================================\n// Default model capability config\n// ============================================================================\n\n/**\n * Default capability config used by `callProviderListModels` when callers\n * don't supply their own. Patterns are intentionally narrow — false\n * positives are worse than missing a model. Caller can override per call\n * via {@link IProviderListModelsParams.capabilityConfig}.\n *\n * @public\n */\nexport const DEFAULT_MODEL_CAPABILITY_CONFIG: IAiModelCapabilityConfig = {\n perProvider: {\n openai: [\n { idPattern: /^dall-e/, capabilities: ['image-generation'] },\n { idPattern: /^gpt-image/, capabilities: ['image-generation'] },\n { idPattern: /^gpt-5/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^gpt-4/, capabilities: ['chat', 'tools', 'vision'] },\n { idPattern: /^gpt-3\\.5/, capabilities: ['chat'] },\n { idPattern: /^o\\d/, capabilities: ['chat', 'tools', 'thinking'] }\n ],\n 'xai-grok': [\n { idPattern: /-image/, capabilities: ['image-generation'] },\n { idPattern: /^grok-4\\.3/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-4$/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-4/, capabilities: ['chat', 'tools', 'vision'] },\n { idPattern: /^grok-3-mini/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-3/, capabilities: ['chat', 'tools'] },\n { idPattern: /^grok-2/, capabilities: ['chat', 'vision'] }\n ],\n 'google-gemini': [\n { idPattern: /^imagen/, capabilities: ['image-generation'] },\n { idPattern: /^gemini-.*-image/, capabilities: ['image-generation'] },\n { idPattern: /^gemini-2\\.5/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^gemini-/, capabilities: ['chat', 'tools', 'vision'] }\n ],\n anthropic: [\n { idPattern: /^claude-opus-4/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^claude-sonnet-4/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^claude-/, capabilities: ['chat', 'tools', 'vision'] }\n ],\n groq: [{ idPattern: /./, capabilities: ['chat'] }],\n mistral: [{ idPattern: /./, capabilities: ['chat'] }]\n }\n};\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/registry.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Centralized provider registry — single source of truth for all AI provider metadata.\n * @packageDocumentation\n */\n\nimport { fail, Result, succeed } from '@fgv/ts-utils';\n\nimport {\n type AiProviderId,\n type IAiEmbeddingModelCapability,\n type IAiImageModelCapability,\n type IAiModelCapabilityConfig,\n type IAiProviderDescriptor\n} from './model';\n\n// ============================================================================\n// Built-in providers\n// ============================================================================\n\n/**\n * All known AI provider descriptors. Copy-paste first, then alphabetical.\n * @internal\n */\nconst BUILTIN_PROVIDERS: ReadonlyArray<IAiProviderDescriptor> = [\n {\n id: 'copy-paste',\n label: 'Copy / Paste',\n buttonLabel: 'AI Assist | Copy',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: '',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'anthropic',\n label: 'Anthropic Claude',\n buttonLabel: 'AI Assist | Claude',\n needsSecret: true,\n apiFormat: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n defaultModel: 'claude-sonnet-4-5-20250929',\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional'\n },\n {\n id: 'google-gemini',\n label: 'Google Gemini',\n buttonLabel: 'AI Assist | Gemini',\n needsSecret: true,\n apiFormat: 'gemini',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n defaultModel: {\n base: 'gemini-2.5-flash',\n image: 'gemini-2.5-flash-image',\n embedding: 'gemini-embedding-001'\n },\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n embedding: [\n {\n modelPrefix: '',\n format: 'gemini-embeddings',\n supportsDimensions: true,\n supportsTaskType: true,\n defaultDimensions: 3072\n }\n ],\n imageGeneration: [\n {\n // Imagen 4 Ultra: max 1 image\n modelPrefix: 'imagen-4.0-ultra-',\n format: 'gemini-imagen',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 1,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/png'\n },\n {\n // All other Imagen 4 models: max 4 images\n modelPrefix: 'imagen-',\n format: 'gemini-imagen',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 4,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/png'\n },\n {\n // Gemini Flash Image: chat-style generateContent\n modelPrefix: '',\n format: 'gemini-image-out',\n acceptsImageReferenceInput: true,\n supportsQualityParam: false,\n maxCount: 1,\n outputParamStyle: 'none',\n defaultOutputMimeType: 'image/jpeg'\n }\n ]\n },\n {\n id: 'groq',\n label: 'Groq',\n buttonLabel: 'AI Assist | Groq',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.groq.com/openai/v1',\n defaultModel: 'llama-3.3-70b-versatile',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported'\n },\n {\n id: 'mistral',\n label: 'Mistral',\n buttonLabel: 'AI Assist | Mistral',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.mistral.ai/v1',\n defaultModel: { base: 'mistral-large-latest', embedding: 'mistral-embed' },\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported',\n embedding: [{ modelPrefix: '', format: 'openai-embeddings' }]\n },\n {\n id: 'ollama',\n label: 'Ollama (self-hosted)',\n buttonLabel: 'AI Assist | Ollama',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: 'http://localhost:11434/v1',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported',\n embedding: [{ modelPrefix: '', format: 'openai-embeddings' }]\n },\n {\n id: 'openai',\n label: 'OpenAI',\n buttonLabel: 'AI Assist | OpenAI',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n defaultModel: { base: 'gpt-4o', image: 'dall-e-3', embedding: 'text-embedding-3-small' },\n supportedTools: ['web_search'],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n embedding: [\n {\n modelPrefix: 'text-embedding-3',\n format: 'openai-embeddings',\n supportsDimensions: true,\n maxBatchSize: 2048\n },\n {\n modelPrefix: '',\n format: 'openai-embeddings'\n }\n ],\n imageGeneration: [\n {\n modelPrefix: 'gpt-image-',\n format: 'openai-images',\n acceptsImageReferenceInput: true,\n acceptedSizes: ['1024x1024', '1536x1024', '1024x1536', 'auto'],\n supportsQualityParam: true,\n acceptedQualities: ['low', 'medium', 'high', 'auto'],\n maxCount: 10,\n outputParamStyle: 'output-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: 'dall-e-3',\n format: 'openai-images',\n acceptsImageReferenceInput: false,\n acceptedSizes: ['1024x1024', '1792x1024', '1024x1792'],\n supportsQualityParam: true,\n acceptedQualities: ['standard', 'hd'],\n maxCount: 1,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: 'dall-e-2',\n format: 'openai-images',\n acceptsImageReferenceInput: false,\n acceptedSizes: ['256x256', '512x512', '1024x1024'],\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n },\n {\n modelPrefix: '',\n format: 'openai-images',\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/png'\n }\n ]\n },\n {\n id: 'openai-compat',\n label: 'OpenAI-compatible (self-hosted)',\n buttonLabel: 'AI Assist | OpenAI-compat',\n needsSecret: false,\n apiFormat: 'openai',\n baseUrl: '',\n defaultModel: '',\n supportedTools: [],\n corsRestricted: false,\n streamingCorsRestricted: false,\n acceptsImageInput: false,\n thinkingMode: 'unsupported',\n embedding: [{ modelPrefix: '', format: 'openai-embeddings' }]\n },\n {\n id: 'xai-grok',\n label: 'xAI Grok',\n buttonLabel: 'AI Assist | Grok',\n needsSecret: true,\n apiFormat: 'openai',\n baseUrl: 'https://api.x.ai/v1',\n defaultModel: {\n base: 'grok-4.3',\n tools: 'grok-4.3',\n thinking: 'grok-4.3',\n image: 'grok-imagine-image-quality'\n },\n supportedTools: ['web_search'],\n corsRestricted: true,\n streamingCorsRestricted: true,\n acceptsImageInput: true,\n thinkingMode: 'optional',\n imageGeneration: [\n {\n // grok-imagine models use JSON edits with image_url objects (different wire format)\n modelPrefix: 'grok-imagine-',\n format: 'xai-images-edits',\n acceptsImageReferenceInput: true,\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/jpeg'\n },\n {\n // catch-all for other xai image models\n modelPrefix: '',\n format: 'xai-images',\n acceptsImageReferenceInput: false,\n supportsQualityParam: false,\n maxCount: 10,\n outputParamStyle: 'response-format',\n defaultOutputMimeType: 'image/jpeg'\n }\n ]\n }\n];\n\n/**\n * Index for O(1) lookup by id.\n * @internal\n */\nconst PROVIDER_BY_ID: ReadonlyMap<string, IAiProviderDescriptor> = new Map(\n BUILTIN_PROVIDERS.map((d) => [d.id, d])\n);\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * All valid provider ID values, in the same order as the registry.\n * @public\n */\nexport const allProviderIds: ReadonlyArray<AiProviderId> = BUILTIN_PROVIDERS.map((d) => d.id);\n\n/**\n * Get all known provider descriptors. Copy-paste first, then alphabetical.\n * @returns All built-in provider descriptors\n * @public\n */\nexport function getProviderDescriptors(): ReadonlyArray<IAiProviderDescriptor> {\n return BUILTIN_PROVIDERS;\n}\n\n/**\n * Get a provider descriptor by id.\n * @param id - The provider identifier\n * @returns The descriptor, or a failure if the provider is unknown\n * @public\n */\nexport function getProviderDescriptor(id: string): Result<IAiProviderDescriptor> {\n const descriptor = PROVIDER_BY_ID.get(id);\n if (!descriptor) {\n return fail(`unknown AI provider: ${id}`);\n }\n return succeed(descriptor);\n}\n\n/**\n * Whether a provider declares any image-generation capability at all.\n *\n * @param descriptor - The provider descriptor\n * @returns `true` when {@link IAiProviderDescriptor.imageGeneration} has at\n * least one entry; `false` otherwise.\n * @public\n */\nexport function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean {\n return (descriptor.imageGeneration?.length ?? 0) > 0;\n}\n\n/**\n * Resolve the image-generation capability that applies to a given model id\n * for a provider. Returns the entry from\n * {@link IAiProviderDescriptor.imageGeneration} whose `modelPrefix` is the\n * longest prefix of `modelId`. Ties are broken by first-encountered, so rule\n * order does not matter for correctness — only for tie-breaking among rules\n * with identical-length prefixes (an unusual case).\n *\n * @param descriptor - The provider descriptor\n * @param modelId - The resolved image model id\n * @returns The matching capability, or `undefined` when no rule matches or\n * the provider declares no image-generation capabilities.\n * @public\n */\nexport function resolveImageCapability(\n descriptor: IAiProviderDescriptor,\n modelId: string\n): IAiImageModelCapability | undefined {\n return (descriptor.imageGeneration ?? [])\n .filter((cap) => modelId.startsWith(cap.modelPrefix))\n .reduce<IAiImageModelCapability | undefined>(\n (best, cap) => (best && best.modelPrefix.length >= cap.modelPrefix.length ? best : cap),\n undefined\n );\n}\n\n/**\n * Whether a provider declares any embedding capability at all.\n *\n * @param descriptor - The provider descriptor\n * @returns `true` when {@link IAiProviderDescriptor.embedding} has at least one\n * entry; `false` otherwise.\n * @public\n */\nexport function supportsEmbedding(descriptor: IAiProviderDescriptor): boolean {\n return (descriptor.embedding?.length ?? 0) > 0;\n}\n\n/**\n * Resolve the embedding capability that applies to a given model id for a\n * provider. Returns the entry from {@link IAiProviderDescriptor.embedding} whose\n * `modelPrefix` is the longest prefix of `modelId`. Ties are broken by\n * first-encountered.\n *\n * @param descriptor - The provider descriptor\n * @param modelId - The resolved embedding model id\n * @returns The matching capability, or `undefined` when no rule matches or the\n * provider declares no embedding capabilities.\n * @public\n */\nexport function resolveEmbeddingCapability(\n descriptor: IAiProviderDescriptor,\n modelId: string\n): IAiEmbeddingModelCapability | undefined {\n return (descriptor.embedding ?? [])\n .filter((cap) => modelId.startsWith(cap.modelPrefix))\n .reduce<IAiEmbeddingModelCapability | undefined>(\n (best, cap) => (best && best.modelPrefix.length >= cap.modelPrefix.length ? best : cap),\n undefined\n );\n}\n\n// ============================================================================\n// Default model capability config\n// ============================================================================\n\n/**\n * Default capability config used by `callProviderListModels` when callers\n * don't supply their own. Patterns are intentionally narrow — false\n * positives are worse than missing a model. Caller can override per call\n * via {@link IProviderListModelsParams.capabilityConfig}.\n *\n * @public\n */\nexport const DEFAULT_MODEL_CAPABILITY_CONFIG: IAiModelCapabilityConfig = {\n perProvider: {\n openai: [\n { idPattern: /^dall-e/, capabilities: ['image-generation'] },\n { idPattern: /^gpt-image/, capabilities: ['image-generation'] },\n { idPattern: /^text-embedding/, capabilities: ['embedding'] },\n { idPattern: /^gpt-5/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^gpt-4/, capabilities: ['chat', 'tools', 'vision'] },\n { idPattern: /^gpt-3\\.5/, capabilities: ['chat'] },\n { idPattern: /^o\\d/, capabilities: ['chat', 'tools', 'thinking'] }\n ],\n 'xai-grok': [\n { idPattern: /-image/, capabilities: ['image-generation'] },\n { idPattern: /^grok-4\\.3/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-4$/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-4/, capabilities: ['chat', 'tools', 'vision'] },\n { idPattern: /^grok-3-mini/, capabilities: ['chat', 'tools', 'thinking'] },\n { idPattern: /^grok-3/, capabilities: ['chat', 'tools'] },\n { idPattern: /^grok-2/, capabilities: ['chat', 'vision'] }\n ],\n 'google-gemini': [\n { idPattern: /^imagen/, capabilities: ['image-generation'] },\n { idPattern: /^gemini-.*-image/, capabilities: ['image-generation'] },\n { idPattern: /embedding/, capabilities: ['embedding'] },\n { idPattern: /^gemini-2\\.5/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^gemini-/, capabilities: ['chat', 'tools', 'vision'] }\n ],\n anthropic: [\n { idPattern: /^claude-opus-4/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^claude-sonnet-4/, capabilities: ['chat', 'tools', 'vision', 'thinking'] },\n { idPattern: /^claude-/, capabilities: ['chat', 'tools', 'vision'] }\n ],\n groq: [{ idPattern: /./, capabilities: ['chat'] }],\n mistral: [\n { idPattern: /embed/, capabilities: ['embedding'] },\n { idPattern: /./, capabilities: ['chat'] }\n ],\n // Self-hosted OpenAI-compatible servers (Ollama, LM Studio, llama.cpp) serve\n // arbitrary, caller-chosen models whose ids we can't enumerate ahead of time.\n // The catch-all `/./` intentionally departs from the \"narrow patterns\" rule\n // above: assume `chat` for everything and let the caller override via\n // `capabilityConfig` when they know their deployment serves image/embedding models.\n ollama: [{ idPattern: /./, capabilities: ['chat'] }],\n 'openai-compat': [{ idPattern: /./, capabilities: ['chat'] }]\n }\n};\n"]}
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { type Logging, Result } from '@fgv/ts-utils';
19
19
  import { type JsonObject } from '@fgv/ts-json-base';
20
- import { type AiPrompt, type AiServerToolConfig, type IAiClientTool, type IAiClientToolContinuation, type IAiClientToolTurnResult, type IAiStreamEvent, type IChatMessage, type IAiProviderDescriptor } from '../model';
20
+ import { type AiServerToolConfig, type IAiClientTool, type IAiClientToolContinuation, type IAiClientToolTurnResult, type IAiStreamEvent, type IChatRequest, type IAiProviderDescriptor } from '../model';
21
21
  import { type IResolvedThinkingConfig } from '../thinkingOptionsResolver';
22
22
  import { type IAccumulatedBlock } from './anthropic';
23
23
  import { type IAccumulatedFunctionCall } from './openaiResponses';
@@ -72,19 +72,23 @@ export declare function buildOpenAiContinuation(calls: Map<string, IAccumulatedF
72
72
  export declare function buildGeminiContinuation(calls: IAccumulatedGeminiFunctionCall[], toolResults: IToolCallResult[]): IAiClientToolContinuation;
73
73
  /**
74
74
  * Parameters for {@link AiAssist.executeClientToolTurn}.
75
+ *
76
+ * @remarks
77
+ * Carries the unified {@link AiAssist.IChatRequest} shape (`system?` + ordered
78
+ * `messages`): the last message is the current user turn and the preceding
79
+ * messages are history, linearized before the current turn — identically to the
80
+ * completion and streaming paths. {@link IExecuteClientToolTurnParams.continuationMessages}
81
+ * remains a distinct post-current-turn axis (see below).
82
+ *
75
83
  * @public
76
84
  */
77
- export interface IExecuteClientToolTurnParams {
85
+ export interface IExecuteClientToolTurnParams extends IChatRequest {
78
86
  /** The provider descriptor for routing (Anthropic / OpenAI / Gemini). */
79
87
  readonly descriptor: IAiProviderDescriptor;
80
88
  /** API key for authentication. */
81
89
  readonly apiKey: string;
82
- /** The structured prompt. */
83
- readonly prompt: AiPrompt;
84
- /** Prior conversation history (excluding the current turn). */
85
- readonly messagesBefore?: ReadonlyArray<IChatMessage>;
86
90
  /**
87
- * Provider-specific continuation messages to append after the prompt's user
91
+ * Provider-specific continuation messages to append after the current user
88
92
  * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s
89
93
  * `messages` field from a prior turn back to the provider in the follow-up request.
90
94
  *
@@ -107,6 +111,16 @@ export interface IExecuteClientToolTurnParams {
107
111
  readonly clientTools: ReadonlyArray<IAiClientTool>;
108
112
  /** Optional abort signal. */
109
113
  readonly signal?: AbortSignal;
114
+ /**
115
+ * Optional override of the descriptor's default base URL. Same semantics as
116
+ * the non-streaming completion path and `callProviderCompletionStream`: a
117
+ * well-formed `http`/`https` URL is substituted for `descriptor.baseUrl`
118
+ * when composing the per-format request, with the per-format suffix appended
119
+ * unchanged. Validated at the dispatcher; auth shape is unaffected. Use this
120
+ * to point a client-tool turn at a local / LAN OpenAI-compatible server
121
+ * (Ollama, LM Studio, llama.cpp).
122
+ */
123
+ readonly endpoint?: string;
110
124
  /** Optional logger for diagnostics. */
111
125
  readonly logger?: Logging.ILogger;
112
126
  /** Optional resolved thinking config (pre-resolved by the caller). */
@@ -1 +1 @@
1
- {"version":3,"file":"clientToolContinuationBuilder.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clientToolContinuationBuilder.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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"}
@@ -62,6 +62,8 @@ exports.executeClientToolTurn = executeClientToolTurn;
62
62
  */
63
63
  const ts_utils_1 = require("@fgv/ts-utils");
64
64
  const model_1 = require("../model");
65
+ const chatRequestBuilders_1 = require("../chatRequestBuilders");
66
+ const endpoint_1 = require("../endpoint");
65
67
  const anthropic_1 = require("./anthropic");
66
68
  const openaiResponses_1 = require("./openaiResponses");
67
69
  const gemini_1 = require("./gemini");
@@ -283,7 +285,15 @@ function buildGeminiContinuation(calls, toolResults) {
283
285
  * @public
284
286
  */
285
287
  function executeClientToolTurn(params) {
286
- const { descriptor, apiKey, prompt, messagesBefore, continuationMessages, temperature, tools, clientTools, signal, logger, resolvedThinking, model } = params;
288
+ const { descriptor, apiKey, system, messages, continuationMessages, temperature, tools, clientTools, signal, logger, resolvedThinking, model, endpoint } = params;
289
+ const splitResult = (0, chatRequestBuilders_1.splitChatRequest)(system, messages);
290
+ if (splitResult.isFailure()) {
291
+ return (0, ts_utils_1.fail)(splitResult.message);
292
+ }
293
+ const { prompt, head } = splitResult.value;
294
+ if (prompt.attachments.length > 0 && !descriptor.acceptsImageInput) {
295
+ return (0, ts_utils_1.fail)(`provider "${descriptor.id}" does not accept image input`);
296
+ }
287
297
  // Build a lookup map of client tools by name for fast access.
288
298
  // Fail fast on duplicate names — silently overwriting would cause one tool
289
299
  // to shadow another with no observable signal.
@@ -300,8 +310,15 @@ function executeClientToolTurn(params) {
300
310
  const effectiveTools = clientTools.length > 0 ? [...(tools !== null && tools !== void 0 ? tools : []), ...clientTools.map((t) => t.config)] : tools;
301
311
  const effectiveTemperature = temperature !== null && temperature !== void 0 ? temperature : 0.7;
302
312
  const resolvedModel = model !== null && model !== void 0 ? model : (0, model_1.resolveModel)(descriptor.defaultModel);
313
+ if (resolvedModel.length === 0) {
314
+ return (0, ts_utils_1.fail)(`provider "${descriptor.id}": no model resolved; pass model or set descriptor.defaultModel`);
315
+ }
316
+ const baseUrlResult = (0, endpoint_1.resolveEffectiveBaseUrl)(descriptor, endpoint);
317
+ if (baseUrlResult.isFailure()) {
318
+ return (0, ts_utils_1.fail)(baseUrlResult.message);
319
+ }
303
320
  const config = {
304
- baseUrl: descriptor.baseUrl,
321
+ baseUrl: baseUrlResult.value,
305
322
  apiKey,
306
323
  model: resolvedModel
307
324
  };
@@ -315,13 +332,13 @@ function executeClientToolTurn(params) {
315
332
  const streamPromise = (() => {
316
333
  switch (descriptor.apiFormat) {
317
334
  case 'anthropic':
318
- return (0, anthropic_1.callAnthropicStream)(config, prompt, messagesBefore, effectiveTemperature, effectiveTools, logger, signal, resolvedThinking, anthropicBuffer, continuationMessages);
335
+ return (0, anthropic_1.callAnthropicStream)(config, prompt, head, effectiveTemperature, effectiveTools, logger, signal, resolvedThinking, anthropicBuffer, continuationMessages);
319
336
  case 'openai':
320
337
  return (0, openaiResponses_1.callOpenAiResponsesStream)(config, prompt,
321
338
  /* c8 ignore next 1 - defensive: openai path requires tools; empty array fallback unreachable in practice */
322
- effectiveTools !== null && effectiveTools !== void 0 ? effectiveTools : [], messagesBefore, effectiveTemperature, logger, signal, resolvedThinking, openAiCallMap, continuationMessages);
339
+ effectiveTools !== null && effectiveTools !== void 0 ? effectiveTools : [], head, effectiveTemperature, logger, signal, resolvedThinking, openAiCallMap, continuationMessages);
323
340
  case 'gemini':
324
- return (0, gemini_1.callGeminiStream)(config, prompt, messagesBefore, effectiveTemperature, effectiveTools, logger, signal, resolvedThinking, geminiCalls, continuationMessages);
341
+ return (0, gemini_1.callGeminiStream)(config, prompt, head, effectiveTemperature, effectiveTools, logger, signal, resolvedThinking, geminiCalls, continuationMessages);
325
342
  /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */
326
343
  default: {
327
344
  const _exhaustive = descriptor.apiFormat;
@@ -1 +1 @@
1
- {"version":3,"file":"clientToolContinuationBuilder.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Per-provider continuation message builders and the `executeClientToolTurn`\n * helper for orchestrating a single client-tool round-trip.\n *\n * Each provider requires a different wire format for the follow-up request:\n * - **Anthropic**: assistant turn reconstructed from the ordered accumulation\n * buffer (thinking / redacted_thinking / text / tool_use in original stream\n * order) + user turn with `tool_result` blocks. When thinking is active, the\n * follow-up request must NOT set `tool_choice: { type: 'any' }` or\n * `tool_choice: { type: 'tool', ... }` (E3 / §5.4 of b4-spike-findings).\n * - **OpenAI / xAI Responses API**: `function_call` input items +\n * `function_call_output` input items.\n * - **Gemini**: model turn with `functionCall` parts + user turn with\n * `functionResponse` parts (correlation by tool name).\n *\n * @packageDocumentation\n */\n\nimport { captureAsyncResult, fail, type Logging, Result, succeed } from '@fgv/ts-utils';\nimport { type JsonArray, type JsonObject } from '@fgv/ts-json-base';\n\nimport {\n type AiPrompt,\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiClientTool,\n type IAiClientToolContinuation,\n type IAiClientToolTurnResult,\n type IAiStreamEvent,\n type IChatMessage,\n type IAiProviderDescriptor,\n resolveModel\n} from '../model';\nimport { type IResolvedThinkingConfig } from '../thinkingOptionsResolver';\nimport { type IAccumulatedBlock } from './anthropic';\nimport { type IAccumulatedFunctionCall } from './openaiResponses';\nimport { type IAccumulatedGeminiFunctionCall } from './gemini';\nimport { callAnthropicStream } from './anthropic';\nimport { callOpenAiResponsesStream } from './openaiResponses';\nimport { callGeminiStream } from './gemini';\nimport { type IStreamApiConfig } from './common';\n\n// ============================================================================\n// Tool-result accumulation (internal)\n// ============================================================================\n\n/**\n * Accumulated result for a single tool call, collected during stream iteration.\n * @internal\n */\ninterface IToolCallResult {\n readonly toolName: string;\n readonly callId?: string;\n readonly args: JsonObject;\n readonly result: string;\n readonly isError: boolean;\n}\n\n// ============================================================================\n// Anthropic continuation builder\n// ============================================================================\n\n/**\n * Builds the Anthropic follow-up messages for a client-tool round-trip.\n *\n * Reconstructs the assistant turn from the ordered accumulation buffer\n * (all block types in original stream order) and appends a user turn\n * with `tool_result` blocks for each executed tool call.\n *\n * **Constraint (E3):** The returned continuation does NOT include a forced\n * `tool_choice` field. When thinking is active, Anthropic rejects\n * `tool_choice: { type: 'any' }` and `tool_choice: { type: 'tool', ... }`\n * with an HTTP 400 error. Only `tool_choice: { type: 'auto' }` (the default,\n * i.e. omitted) is compatible with extended thinking.\n *\n * @internal\n */\nexport function buildAnthropicContinuation(\n accBuffer: Map<number, IAccumulatedBlock>,\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n // Reconstruct the assistant turn from the ordered accumulation buffer.\n // Sort by buffer key (SSE index) to restore original stream order.\n const sortedKeys = Array.from(accBuffer.keys()).sort((a, b) => a - b);\n const assistantContent: JsonArray = [];\n\n for (const key of sortedKeys) {\n const block = accBuffer.get(key);\n /* c8 ignore next 1 - defensive: key always exists in map since we iterate its keys */\n if (!block) continue;\n if (block.type === 'thinking') {\n assistantContent.push({\n type: 'thinking',\n thinking: block.thinking,\n signature: block.signature\n });\n } else if (block.type === 'redacted_thinking') {\n assistantContent.push({\n type: 'redacted_thinking',\n data: block.data\n });\n } else if (block.type === 'text') {\n if (block.text.length > 0) {\n assistantContent.push({ type: 'text', text: block.text });\n }\n } else if (block.type === 'tool_use') {\n let parsedInput: JsonObject;\n try {\n /* c8 ignore next 1 - defensive: argsBuffer is JSON-parsed in the adapter before emitting client-tool-call-done */\n parsedInput = JSON.parse(block.argsBuffer || '{}') as JsonObject;\n /* c8 ignore start - defensive: malformed argsBuffer defaults to empty object */\n } catch {\n parsedInput = {};\n }\n /* c8 ignore stop */\n assistantContent.push({\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: parsedInput\n });\n }\n }\n\n // Build user turn with tool_result blocks for each tool call.\n const userContent: JsonArray = toolResults.map((r): JsonObject => {\n const block: JsonObject = {\n type: 'tool_result',\n // eslint-disable-next-line @typescript-eslint/naming-convention\n tool_use_id: r.callId ?? r.toolName,\n content: r.result\n };\n if (r.isError) {\n return { ...block, is_error: true };\n }\n return block;\n });\n\n const assistantMessage: JsonObject = {\n role: 'assistant',\n content: assistantContent\n };\n const userMessage: JsonObject = {\n role: 'user',\n content: userContent\n };\n\n return {\n messages: [assistantMessage, userMessage],\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// OpenAI / xAI Responses API continuation builder\n// ============================================================================\n\n/**\n * Builds the OpenAI / xAI Responses API follow-up input items for a\n * client-tool round-trip.\n *\n * Emits `function_call` items (the model's call) followed by\n * `function_call_output` items (the harness execution result), one pair\n * per executed tool call.\n *\n * @internal\n */\nexport function buildOpenAiContinuation(\n calls: Map<string, IAccumulatedFunctionCall>,\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n const items: JsonObject[] = [];\n\n // Emit function_call items for each call (model's side). Per the Responses API spec\n // (ResponseFunctionToolCall), `call_id` is the required correlation field — it must\n // match the matching function_call_output's `call_id` below. The optional `id` field\n // is the output-item id (`fc_*`) used to reference the streamed item; we omit it\n // because it is not load-bearing for input items.\n for (const [callId, call] of calls) {\n items.push({\n type: 'function_call',\n call_id: callId,\n name: call.name,\n arguments: call.argsBuffer\n });\n }\n\n // Emit function_call_output items (harness execution results).\n for (const r of toolResults) {\n items.push({\n type: 'function_call_output',\n call_id: r.callId ?? r.toolName,\n output: r.result\n });\n }\n\n return {\n messages: items,\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// Gemini continuation builder\n// ============================================================================\n\n/**\n * Builds the Gemini follow-up contents for a client-tool round-trip.\n *\n * Emits a model turn with `functionCall` parts (one per tool call) and a\n * user turn with `functionResponse` parts (correlation by tool name, since\n * Gemini does not assign call IDs).\n *\n * @internal\n */\nexport function buildGeminiContinuation(\n calls: IAccumulatedGeminiFunctionCall[],\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n // Model turn: functionCall parts for each call.\n const modelParts: JsonArray = calls.map(\n (call): JsonObject => ({\n functionCall: {\n name: call.name,\n args: call.args\n }\n })\n );\n\n // User turn: functionResponse parts for each executed result.\n // Correlation is by name since Gemini has no call IDs.\n const userParts: JsonArray = toolResults.map(\n (r): JsonObject => ({\n functionResponse: {\n name: r.toolName,\n response: {\n content: r.result,\n ...(r.isError ? { error: true } : {})\n }\n }\n })\n );\n\n const modelMessage: JsonObject = {\n role: 'model',\n parts: modelParts\n };\n const userMessage: JsonObject = {\n role: 'user',\n parts: userParts\n };\n\n return {\n messages: [modelMessage, userMessage],\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// executeClientToolTurn parameters\n// ============================================================================\n\n/**\n * Parameters for {@link AiAssist.executeClientToolTurn}.\n * @public\n */\nexport interface IExecuteClientToolTurnParams {\n /** The provider descriptor for routing (Anthropic / OpenAI / Gemini). */\n readonly descriptor: IAiProviderDescriptor;\n /** API key for authentication. */\n readonly apiKey: string;\n /** The structured prompt. */\n readonly prompt: AiPrompt;\n /** Prior conversation history (excluding the current turn). */\n readonly messagesBefore?: ReadonlyArray<IChatMessage>;\n /**\n * Provider-specific continuation messages to append after the prompt's user\n * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s\n * `messages` field from a prior turn back to the provider in the follow-up request.\n *\n * Each provider applies its own shape guard to the supplied wire objects:\n * - Anthropic: projects each entry to `{ role, content }` (sufficient for\n * thinking blocks and `tool_result` arrays).\n * - OpenAI / xAI Responses: passes each item verbatim (`function_call` /\n * `function_call_output` items carry distinct fields per `type`); only guards\n * that each entry is a JSON object.\n * - Gemini: projects each entry to `{ role, parts }`.\n *\n * Entries that fail their provider's shape check are silently skipped.\n */\n readonly continuationMessages?: ReadonlyArray<JsonObject>;\n /** Temperature (default: 0.7). */\n readonly temperature?: number;\n /** Server-side tools to include. */\n readonly tools?: ReadonlyArray<AiServerToolConfig>;\n /** Client-defined tools available for the model to call. */\n readonly clientTools: ReadonlyArray<IAiClientTool>;\n /** Optional abort signal. */\n readonly signal?: AbortSignal;\n /** Optional logger for diagnostics. */\n readonly logger?: Logging.ILogger;\n /** Optional resolved thinking config (pre-resolved by the caller). */\n readonly resolvedThinking?: IResolvedThinkingConfig;\n /** Resolved model string (pre-resolved by the caller). When omitted, uses the descriptor's default model. */\n readonly model?: string;\n}\n\n/**\n * Return value of {@link AiAssist.executeClientToolTurn}.\n * @public\n */\nexport interface IExecuteClientToolTurnResult {\n /**\n * The unified-event iterable. Callers iterate this to drive the streaming UI.\n * The iterable forwards `text-delta`, `tool-event`, `client-tool-call-start`,\n * `client-tool-call-done`, and `client-tool-result` events through.\n */\n readonly events: AsyncIterable<IAiStreamEvent>;\n /**\n * Resolves when the stream terminates. On success, carries the\n * {@link AiAssist.IAiClientToolTurnResult} with the optional continuation for the\n * next round. On failure, carries the error message.\n */\n readonly nextTurn: Promise<Result<IAiClientToolTurnResult>>;\n}\n\n// ============================================================================\n// executeClientToolTurn\n// ============================================================================\n\n/**\n * Orchestrates a single client-tool streaming turn for any supported provider.\n *\n * Starts a streaming request, iterates the underlying provider stream, and:\n * - Forwards `text-delta`, `tool-event`, `client-tool-call-start`, and\n * `client-tool-call-done` events through to the consumer.\n * - For each `client-tool-call-done` event: validates the raw args against the\n * tool's `parametersSchema`, invokes `execute(typedArgs)`, and emits a\n * `client-tool-result` event.\n * - After stream completion: builds the per-provider continuation (or\n * `{ continuation: undefined }` when no tool calls occurred) and resolves\n * `nextTurn`.\n *\n * **Anthropic constraint (E3):** The continuation for Anthropic does not set\n * a forced `tool_choice`. Only `tool_choice: 'auto'` (the default, i.e.\n * omitted) is compatible with extended thinking.\n *\n * @param params - Turn parameters\n * @returns `{ events, nextTurn }` — stream iterable + completion promise\n * @public\n */\nexport function executeClientToolTurn(\n params: IExecuteClientToolTurnParams\n): Result<IExecuteClientToolTurnResult> {\n const {\n descriptor,\n apiKey,\n prompt,\n messagesBefore,\n continuationMessages,\n temperature,\n tools,\n clientTools,\n signal,\n logger,\n resolvedThinking,\n model\n } = params;\n\n // Build a lookup map of client tools by name for fast access.\n // Fail fast on duplicate names — silently overwriting would cause one tool\n // to shadow another with no observable signal.\n const toolsByName = new Map<string, IAiClientTool>();\n for (const tool of clientTools) {\n if (toolsByName.has(tool.config.name)) {\n return fail(`executeClientToolTurn: duplicate client tool name '${tool.config.name}'`);\n }\n toolsByName.set(tool.config.name, tool);\n }\n\n // Merge server tools and client tool configs into a single array for the provider.\n // This is the fix for P1-1: client tools were never sent to the provider because\n // the adapters only received `tools` (server tools). Both must coexist per design §2.5.\n const effectiveTools: ReadonlyArray<AiToolConfig> | undefined =\n clientTools.length > 0 ? [...(tools ?? []), ...clientTools.map((t) => t.config)] : tools;\n\n const effectiveTemperature = temperature ?? 0.7;\n const resolvedModel = model ?? resolveModel(descriptor.defaultModel);\n const config: IStreamApiConfig = {\n baseUrl: descriptor.baseUrl,\n apiKey,\n model: resolvedModel\n };\n\n // Accumulation buffers — populated by the adapter, read by the builder.\n const anthropicBuffer = new Map<number, IAccumulatedBlock>();\n const openAiCallMap = new Map<string, IAccumulatedFunctionCall>();\n const geminiCalls: IAccumulatedGeminiFunctionCall[] = [];\n\n // Collected tool results, populated as each client-tool-call-done is processed.\n const toolResults: IToolCallResult[] = [];\n\n // Stream start: open the underlying adapter stream.\n const streamPromise: Promise<Result<AsyncIterable<IAiStreamEvent>>> = (() => {\n switch (descriptor.apiFormat) {\n case 'anthropic':\n return callAnthropicStream(\n config,\n prompt,\n messagesBefore,\n effectiveTemperature,\n effectiveTools,\n logger,\n signal,\n resolvedThinking,\n anthropicBuffer,\n continuationMessages\n );\n case 'openai':\n return callOpenAiResponsesStream(\n config,\n prompt,\n /* c8 ignore next 1 - defensive: openai path requires tools; empty array fallback unreachable in practice */\n effectiveTools ?? [],\n messagesBefore,\n effectiveTemperature,\n logger,\n signal,\n resolvedThinking,\n openAiCallMap,\n continuationMessages\n );\n case 'gemini':\n return callGeminiStream(\n config,\n prompt,\n messagesBefore,\n effectiveTemperature,\n effectiveTools,\n logger,\n signal,\n resolvedThinking,\n geminiCalls,\n continuationMessages\n );\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = descriptor.apiFormat;\n return Promise.resolve(fail(`unsupported API format: ${String(_exhaustive)}`));\n }\n }\n })();\n\n // Resolve controls for `nextTurn`.\n let resolveNextTurn!: (result: Result<IAiClientToolTurnResult>) => void;\n const nextTurn = new Promise<Result<IAiClientToolTurnResult>>((resolve) => {\n resolveNextTurn = resolve;\n });\n\n // The unified-event generator: opens the stream, proxies events, executes tools.\n async function* eventGenerator(): AsyncGenerator<IAiStreamEvent> {\n const streamResult = await streamPromise;\n if (streamResult.isFailure()) {\n resolveNextTurn(fail(streamResult.message));\n yield { type: 'error', message: streamResult.message };\n return;\n }\n\n let truncated = false;\n let fullText = '';\n let streamError: string | undefined;\n\n for await (const event of streamResult.value) {\n if (event.type === 'done') {\n truncated = event.truncated;\n fullText = event.fullText;\n yield event;\n continue;\n }\n\n if (event.type === 'error') {\n streamError = event.message;\n yield event;\n continue;\n }\n\n if (event.type === 'text-delta') {\n yield event;\n continue;\n }\n\n if (event.type === 'tool-event') {\n yield event;\n continue;\n }\n\n if (event.type === 'client-tool-call-start') {\n yield event;\n continue;\n }\n\n if (event.type === 'client-tool-call-done') {\n yield event;\n\n const { toolName, callId, args } = event;\n const tool = toolsByName.get(toolName);\n\n if (!tool) {\n const errMsg = `model called unknown tool: ${toolName}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n resolveNextTurn(fail(errMsg));\n return;\n }\n\n const validationResult = tool.config.parametersSchema.validate(args);\n if (validationResult.isFailure()) {\n const errMsg = `${toolName} (callId=${callId}): ${validationResult.message}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n\n const executeResult = await captureAsyncResult(async () => tool.execute(validationResult.value));\n const executionResult: Result<unknown> = executeResult.isSuccess()\n ? executeResult.value\n : executeResult;\n\n if (executionResult.isFailure()) {\n const errMsg = `${toolName} (callId=${callId}): ${executionResult.message}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n\n // JSON.stringify can throw (circular references) or return undefined\n // (e.g. for a bare `undefined` value, or a value of type `function`).\n // Either outcome violates the client-tool-result event contract, so\n // emit an isError result with diagnostic context instead.\n let resultStr: string;\n try {\n const stringified = JSON.stringify(executionResult.value);\n if (stringified === undefined) {\n const errMsg = `${toolName} (callId=${callId}): tool returned a non-serializable value (JSON.stringify produced undefined)`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n resultStr = stringified;\n } catch (e) {\n const errMsg = `${toolName} (callId=${callId}): failed to serialize tool result: ${\n (e as Error).message\n }`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: resultStr,\n isError: false\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: resultStr, isError: false });\n continue;\n }\n\n // client-tool-result events are emitted by this layer, not the adapters — no passthrough needed.\n }\n\n // Stream has ended. Build the continuation.\n if (streamError !== undefined) {\n resolveNextTurn(fail(streamError));\n return;\n }\n\n if (toolResults.length === 0) {\n resolveNextTurn(succeed({ continuation: undefined, truncated, fullText }));\n return;\n }\n\n let continuation: IAiClientToolContinuation;\n switch (descriptor.apiFormat) {\n case 'anthropic':\n continuation = buildAnthropicContinuation(anthropicBuffer, toolResults);\n break;\n case 'openai':\n continuation = buildOpenAiContinuation(openAiCallMap, toolResults);\n break;\n case 'gemini':\n continuation = buildGeminiContinuation(geminiCalls, toolResults);\n break;\n /* c8 ignore next 5 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = descriptor.apiFormat;\n resolveNextTurn(fail(`unsupported API format: ${String(_exhaustive)}`));\n return;\n }\n }\n\n resolveNextTurn(succeed({ continuation, truncated, fullText }));\n }\n\n return succeed({\n events: { [Symbol.asyncIterator]: () => eventGenerator() },\n nextTurn\n });\n}\n"]}
1
+ {"version":3,"file":"clientToolContinuationBuilder.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Per-provider continuation message builders and the `executeClientToolTurn`\n * helper for orchestrating a single client-tool round-trip.\n *\n * Each provider requires a different wire format for the follow-up request:\n * - **Anthropic**: assistant turn reconstructed from the ordered accumulation\n * buffer (thinking / redacted_thinking / text / tool_use in original stream\n * order) + user turn with `tool_result` blocks. When thinking is active, the\n * follow-up request must NOT set `tool_choice: { type: 'any' }` or\n * `tool_choice: { type: 'tool', ... }` (E3 / §5.4 of b4-spike-findings).\n * - **OpenAI / xAI Responses API**: `function_call` input items +\n * `function_call_output` input items.\n * - **Gemini**: model turn with `functionCall` parts + user turn with\n * `functionResponse` parts (correlation by tool name).\n *\n * @packageDocumentation\n */\n\nimport { captureAsyncResult, fail, type Logging, Result, succeed } from '@fgv/ts-utils';\nimport { type JsonArray, type JsonObject } from '@fgv/ts-json-base';\n\nimport {\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiClientTool,\n type IAiClientToolContinuation,\n type IAiClientToolTurnResult,\n type IAiStreamEvent,\n type IChatRequest,\n type IAiProviderDescriptor,\n resolveModel\n} from '../model';\nimport { type IResolvedThinkingConfig } from '../thinkingOptionsResolver';\nimport { splitChatRequest } from '../chatRequestBuilders';\nimport { resolveEffectiveBaseUrl } from '../endpoint';\nimport { type IAccumulatedBlock } from './anthropic';\nimport { type IAccumulatedFunctionCall } from './openaiResponses';\nimport { type IAccumulatedGeminiFunctionCall } from './gemini';\nimport { callAnthropicStream } from './anthropic';\nimport { callOpenAiResponsesStream } from './openaiResponses';\nimport { callGeminiStream } from './gemini';\nimport { type IStreamApiConfig } from './common';\n\n// ============================================================================\n// Tool-result accumulation (internal)\n// ============================================================================\n\n/**\n * Accumulated result for a single tool call, collected during stream iteration.\n * @internal\n */\ninterface IToolCallResult {\n readonly toolName: string;\n readonly callId?: string;\n readonly args: JsonObject;\n readonly result: string;\n readonly isError: boolean;\n}\n\n// ============================================================================\n// Anthropic continuation builder\n// ============================================================================\n\n/**\n * Builds the Anthropic follow-up messages for a client-tool round-trip.\n *\n * Reconstructs the assistant turn from the ordered accumulation buffer\n * (all block types in original stream order) and appends a user turn\n * with `tool_result` blocks for each executed tool call.\n *\n * **Constraint (E3):** The returned continuation does NOT include a forced\n * `tool_choice` field. When thinking is active, Anthropic rejects\n * `tool_choice: { type: 'any' }` and `tool_choice: { type: 'tool', ... }`\n * with an HTTP 400 error. Only `tool_choice: { type: 'auto' }` (the default,\n * i.e. omitted) is compatible with extended thinking.\n *\n * @internal\n */\nexport function buildAnthropicContinuation(\n accBuffer: Map<number, IAccumulatedBlock>,\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n // Reconstruct the assistant turn from the ordered accumulation buffer.\n // Sort by buffer key (SSE index) to restore original stream order.\n const sortedKeys = Array.from(accBuffer.keys()).sort((a, b) => a - b);\n const assistantContent: JsonArray = [];\n\n for (const key of sortedKeys) {\n const block = accBuffer.get(key);\n /* c8 ignore next 1 - defensive: key always exists in map since we iterate its keys */\n if (!block) continue;\n if (block.type === 'thinking') {\n assistantContent.push({\n type: 'thinking',\n thinking: block.thinking,\n signature: block.signature\n });\n } else if (block.type === 'redacted_thinking') {\n assistantContent.push({\n type: 'redacted_thinking',\n data: block.data\n });\n } else if (block.type === 'text') {\n if (block.text.length > 0) {\n assistantContent.push({ type: 'text', text: block.text });\n }\n } else if (block.type === 'tool_use') {\n let parsedInput: JsonObject;\n try {\n /* c8 ignore next 1 - defensive: argsBuffer is JSON-parsed in the adapter before emitting client-tool-call-done */\n parsedInput = JSON.parse(block.argsBuffer || '{}') as JsonObject;\n /* c8 ignore start - defensive: malformed argsBuffer defaults to empty object */\n } catch {\n parsedInput = {};\n }\n /* c8 ignore stop */\n assistantContent.push({\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: parsedInput\n });\n }\n }\n\n // Build user turn with tool_result blocks for each tool call.\n const userContent: JsonArray = toolResults.map((r): JsonObject => {\n const block: JsonObject = {\n type: 'tool_result',\n // eslint-disable-next-line @typescript-eslint/naming-convention\n tool_use_id: r.callId ?? r.toolName,\n content: r.result\n };\n if (r.isError) {\n return { ...block, is_error: true };\n }\n return block;\n });\n\n const assistantMessage: JsonObject = {\n role: 'assistant',\n content: assistantContent\n };\n const userMessage: JsonObject = {\n role: 'user',\n content: userContent\n };\n\n return {\n messages: [assistantMessage, userMessage],\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// OpenAI / xAI Responses API continuation builder\n// ============================================================================\n\n/**\n * Builds the OpenAI / xAI Responses API follow-up input items for a\n * client-tool round-trip.\n *\n * Emits `function_call` items (the model's call) followed by\n * `function_call_output` items (the harness execution result), one pair\n * per executed tool call.\n *\n * @internal\n */\nexport function buildOpenAiContinuation(\n calls: Map<string, IAccumulatedFunctionCall>,\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n const items: JsonObject[] = [];\n\n // Emit function_call items for each call (model's side). Per the Responses API spec\n // (ResponseFunctionToolCall), `call_id` is the required correlation field — it must\n // match the matching function_call_output's `call_id` below. The optional `id` field\n // is the output-item id (`fc_*`) used to reference the streamed item; we omit it\n // because it is not load-bearing for input items.\n for (const [callId, call] of calls) {\n items.push({\n type: 'function_call',\n call_id: callId,\n name: call.name,\n arguments: call.argsBuffer\n });\n }\n\n // Emit function_call_output items (harness execution results).\n for (const r of toolResults) {\n items.push({\n type: 'function_call_output',\n call_id: r.callId ?? r.toolName,\n output: r.result\n });\n }\n\n return {\n messages: items,\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// Gemini continuation builder\n// ============================================================================\n\n/**\n * Builds the Gemini follow-up contents for a client-tool round-trip.\n *\n * Emits a model turn with `functionCall` parts (one per tool call) and a\n * user turn with `functionResponse` parts (correlation by tool name, since\n * Gemini does not assign call IDs).\n *\n * @internal\n */\nexport function buildGeminiContinuation(\n calls: IAccumulatedGeminiFunctionCall[],\n toolResults: IToolCallResult[]\n): IAiClientToolContinuation {\n // Model turn: functionCall parts for each call.\n const modelParts: JsonArray = calls.map(\n (call): JsonObject => ({\n functionCall: {\n name: call.name,\n args: call.args\n }\n })\n );\n\n // User turn: functionResponse parts for each executed result.\n // Correlation is by name since Gemini has no call IDs.\n const userParts: JsonArray = toolResults.map(\n (r): JsonObject => ({\n functionResponse: {\n name: r.toolName,\n response: {\n content: r.result,\n ...(r.isError ? { error: true } : {})\n }\n }\n })\n );\n\n const modelMessage: JsonObject = {\n role: 'model',\n parts: modelParts\n };\n const userMessage: JsonObject = {\n role: 'user',\n parts: userParts\n };\n\n return {\n messages: [modelMessage, userMessage],\n toolCallsSummary: toolResults.map((r) => ({\n toolName: r.toolName,\n callId: r.callId,\n args: r.args,\n result: r.result,\n isError: r.isError\n }))\n };\n}\n\n// ============================================================================\n// executeClientToolTurn parameters\n// ============================================================================\n\n/**\n * Parameters for {@link AiAssist.executeClientToolTurn}.\n *\n * @remarks\n * Carries the unified {@link AiAssist.IChatRequest} shape (`system?` + ordered\n * `messages`): the last message is the current user turn and the preceding\n * messages are history, linearized before the current turn — identically to the\n * completion and streaming paths. {@link IExecuteClientToolTurnParams.continuationMessages}\n * remains a distinct post-current-turn axis (see below).\n *\n * @public\n */\nexport interface IExecuteClientToolTurnParams extends IChatRequest {\n /** The provider descriptor for routing (Anthropic / OpenAI / Gemini). */\n readonly descriptor: IAiProviderDescriptor;\n /** API key for authentication. */\n readonly apiKey: string;\n /**\n * Provider-specific continuation messages to append after the current user\n * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s\n * `messages` field from a prior turn back to the provider in the follow-up request.\n *\n * Each provider applies its own shape guard to the supplied wire objects:\n * - Anthropic: projects each entry to `{ role, content }` (sufficient for\n * thinking blocks and `tool_result` arrays).\n * - OpenAI / xAI Responses: passes each item verbatim (`function_call` /\n * `function_call_output` items carry distinct fields per `type`); only guards\n * that each entry is a JSON object.\n * - Gemini: projects each entry to `{ role, parts }`.\n *\n * Entries that fail their provider's shape check are silently skipped.\n */\n readonly continuationMessages?: ReadonlyArray<JsonObject>;\n /** Temperature (default: 0.7). */\n readonly temperature?: number;\n /** Server-side tools to include. */\n readonly tools?: ReadonlyArray<AiServerToolConfig>;\n /** Client-defined tools available for the model to call. */\n readonly clientTools: ReadonlyArray<IAiClientTool>;\n /** Optional abort signal. */\n readonly signal?: AbortSignal;\n /**\n * Optional override of the descriptor's default base URL. Same semantics as\n * the non-streaming completion path and `callProviderCompletionStream`: a\n * well-formed `http`/`https` URL is substituted for `descriptor.baseUrl`\n * when composing the per-format request, with the per-format suffix appended\n * unchanged. Validated at the dispatcher; auth shape is unaffected. Use this\n * to point a client-tool turn at a local / LAN OpenAI-compatible server\n * (Ollama, LM Studio, llama.cpp).\n */\n readonly endpoint?: string;\n /** Optional logger for diagnostics. */\n readonly logger?: Logging.ILogger;\n /** Optional resolved thinking config (pre-resolved by the caller). */\n readonly resolvedThinking?: IResolvedThinkingConfig;\n /** Resolved model string (pre-resolved by the caller). When omitted, uses the descriptor's default model. */\n readonly model?: string;\n}\n\n/**\n * Return value of {@link AiAssist.executeClientToolTurn}.\n * @public\n */\nexport interface IExecuteClientToolTurnResult {\n /**\n * The unified-event iterable. Callers iterate this to drive the streaming UI.\n * The iterable forwards `text-delta`, `tool-event`, `client-tool-call-start`,\n * `client-tool-call-done`, and `client-tool-result` events through.\n */\n readonly events: AsyncIterable<IAiStreamEvent>;\n /**\n * Resolves when the stream terminates. On success, carries the\n * {@link AiAssist.IAiClientToolTurnResult} with the optional continuation for the\n * next round. On failure, carries the error message.\n */\n readonly nextTurn: Promise<Result<IAiClientToolTurnResult>>;\n}\n\n// ============================================================================\n// executeClientToolTurn\n// ============================================================================\n\n/**\n * Orchestrates a single client-tool streaming turn for any supported provider.\n *\n * Starts a streaming request, iterates the underlying provider stream, and:\n * - Forwards `text-delta`, `tool-event`, `client-tool-call-start`, and\n * `client-tool-call-done` events through to the consumer.\n * - For each `client-tool-call-done` event: validates the raw args against the\n * tool's `parametersSchema`, invokes `execute(typedArgs)`, and emits a\n * `client-tool-result` event.\n * - After stream completion: builds the per-provider continuation (or\n * `{ continuation: undefined }` when no tool calls occurred) and resolves\n * `nextTurn`.\n *\n * **Anthropic constraint (E3):** The continuation for Anthropic does not set\n * a forced `tool_choice`. Only `tool_choice: 'auto'` (the default, i.e.\n * omitted) is compatible with extended thinking.\n *\n * @param params - Turn parameters\n * @returns `{ events, nextTurn }` — stream iterable + completion promise\n * @public\n */\nexport function executeClientToolTurn(\n params: IExecuteClientToolTurnParams\n): Result<IExecuteClientToolTurnResult> {\n const {\n descriptor,\n apiKey,\n system,\n messages,\n continuationMessages,\n temperature,\n tools,\n clientTools,\n signal,\n logger,\n resolvedThinking,\n model,\n endpoint\n } = params;\n\n const splitResult = splitChatRequest(system, messages);\n if (splitResult.isFailure()) {\n return fail(splitResult.message);\n }\n const { prompt, head } = splitResult.value;\n if (prompt.attachments.length > 0 && !descriptor.acceptsImageInput) {\n return fail(`provider \"${descriptor.id}\" does not accept image input`);\n }\n\n // Build a lookup map of client tools by name for fast access.\n // Fail fast on duplicate names — silently overwriting would cause one tool\n // to shadow another with no observable signal.\n const toolsByName = new Map<string, IAiClientTool>();\n for (const tool of clientTools) {\n if (toolsByName.has(tool.config.name)) {\n return fail(`executeClientToolTurn: duplicate client tool name '${tool.config.name}'`);\n }\n toolsByName.set(tool.config.name, tool);\n }\n\n // Merge server tools and client tool configs into a single array for the provider.\n // This is the fix for P1-1: client tools were never sent to the provider because\n // the adapters only received `tools` (server tools). Both must coexist per design §2.5.\n const effectiveTools: ReadonlyArray<AiToolConfig> | undefined =\n clientTools.length > 0 ? [...(tools ?? []), ...clientTools.map((t) => t.config)] : tools;\n\n const effectiveTemperature = temperature ?? 0.7;\n const resolvedModel = model ?? resolveModel(descriptor.defaultModel);\n if (resolvedModel.length === 0) {\n return fail(`provider \"${descriptor.id}\": no model resolved; pass model or set descriptor.defaultModel`);\n }\n const baseUrlResult = resolveEffectiveBaseUrl(descriptor, endpoint);\n if (baseUrlResult.isFailure()) {\n return fail(baseUrlResult.message);\n }\n const config: IStreamApiConfig = {\n baseUrl: baseUrlResult.value,\n apiKey,\n model: resolvedModel\n };\n\n // Accumulation buffers — populated by the adapter, read by the builder.\n const anthropicBuffer = new Map<number, IAccumulatedBlock>();\n const openAiCallMap = new Map<string, IAccumulatedFunctionCall>();\n const geminiCalls: IAccumulatedGeminiFunctionCall[] = [];\n\n // Collected tool results, populated as each client-tool-call-done is processed.\n const toolResults: IToolCallResult[] = [];\n\n // Stream start: open the underlying adapter stream.\n const streamPromise: Promise<Result<AsyncIterable<IAiStreamEvent>>> = (() => {\n switch (descriptor.apiFormat) {\n case 'anthropic':\n return callAnthropicStream(\n config,\n prompt,\n head,\n effectiveTemperature,\n effectiveTools,\n logger,\n signal,\n resolvedThinking,\n anthropicBuffer,\n continuationMessages\n );\n case 'openai':\n return callOpenAiResponsesStream(\n config,\n prompt,\n /* c8 ignore next 1 - defensive: openai path requires tools; empty array fallback unreachable in practice */\n effectiveTools ?? [],\n head,\n effectiveTemperature,\n logger,\n signal,\n resolvedThinking,\n openAiCallMap,\n continuationMessages\n );\n case 'gemini':\n return callGeminiStream(\n config,\n prompt,\n head,\n effectiveTemperature,\n effectiveTools,\n logger,\n signal,\n resolvedThinking,\n geminiCalls,\n continuationMessages\n );\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = descriptor.apiFormat;\n return Promise.resolve(fail(`unsupported API format: ${String(_exhaustive)}`));\n }\n }\n })();\n\n // Resolve controls for `nextTurn`.\n let resolveNextTurn!: (result: Result<IAiClientToolTurnResult>) => void;\n const nextTurn = new Promise<Result<IAiClientToolTurnResult>>((resolve) => {\n resolveNextTurn = resolve;\n });\n\n // The unified-event generator: opens the stream, proxies events, executes tools.\n async function* eventGenerator(): AsyncGenerator<IAiStreamEvent> {\n const streamResult = await streamPromise;\n if (streamResult.isFailure()) {\n resolveNextTurn(fail(streamResult.message));\n yield { type: 'error', message: streamResult.message };\n return;\n }\n\n let truncated = false;\n let fullText = '';\n let streamError: string | undefined;\n\n for await (const event of streamResult.value) {\n if (event.type === 'done') {\n truncated = event.truncated;\n fullText = event.fullText;\n yield event;\n continue;\n }\n\n if (event.type === 'error') {\n streamError = event.message;\n yield event;\n continue;\n }\n\n if (event.type === 'text-delta') {\n yield event;\n continue;\n }\n\n if (event.type === 'tool-event') {\n yield event;\n continue;\n }\n\n if (event.type === 'client-tool-call-start') {\n yield event;\n continue;\n }\n\n if (event.type === 'client-tool-call-done') {\n yield event;\n\n const { toolName, callId, args } = event;\n const tool = toolsByName.get(toolName);\n\n if (!tool) {\n const errMsg = `model called unknown tool: ${toolName}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n resolveNextTurn(fail(errMsg));\n return;\n }\n\n const validationResult = tool.config.parametersSchema.validate(args);\n if (validationResult.isFailure()) {\n const errMsg = `${toolName} (callId=${callId}): ${validationResult.message}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n\n const executeResult = await captureAsyncResult(async () => tool.execute(validationResult.value));\n const executionResult: Result<unknown> = executeResult.isSuccess()\n ? executeResult.value\n : executeResult;\n\n if (executionResult.isFailure()) {\n const errMsg = `${toolName} (callId=${callId}): ${executionResult.message}`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n\n // JSON.stringify can throw (circular references) or return undefined\n // (e.g. for a bare `undefined` value, or a value of type `function`).\n // Either outcome violates the client-tool-result event contract, so\n // emit an isError result with diagnostic context instead.\n let resultStr: string;\n try {\n const stringified = JSON.stringify(executionResult.value);\n if (stringified === undefined) {\n const errMsg = `${toolName} (callId=${callId}): tool returned a non-serializable value (JSON.stringify produced undefined)`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n resultStr = stringified;\n } catch (e) {\n const errMsg = `${toolName} (callId=${callId}): failed to serialize tool result: ${\n (e as Error).message\n }`;\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: errMsg,\n isError: true\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: errMsg, isError: true });\n continue;\n }\n const resultEvent: IAiStreamEvent = {\n type: 'client-tool-result',\n toolName,\n callId,\n result: resultStr,\n isError: false\n };\n yield resultEvent;\n toolResults.push({ toolName, callId, args, result: resultStr, isError: false });\n continue;\n }\n\n // client-tool-result events are emitted by this layer, not the adapters — no passthrough needed.\n }\n\n // Stream has ended. Build the continuation.\n if (streamError !== undefined) {\n resolveNextTurn(fail(streamError));\n return;\n }\n\n if (toolResults.length === 0) {\n resolveNextTurn(succeed({ continuation: undefined, truncated, fullText }));\n return;\n }\n\n let continuation: IAiClientToolContinuation;\n switch (descriptor.apiFormat) {\n case 'anthropic':\n continuation = buildAnthropicContinuation(anthropicBuffer, toolResults);\n break;\n case 'openai':\n continuation = buildOpenAiContinuation(openAiCallMap, toolResults);\n break;\n case 'gemini':\n continuation = buildGeminiContinuation(geminiCalls, toolResults);\n break;\n /* c8 ignore next 5 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = descriptor.apiFormat;\n resolveNextTurn(fail(`unsupported API format: ${String(_exhaustive)}`));\n return;\n }\n }\n\n resolveNextTurn(succeed({ continuation, truncated, fullText }));\n }\n\n return succeed({\n events: { [Symbol.asyncIterator]: () => eventGenerator() },\n nextTurn\n });\n}\n"]}
@@ -6,28 +6,25 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
  import { type Logging, Result, type Validator } from '@fgv/ts-utils';
9
- import { AiPrompt, type AiServerToolConfig, type IAiProviderDescriptor, type IChatMessage, type IThinkingConfig, type ModelSpec } from '../model';
9
+ import { type AiServerToolConfig, type IAiProviderDescriptor, type IChatRequest, type IThinkingConfig, type ModelSpec } from '../model';
10
10
  /**
11
11
  * Parameters for a streaming completion request. Structurally identical to
12
12
  * the non-streaming `IProviderCompletionParams`; kept as its own interface
13
13
  * so callers can be explicit about which path they're invoking.
14
14
  *
15
+ * @remarks
16
+ * Carries the unified {@link AiAssist.IChatRequest} shape (`system?` + ordered
17
+ * `messages`): the last message is the current user turn and the preceding
18
+ * messages are history, linearized before the current turn (identical to the
19
+ * completion and client-tool turn paths).
20
+ *
15
21
  * @public
16
22
  */
17
- export interface IProviderCompletionStreamParams {
23
+ export interface IProviderCompletionStreamParams extends IChatRequest {
18
24
  /** The provider descriptor */
19
25
  readonly descriptor: IAiProviderDescriptor;
20
26
  /** API key for authentication */
21
27
  readonly apiKey: string;
22
- /** The structured prompt to send */
23
- readonly prompt: AiPrompt;
24
- /**
25
- * Prior conversation history to insert between the system prompt and the
26
- * prompt's user message. The new user turn (carried by `prompt.user`) is
27
- * always sent last, so the wire shape becomes
28
- * `[system, ...messagesBefore, user=prompt.user]`.
29
- */
30
- readonly messagesBefore?: ReadonlyArray<IChatMessage>;
31
28
  /** Sampling temperature (default: 0.7) */
32
29
  readonly temperature?: number;
33
30
  /** Optional model override — string or context-aware map. */
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/common.ts"],"names":[],"mappings":"AAoBA;;;;;;GAMG;AAEH,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,EACL,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAElB;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC9C,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACtD,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAuC,CAAC;AAclF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uCAAuC,EAAE,MAAoD,CAAC;AAE3G;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgC1E;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAmC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAG7F"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/common.ts"],"names":[],"mappings":"AAoBA;;;;;;GAMG;AAEH,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,+BAAgC,SAAQ,YAAY;IACnE,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAuC,CAAC;AAclF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uCAAuC,EAAE,MAAoD,CAAC;AAE3G;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgC1E;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAmC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAG7F"}
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/common.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Shared infrastructure for the per-format streaming adapters: HTTP connection\n * helper, common config and request-params types, and a typed-validation\n * helper for SSE event payloads.\n *\n * @packageDocumentation\n */\n\nimport { fail, type Logging, Result, succeed, type Validator } from '@fgv/ts-utils';\n\nimport {\n AiPrompt,\n type AiServerToolConfig,\n type IAiProviderDescriptor,\n type IChatMessage,\n type IThinkingConfig,\n type ModelSpec\n} from '../model';\n\n/**\n * Parameters for a streaming completion request. Structurally identical to\n * the non-streaming `IProviderCompletionParams`; kept as its own interface\n * so callers can be explicit about which path they're invoking.\n *\n * @public\n */\nexport interface IProviderCompletionStreamParams {\n /** The provider descriptor */\n readonly descriptor: IAiProviderDescriptor;\n /** API key for authentication */\n readonly apiKey: string;\n /** The structured prompt to send */\n readonly prompt: AiPrompt;\n /**\n * Prior conversation history to insert between the system prompt and the\n * prompt's user message. The new user turn (carried by `prompt.user`) is\n * always sent last, so the wire shape becomes\n * `[system, ...messagesBefore, user=prompt.user]`.\n */\n readonly messagesBefore?: ReadonlyArray<IChatMessage>;\n /** Sampling temperature (default: 0.7) */\n readonly temperature?: number;\n /** Optional model override — string or context-aware map. */\n readonly modelOverride?: ModelSpec;\n /** Optional logger for request/response observability. */\n readonly logger?: Logging.ILogger;\n /** Server-side tools to include in the request. */\n readonly tools?: ReadonlyArray<AiServerToolConfig>;\n /** Optional abort signal for cancelling the in-flight stream. */\n readonly signal?: AbortSignal;\n /**\n * Optional override of the descriptor's default base URL. Same semantics as\n * the non-streaming completion path: a well-formed `http`/`https` URL is\n * substituted for `descriptor.baseUrl` when composing the streaming\n * request, with the per-format suffix appended unchanged. Validated at the\n * dispatcher; auth shape is unaffected.\n */\n readonly endpoint?: string;\n /**\n * Optional thinking/reasoning mode configuration.\n */\n readonly thinking?: IThinkingConfig;\n}\n\n/**\n * Configuration for a single per-format streaming call: where to POST, what\n * key to authenticate with, and which model to request.\n *\n * @internal\n */\nexport interface IStreamApiConfig {\n readonly baseUrl: string;\n readonly apiKey: string;\n readonly model: string;\n}\n\n/**\n * Stable log-line prefix that every streaming adapter's \"unrecognized SSE event\"\n * warning starts with. Production deployments can filter / alert on this exact\n * substring without coupling to the per-adapter detail message. Surfacing this\n * as a shared constant ensures all adapters emit the same prefix; loosening or\n * renaming the prefix is a coordinated, intentional change rather than a per-file\n * accident.\n *\n * @internal\n */\nexport const UNRECOGNIZED_EVENT_WARN_TAG: string = 'ai-assist:unrecognized-event';\n\n/**\n * Maximum characters of raw SSE payload to include in the\n * {@link UNRECOGNIZED_EVENT_WARN_TAG} warning when raw-preview mode is opted in\n * via {@link UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR}. Long enough to identify\n * the JSON shape that arrived (\"the new event carries field X\"), short enough\n * that a hot stream of unknown events with a verbose payload doesn't blow up\n * log volume.\n *\n * @internal\n */\nconst UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX: number = 200;\n\n/**\n * Environment variable that opts in to **raw payload preview** in the\n * {@link UNRECOGNIZED_EVENT_WARN_TAG} warning. Any non-empty, non-`'0'` value\n * activates the raw preview. **Default behavior** (env var absent / empty /\n * `'0'`) is **structural-only** preview — top-level JSON keys + payload byte\n * length, never the values.\n *\n * The default-safe posture exists because unrecognized SSE event payloads can\n * carry tool arguments, tool results, user-conversation text, or other\n * potentially sensitive content. Emitting them verbatim at `warn` level — which\n * is the level explicitly designed to surface in production logs / alerting —\n * is a PII leak waiting to happen.\n *\n * Ops triaging an active drift signal (`ai-assist:unrecognized-event` warnings\n * appearing in production logs after a provider API evolution) can set this\n * env var to widen the preview and see the actual payload shape during\n * investigation, then unset it once the new event family is handled.\n *\n * @internal\n */\nexport const UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR: string = 'AI_ASSIST_UNRECOGNIZED_EVENT_FULL_PAYLOAD';\n\n/**\n * Renders an SSE `data:` payload for inclusion in an unrecognized-event\n * warning.\n *\n * - Empty payload: returns `<no payload>`.\n * - Default (env var unset): returns structural-only preview (e.g.\n * `{ keys: [type, data], length: 1234 }` for a JSON object payload;\n * `<array payload, length=N>` / `<{type} payload, length=N>` /\n * `<non-JSON payload, length=N>` for other shapes). Never includes\n * field values.\n * - With {@link UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR} set to a truthy\n * value: returns the raw payload, newlines collapsed to spaces, capped\n * at {@link UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX} chars with a trailing\n * ellipsis on truncation. **Use this mode only for active drift triage**\n * — it leaks payload content into warn logs.\n *\n * @internal\n */\nexport function formatUnrecognizedEventPayloadPreview(data: string): string {\n if (data.length === 0) return '<no payload>';\n\n // Opt-in raw preview for ops triage. Accessed via `globalThis` (always\n // defined) rather than a bare `process` reference, so webpack/rollup never\n // try to bundle or polyfill `process` for browser consumers. A\n // `typeof process !== 'undefined'` guard is runtime-safe but still triggers\n // webpack's static module resolution on the `process` identifier.\n const proc = (globalThis as unknown as { process?: { env?: Record<string, string | undefined> } }).process;\n const envValue = proc?.env?.[UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR];\n const rawPreviewOptIn = envValue !== undefined && envValue !== '' && envValue !== '0';\n if (rawPreviewOptIn) {\n const collapsed = data.replace(/\\s+/g, ' ');\n return collapsed.length > UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX\n ? `${collapsed.slice(0, UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX)}…`\n : collapsed;\n }\n\n // Default-safe: structural information only. Never emits payload values.\n try {\n const parsed: unknown = JSON.parse(data);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n const keys = Object.keys(parsed);\n return `{ keys: [${keys.join(', ')}], length: ${data.length} }`;\n }\n if (Array.isArray(parsed)) {\n return `<array payload, length=${data.length}>`;\n }\n return `<${typeof parsed} payload, length=${data.length}>`;\n } catch {\n return `<non-JSON payload, length=${data.length}>`;\n }\n}\n\n/**\n * Opens an SSE-style POST connection. Returns the underlying Response on a\n * 2xx; failures (network, non-2xx, missing body) surface as Result.fail\n * carrying the body text.\n *\n * @internal\n */\nexport async function openSseConnection(\n url: string,\n headers: Record<string, string>,\n body: unknown,\n logger?: Logging.ILogger,\n signal?: AbortSignal\n): Promise<Result<Response>> {\n /* c8 ignore next 1 - optional logger */\n logger?.detail(`AI streaming request: POST ${url}`);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n ...headers\n },\n body: JSON.stringify(body),\n signal\n });\n } catch (err: unknown) {\n /* c8 ignore next 1 - defensive: fetch errors are always Error instances in practice */\n const detail = err instanceof Error ? err.message : String(err);\n /* c8 ignore next 1 - optional logger */\n logger?.error(`AI streaming request failed: ${detail}`);\n return fail(`AI streaming request failed: ${detail}`);\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n /* c8 ignore next 1 - optional logger */\n logger?.error(`AI streaming API returned ${response.status}: ${errorText}`);\n return fail(`AI streaming API returned ${response.status}: ${errorText}`);\n }\n /* c8 ignore next 3 - defensive coding: response.body is always defined for successful fetch responses */\n if (!response.body) {\n return fail('AI streaming API returned an empty body');\n }\n return succeed(response);\n}\n\n/**\n * Validates a parsed SSE event payload against a typed shape, returning the\n * validated value or `undefined` if validation fails. Adapters use the\n * `undefined` return to skip unrecognized event shapes — the same lenient\n * behavior the inline casts had, but with a real type-checked path on the\n * happy case.\n *\n * @internal\n */\nexport function validateEventPayload<T>(json: unknown, validator: Validator<T>): T | undefined {\n const result = validator.validate(json);\n return result.isSuccess() ? result.value : undefined;\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/common.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Shared infrastructure for the per-format streaming adapters: HTTP connection\n * helper, common config and request-params types, and a typed-validation\n * helper for SSE event payloads.\n *\n * @packageDocumentation\n */\n\nimport { fail, type Logging, Result, succeed, type Validator } from '@fgv/ts-utils';\n\nimport {\n type AiServerToolConfig,\n type IAiProviderDescriptor,\n type IChatRequest,\n type IThinkingConfig,\n type ModelSpec\n} from '../model';\n\n/**\n * Parameters for a streaming completion request. Structurally identical to\n * the non-streaming `IProviderCompletionParams`; kept as its own interface\n * so callers can be explicit about which path they're invoking.\n *\n * @remarks\n * Carries the unified {@link AiAssist.IChatRequest} shape (`system?` + ordered\n * `messages`): the last message is the current user turn and the preceding\n * messages are history, linearized before the current turn (identical to the\n * completion and client-tool turn paths).\n *\n * @public\n */\nexport interface IProviderCompletionStreamParams extends IChatRequest {\n /** The provider descriptor */\n readonly descriptor: IAiProviderDescriptor;\n /** API key for authentication */\n readonly apiKey: string;\n /** Sampling temperature (default: 0.7) */\n readonly temperature?: number;\n /** Optional model override — string or context-aware map. */\n readonly modelOverride?: ModelSpec;\n /** Optional logger for request/response observability. */\n readonly logger?: Logging.ILogger;\n /** Server-side tools to include in the request. */\n readonly tools?: ReadonlyArray<AiServerToolConfig>;\n /** Optional abort signal for cancelling the in-flight stream. */\n readonly signal?: AbortSignal;\n /**\n * Optional override of the descriptor's default base URL. Same semantics as\n * the non-streaming completion path: a well-formed `http`/`https` URL is\n * substituted for `descriptor.baseUrl` when composing the streaming\n * request, with the per-format suffix appended unchanged. Validated at the\n * dispatcher; auth shape is unaffected.\n */\n readonly endpoint?: string;\n /**\n * Optional thinking/reasoning mode configuration.\n */\n readonly thinking?: IThinkingConfig;\n}\n\n/**\n * Configuration for a single per-format streaming call: where to POST, what\n * key to authenticate with, and which model to request.\n *\n * @internal\n */\nexport interface IStreamApiConfig {\n readonly baseUrl: string;\n readonly apiKey: string;\n readonly model: string;\n}\n\n/**\n * Stable log-line prefix that every streaming adapter's \"unrecognized SSE event\"\n * warning starts with. Production deployments can filter / alert on this exact\n * substring without coupling to the per-adapter detail message. Surfacing this\n * as a shared constant ensures all adapters emit the same prefix; loosening or\n * renaming the prefix is a coordinated, intentional change rather than a per-file\n * accident.\n *\n * @internal\n */\nexport const UNRECOGNIZED_EVENT_WARN_TAG: string = 'ai-assist:unrecognized-event';\n\n/**\n * Maximum characters of raw SSE payload to include in the\n * {@link UNRECOGNIZED_EVENT_WARN_TAG} warning when raw-preview mode is opted in\n * via {@link UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR}. Long enough to identify\n * the JSON shape that arrived (\"the new event carries field X\"), short enough\n * that a hot stream of unknown events with a verbose payload doesn't blow up\n * log volume.\n *\n * @internal\n */\nconst UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX: number = 200;\n\n/**\n * Environment variable that opts in to **raw payload preview** in the\n * {@link UNRECOGNIZED_EVENT_WARN_TAG} warning. Any non-empty, non-`'0'` value\n * activates the raw preview. **Default behavior** (env var absent / empty /\n * `'0'`) is **structural-only** preview — top-level JSON keys + payload byte\n * length, never the values.\n *\n * The default-safe posture exists because unrecognized SSE event payloads can\n * carry tool arguments, tool results, user-conversation text, or other\n * potentially sensitive content. Emitting them verbatim at `warn` level — which\n * is the level explicitly designed to surface in production logs / alerting —\n * is a PII leak waiting to happen.\n *\n * Ops triaging an active drift signal (`ai-assist:unrecognized-event` warnings\n * appearing in production logs after a provider API evolution) can set this\n * env var to widen the preview and see the actual payload shape during\n * investigation, then unset it once the new event family is handled.\n *\n * @internal\n */\nexport const UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR: string = 'AI_ASSIST_UNRECOGNIZED_EVENT_FULL_PAYLOAD';\n\n/**\n * Renders an SSE `data:` payload for inclusion in an unrecognized-event\n * warning.\n *\n * - Empty payload: returns `<no payload>`.\n * - Default (env var unset): returns structural-only preview (e.g.\n * `{ keys: [type, data], length: 1234 }` for a JSON object payload;\n * `<array payload, length=N>` / `<{type} payload, length=N>` /\n * `<non-JSON payload, length=N>` for other shapes). Never includes\n * field values.\n * - With {@link UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR} set to a truthy\n * value: returns the raw payload, newlines collapsed to spaces, capped\n * at {@link UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX} chars with a trailing\n * ellipsis on truncation. **Use this mode only for active drift triage**\n * — it leaks payload content into warn logs.\n *\n * @internal\n */\nexport function formatUnrecognizedEventPayloadPreview(data: string): string {\n if (data.length === 0) return '<no payload>';\n\n // Opt-in raw preview for ops triage. Accessed via `globalThis` (always\n // defined) rather than a bare `process` reference, so webpack/rollup never\n // try to bundle or polyfill `process` for browser consumers. A\n // `typeof process !== 'undefined'` guard is runtime-safe but still triggers\n // webpack's static module resolution on the `process` identifier.\n const proc = (globalThis as unknown as { process?: { env?: Record<string, string | undefined> } }).process;\n const envValue = proc?.env?.[UNRECOGNIZED_EVENT_FULL_PAYLOAD_ENV_VAR];\n const rawPreviewOptIn = envValue !== undefined && envValue !== '' && envValue !== '0';\n if (rawPreviewOptIn) {\n const collapsed = data.replace(/\\s+/g, ' ');\n return collapsed.length > UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX\n ? `${collapsed.slice(0, UNRECOGNIZED_EVENT_PAYLOAD_PREVIEW_MAX)}…`\n : collapsed;\n }\n\n // Default-safe: structural information only. Never emits payload values.\n try {\n const parsed: unknown = JSON.parse(data);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n const keys = Object.keys(parsed);\n return `{ keys: [${keys.join(', ')}], length: ${data.length} }`;\n }\n if (Array.isArray(parsed)) {\n return `<array payload, length=${data.length}>`;\n }\n return `<${typeof parsed} payload, length=${data.length}>`;\n } catch {\n return `<non-JSON payload, length=${data.length}>`;\n }\n}\n\n/**\n * Opens an SSE-style POST connection. Returns the underlying Response on a\n * 2xx; failures (network, non-2xx, missing body) surface as Result.fail\n * carrying the body text.\n *\n * @internal\n */\nexport async function openSseConnection(\n url: string,\n headers: Record<string, string>,\n body: unknown,\n logger?: Logging.ILogger,\n signal?: AbortSignal\n): Promise<Result<Response>> {\n /* c8 ignore next 1 - optional logger */\n logger?.detail(`AI streaming request: POST ${url}`);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n ...headers\n },\n body: JSON.stringify(body),\n signal\n });\n } catch (err: unknown) {\n /* c8 ignore next 1 - defensive: fetch errors are always Error instances in practice */\n const detail = err instanceof Error ? err.message : String(err);\n /* c8 ignore next 1 - optional logger */\n logger?.error(`AI streaming request failed: ${detail}`);\n return fail(`AI streaming request failed: ${detail}`);\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n /* c8 ignore next 1 - optional logger */\n logger?.error(`AI streaming API returned ${response.status}: ${errorText}`);\n return fail(`AI streaming API returned ${response.status}: ${errorText}`);\n }\n /* c8 ignore next 3 - defensive coding: response.body is always defined for successful fetch responses */\n if (!response.body) {\n return fail('AI streaming API returned an empty body');\n }\n return succeed(response);\n}\n\n/**\n * Validates a parsed SSE event payload against a typed shape, returning the\n * validated value or `undefined` if validation fails. Adapters use the\n * `undefined` return to skip unrecognized event shapes — the same lenient\n * behavior the inline casts had, but with a real type-checked path on the\n * happy case.\n *\n * @internal\n */\nexport function validateEventPayload<T>(json: unknown, validator: Validator<T>): T | undefined {\n const result = validator.validate(json);\n return result.isSuccess() ? result.value : undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/proxy.ts"],"names":[],"mappings":"AAoBA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAE5E,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EAAE,+BAA+B,EAA2C,MAAM,UAAU,CAAC;AAkEpG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CA6ChD"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/proxy.ts"],"names":[],"mappings":"AAoBA;;;;;;;GAOG;AAEH,OAAO,EAAQ,MAAM,EAAuC,MAAM,eAAe,CAAC;AAGlF,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EAAE,+BAA+B,EAA2C,MAAM,UAAU,CAAC;AAkEpG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAoDhD"}