agentworkshop 0.7.60 → 0.7.61

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 (288) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{KXQppTXc.js → BTXdYngG.js} +1 -1
  3. package/.output/public/_nuxt/{Ce5SiMQR2.js → BXbKTAwC2.js} +1 -1
  4. package/.output/public/_nuxt/B_6yBa_Z.js +1 -0
  5. package/.output/public/_nuxt/B_ic601Y.js +1 -0
  6. package/.output/public/_nuxt/{DhSlJyZD2.js → BegV7-FE2.js} +1 -1
  7. package/.output/public/_nuxt/{D9sgxxsM2.js → BrRXGr472.js} +1 -1
  8. package/.output/public/_nuxt/{BeNdseTX.js → BtBgrPNT.js} +1 -1
  9. package/.output/public/_nuxt/{Cyd68Xbv2.js → C5MPzgon2.js} +1 -1
  10. package/.output/public/_nuxt/{DBdwjOGB2.js → CI5sliIF2.js} +1 -1
  11. package/.output/public/_nuxt/CI8awYVQ2.js +1 -0
  12. package/.output/public/_nuxt/{Cfp00Rdo.js → CK2ts9sD.js} +1 -1
  13. package/.output/public/_nuxt/{BjUpWKS6.js → CPZKwmLQ.js} +1 -1
  14. package/.output/public/_nuxt/{CjeMxUv8.js → CVUMEGa1.js} +1 -1
  15. package/.output/public/_nuxt/{p2sDc0tO2.js → CcLFZjCI2.js} +1 -1
  16. package/.output/public/_nuxt/{C4AICl3l.js → CeEzUIvN.js} +4 -4
  17. package/.output/public/_nuxt/{C93LpBMF.js → CfIGBe_4.js} +3 -3
  18. package/.output/public/_nuxt/{DTcsb0fG.js → Ci5kuU1q.js} +1 -1
  19. package/.output/public/_nuxt/CiyTTgqr.js +106 -0
  20. package/.output/public/_nuxt/{CgbP5yJk2.js → CkYk8bj02.js} +7 -7
  21. package/.output/public/_nuxt/Cmiz_VOb2.js +47 -0
  22. package/.output/public/_nuxt/Cnf1PFhB2.js +1 -0
  23. package/.output/public/_nuxt/CoTm7jd3.js +28 -0
  24. package/.output/public/_nuxt/{C0sNwDTK2.js → CsN8RHJ02.js} +1 -1
  25. package/.output/public/_nuxt/D-jg-SoR.js +1 -0
  26. package/.output/public/_nuxt/{CEHT9inW.js → D-z6N1Cz.js} +1 -1
  27. package/.output/public/_nuxt/D3gfSKKi2.js +1 -0
  28. package/.output/public/_nuxt/D4elH6Bo2.js +1 -0
  29. package/.output/public/_nuxt/{C5OSTzBh.js → D4tAdwYm.js} +1 -1
  30. package/.output/public/_nuxt/{BlEJRYAn2.js → DC7WzYCf2.js} +1 -1
  31. package/.output/public/_nuxt/{VeOVO2sE2.js → DE-qkHRd2.js} +1 -1
  32. package/.output/public/_nuxt/DE2kUGPK.js +1 -0
  33. package/.output/public/_nuxt/DI4sdLmu2.js +1 -0
  34. package/.output/public/_nuxt/DKHA3XxF.js +2 -0
  35. package/.output/public/_nuxt/{zVupTo2z2.js → DL6fliAT.js} +2 -2
  36. package/.output/public/_nuxt/{CMDAjShv2.js → DP6tsk912.js} +1 -1
  37. package/.output/public/_nuxt/DP_e7Vwv.js +24 -0
  38. package/.output/public/_nuxt/{C8XVZGSZ.js → DR83EvmX.js} +1 -1
  39. package/.output/public/_nuxt/{BtXwFpv42.js → DSWuWYx_2.js} +1 -1
  40. package/.output/public/_nuxt/DSdxfFX_.js +1 -0
  41. package/.output/public/_nuxt/DVS06wUy2.js +13 -0
  42. package/.output/public/_nuxt/DXlAfhEi.js +3 -0
  43. package/.output/public/_nuxt/Dc5NeCDq.js +1 -0
  44. package/.output/public/_nuxt/{B_JLVF30.js → DiHL9ehB.js} +1 -1
  45. package/.output/public/_nuxt/{Bdq2LNSO.js → DjtDexGg.js} +1 -1
  46. package/.output/public/_nuxt/DnunMTRD2.js +1 -0
  47. package/.output/public/_nuxt/{KXvRkBgg.js → Dok0B4Ol.js} +2 -2
  48. package/.output/public/_nuxt/{BFBysc2M2.js → DqT2_Jtw2.js} +1 -1
  49. package/.output/public/_nuxt/{B_BYwIf22.js → DtMlAxCm2.js} +1 -1
  50. package/.output/public/_nuxt/{BplhglEM.js → DwzJpr7P.js} +1 -1
  51. package/.output/public/_nuxt/J94L7hHq2.js +1 -0
  52. package/.output/public/_nuxt/LQBLwrYS2.js +1 -0
  53. package/.output/public/_nuxt/QSY9fE482.js +1 -0
  54. package/.output/public/_nuxt/{iCvdSYYN2.js → Qa9rS9oK2.js} +2 -2
  55. package/.output/public/_nuxt/{Cyuxcv5s2.js → R3gBFghJ2.js} +1 -1
  56. package/.output/public/_nuxt/ZxBwmbs9.js +1 -0
  57. package/.output/public/_nuxt/{BGFhOMVM.js → _mD4IkJj.js} +2 -2
  58. package/.output/public/_nuxt/analysis.DfMg76el.css +1 -0
  59. package/.output/public/_nuxt/builds/latest.json +1 -1
  60. package/.output/public/_nuxt/builds/meta/eba8574d-1991-47df-944c-18608bb58181.json +1 -0
  61. package/.output/public/_nuxt/{CZmMgjIK.js → c_nqArmG.js} +1 -1
  62. package/.output/public/_nuxt/h8ddxY892.js +1 -0
  63. package/.output/public/_nuxt/i3KBHle7.js +1 -0
  64. package/.output/public/_nuxt/jmKfTQMN.js +13 -0
  65. package/.output/public/_nuxt/{59a6cSgj.js → taHLOXkS.js} +1 -1
  66. package/.output/public/_nuxt/{EQijmkCh2.js → uYP6z4G72.js} +1 -1
  67. package/.output/public/_nuxt/{D0vmf1z9.js → yuIP6K9s.js} +1 -1
  68. package/.output/public/_nuxt/{Ddc_Pn7D.js → zWg-9WN6.js} +4 -4
  69. package/.output/public/_nuxt/zrgcKVTq.js +2 -0
  70. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  71. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  72. package/.output/server/chunks/_/nitro.mjs +1158 -1111
  73. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  74. package/.output/server/chunks/build/{AuthGate-CZYkvPrg.mjs → AuthGate-BK2RqkbD.mjs} +5 -5
  75. package/.output/server/chunks/build/{AuthGate-CZYkvPrg.mjs.map → AuthGate-BK2RqkbD.mjs.map} +1 -1
  76. package/.output/server/chunks/build/{FormItemContext-DcWIIAaK.mjs → FormItemContext-BqtgOBDe.mjs} +1 -1
  77. package/.output/server/chunks/build/{FormItemContext-DcWIIAaK.mjs.map → FormItemContext-BqtgOBDe.mjs.map} +1 -1
  78. package/.output/server/chunks/build/{OmpTerminalPanel-CtFJ6Kc8.mjs → OmpTerminalPanel-Bun6rpAk.mjs} +4 -4
  79. package/.output/server/chunks/build/{OmpTerminalPanel-CtFJ6Kc8.mjs.map → OmpTerminalPanel-Bun6rpAk.mjs.map} +1 -1
  80. package/.output/server/chunks/build/{PluginSlot-BT7kYQgK.mjs → PluginSlot-Do6dX0RE.mjs} +1 -1
  81. package/.output/server/chunks/build/{PluginSlot-BT7kYQgK.mjs.map → PluginSlot-Do6dX0RE.mjs.map} +1 -1
  82. package/.output/server/chunks/build/{_wsId_-DOEw9jgZ.mjs → _wsId_-Dp3ACbQ5.mjs} +19 -19
  83. package/.output/server/chunks/build/{_wsId_-DOEw9jgZ.mjs.map → _wsId_-Dp3ACbQ5.mjs.map} +1 -1
  84. package/.output/server/chunks/build/{agents-C36wR56A.mjs → agents-BfIoGr_p.mjs} +18 -18
  85. package/.output/server/chunks/build/{agents-C36wR56A.mjs.map → agents-BfIoGr_p.mjs.map} +1 -1
  86. package/.output/server/chunks/build/{aml-CBGndvHT.mjs → aml-B5zKrvB3.mjs} +7 -7
  87. package/.output/server/chunks/build/{aml-CBGndvHT.mjs.map → aml-B5zKrvB3.mjs.map} +1 -1
  88. package/.output/server/chunks/build/analysis-MVEnlO7A.mjs +531 -0
  89. package/.output/server/chunks/build/analysis-MVEnlO7A.mjs.map +1 -0
  90. package/.output/server/chunks/build/{card-Db7OB49d.mjs → card-IyQjdGXA.mjs} +3 -3
  91. package/.output/server/chunks/build/{card-Db7OB49d.mjs.map → card-IyQjdGXA.mjs.map} +1 -1
  92. package/.output/server/chunks/build/{channel-templates-BixUrDmU.mjs → channel-templates-Bd8bgBCh.mjs} +11 -11
  93. package/.output/server/chunks/build/{channel-templates-BixUrDmU.mjs.map → channel-templates-Bd8bgBCh.mjs.map} +1 -1
  94. package/.output/server/chunks/build/{checkbox-CyF96D30.mjs → checkbox-NnjtOam0.mjs} +2 -2
  95. package/.output/server/chunks/build/{checkbox-CyF96D30.mjs.map → checkbox-NnjtOam0.mjs.map} +1 -1
  96. package/.output/server/chunks/build/{daq-DLMLufDq.mjs → daq-mC3-5A0L.mjs} +1 -1
  97. package/.output/server/chunks/build/{daq-DLMLufDq.mjs.map → daq-mC3-5A0L.mjs.map} +1 -1
  98. package/.output/server/chunks/build/{default-C7Qmdyz_.mjs → default-flcNWlNg.mjs} +12 -12
  99. package/.output/server/chunks/build/{default-C7Qmdyz_.mjs.map → default-flcNWlNg.mjs.map} +1 -1
  100. package/.output/server/chunks/build/{descriptions-1bH81YsZ.mjs → descriptions-DuAefuzp.mjs} +1 -1
  101. package/.output/server/chunks/build/{descriptions-1bH81YsZ.mjs.map → descriptions-DuAefuzp.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{drawer-C7shdEHy.mjs → drawer-DEIB1_X6.mjs} +1 -1
  103. package/.output/server/chunks/build/{drawer-C7shdEHy.mjs.map → drawer-DEIB1_X6.mjs.map} +1 -1
  104. package/.output/server/chunks/build/{dropdown-BiwcuXDi.mjs → dropdown-BuD1pxH2.mjs} +5 -5
  105. package/.output/server/chunks/build/{dropdown-BiwcuXDi.mjs.map → dropdown-BuD1pxH2.mjs.map} +1 -1
  106. package/.output/server/chunks/build/{dropdown-BhLSIp5A.mjs → dropdown-w7qhyN2D.mjs} +2 -2
  107. package/.output/server/chunks/build/{dropdown-BhLSIp5A.mjs.map → dropdown-w7qhyN2D.mjs.map} +1 -1
  108. package/.output/server/chunks/build/es-DfgEl5n-.mjs +42 -0
  109. package/.output/server/chunks/build/es-DfgEl5n-.mjs.map +1 -0
  110. package/.output/server/chunks/build/{form-nE8C0G8B.mjs → form-CMLL_-Xx.mjs} +6 -6
  111. package/.output/server/chunks/build/{form-nE8C0G8B.mjs.map → form-CMLL_-Xx.mjs.map} +1 -1
  112. package/.output/server/chunks/build/{input-DwF72eVI.mjs → input-DZcioTwL.mjs} +3 -3
  113. package/.output/server/chunks/build/{input-DwF72eVI.mjs.map → input-DZcioTwL.mjs.map} +1 -1
  114. package/.output/server/chunks/build/{input-number-TSq6ltkz.mjs → input-number-BRnbiKLd.mjs} +5 -5
  115. package/.output/server/chunks/build/{input-number-TSq6ltkz.mjs.map → input-number-BRnbiKLd.mjs.map} +1 -1
  116. package/.output/server/chunks/build/{logs-hOEVuxqm.mjs → logs-BYop3JfX.mjs} +2 -2
  117. package/.output/server/chunks/build/{logs-hOEVuxqm.mjs.map → logs-BYop3JfX.mjs.map} +1 -1
  118. package/.output/server/chunks/build/{menu-Cy5Nrecn.mjs → menu-DXfhc0qN.mjs} +3 -3
  119. package/.output/server/chunks/build/{menu-Cy5Nrecn.mjs.map → menu-DXfhc0qN.mjs.map} +1 -1
  120. package/.output/server/chunks/build/{monitor-CfVoiavp.mjs → monitor-BjBGkUm2.mjs} +19 -19
  121. package/.output/server/chunks/build/{monitor-CfVoiavp.mjs.map → monitor-BjBGkUm2.mjs.map} +1 -1
  122. package/.output/server/chunks/build/{permissions-XPtQJSaO.mjs → permissions-u5SZL8Fe.mjs} +14 -14
  123. package/.output/server/chunks/build/{permissions-XPtQJSaO.mjs.map → permissions-u5SZL8Fe.mjs.map} +1 -1
  124. package/.output/server/chunks/build/{plugins-DjBSG9pV.mjs → plugins-Cas6KOF-.mjs} +5 -5
  125. package/.output/server/chunks/build/{plugins-DjBSG9pV.mjs.map → plugins-Cas6KOF-.mjs.map} +1 -1
  126. package/.output/server/chunks/build/{popconfirm-DKeEbaGd.mjs → popconfirm-BWxt-53K.mjs} +2 -2
  127. package/.output/server/chunks/build/{popconfirm-DKeEbaGd.mjs.map → popconfirm-BWxt-53K.mjs.map} +1 -1
  128. package/.output/server/chunks/build/{schedules-PcDLCUWN.mjs → schedules-Ct68Jrvw.mjs} +19 -19
  129. package/.output/server/chunks/build/{schedules-PcDLCUWN.mjs.map → schedules-Ct68Jrvw.mjs.map} +1 -1
  130. package/.output/server/chunks/build/{segmented-BdWCdZUM.mjs → segmented-DN62bOFu.mjs} +2 -2
  131. package/.output/server/chunks/build/{segmented-BdWCdZUM.mjs.map → segmented-DN62bOFu.mjs.map} +1 -1
  132. package/.output/server/chunks/build/{select-C5yighj8.mjs → select-DQv1DXcW.mjs} +4 -4
  133. package/.output/server/chunks/build/{select-C5yighj8.mjs.map → select-DQv1DXcW.mjs.map} +1 -1
  134. package/.output/server/chunks/build/{settings-90zT_h9w.mjs → settings-CQzR1YXR.mjs} +13 -13
  135. package/.output/server/chunks/build/{settings-90zT_h9w.mjs.map → settings-CQzR1YXR.mjs.map} +1 -1
  136. package/.output/server/chunks/build/{space-BCffbXIG.mjs → space-6FfG3llN.mjs} +3 -3
  137. package/.output/server/chunks/build/{space-BCffbXIG.mjs.map → space-6FfG3llN.mjs.map} +1 -1
  138. package/.output/server/chunks/build/{switch-OG0SM_Px.mjs → switch-CfsCVFQP.mjs} +2 -2
  139. package/.output/server/chunks/build/{switch-OG0SM_Px.mjs.map → switch-CfsCVFQP.mjs.map} +1 -1
  140. package/.output/server/chunks/build/{table-UpVzu50c.mjs → table-HOjbB5YY.mjs} +9 -9
  141. package/.output/server/chunks/build/{table-UpVzu50c.mjs.map → table-HOjbB5YY.mjs.map} +1 -1
  142. package/.output/server/chunks/build/{tabs-CWwoL33v.mjs → tabs-CC26Rbcw.mjs} +4 -4
  143. package/.output/server/chunks/build/{tabs-CWwoL33v.mjs.map → tabs-CC26Rbcw.mjs.map} +1 -1
  144. package/.output/server/chunks/build/{tag-CS7mwrfG.mjs → tag-BtOMjpDx.mjs} +4 -4
  145. package/.output/server/chunks/build/{tag-CS7mwrfG.mjs.map → tag-BtOMjpDx.mjs.map} +1 -1
  146. package/.output/server/chunks/build/{teams-BIAFvRw1.mjs → teams-Re0wY2SQ.mjs} +19 -19
  147. package/.output/server/chunks/build/{teams-BIAFvRw1.mjs.map → teams-Re0wY2SQ.mjs.map} +1 -1
  148. package/.output/server/chunks/build/{tokens-CLpdrzQ7.mjs → tokens-DLFIUvXE.mjs} +19 -19
  149. package/.output/server/chunks/build/{tokens-CLpdrzQ7.mjs.map → tokens-DLFIUvXE.mjs.map} +1 -1
  150. package/.output/server/chunks/build/{tooltip-CJlH_8ZK.mjs → tooltip-BSDwL_LM.mjs} +4 -4
  151. package/.output/server/chunks/build/{tooltip-CJlH_8ZK.mjs.map → tooltip-BSDwL_LM.mjs.map} +1 -1
  152. package/.output/server/chunks/build/{useAgentTemplateActions-6VyAHgu5.mjs → useAgentTemplateActions-CjBwCb3u.mjs} +1 -1
  153. package/.output/server/chunks/build/{useAgentTemplateActions-6VyAHgu5.mjs.map → useAgentTemplateActions-CjBwCb3u.mjs.map} +1 -1
  154. package/.output/server/chunks/build/{useAgentTemplateForm-DWa-ezNq.mjs → useAgentTemplateForm-BX9_xqj8.mjs} +1 -1
  155. package/.output/server/chunks/build/{useAgentTemplateForm-DWa-ezNq.mjs.map → useAgentTemplateForm-BX9_xqj8.mjs.map} +1 -1
  156. package/.output/server/chunks/build/{useAmlEntities-Co2fgjzh.mjs → useAmlEntities-BrcTqHwa.mjs} +2 -2
  157. package/.output/server/chunks/build/{useAmlEntities-Co2fgjzh.mjs.map → useAmlEntities-BrcTqHwa.mjs.map} +1 -1
  158. package/.output/server/chunks/build/{useAmlEnv-JTiWPrzH.mjs → useAmlEnv-jiGYK790.mjs} +1 -1
  159. package/.output/server/chunks/build/{useAmlEnv-JTiWPrzH.mjs.map → useAmlEnv-jiGYK790.mjs.map} +1 -1
  160. package/.output/server/chunks/build/{useAmlJobs-By4pjOzc.mjs → useAmlJobs-CVZ1btzg.mjs} +1 -1
  161. package/.output/server/chunks/build/{useAmlJobs-By4pjOzc.mjs.map → useAmlJobs-CVZ1btzg.mjs.map} +1 -1
  162. package/.output/server/chunks/build/{useAmlModels-B1_5vjMA.mjs → useAmlModels-DJkQzcCU.mjs} +1 -1
  163. package/.output/server/chunks/build/{useAmlModels-B1_5vjMA.mjs.map → useAmlModels-DJkQzcCU.mjs.map} +1 -1
  164. package/.output/server/chunks/build/{useAmlNotes-5uwvCb3h.mjs → useAmlNotes-DKnx9a8x.mjs} +1 -1
  165. package/.output/server/chunks/build/{useAmlNotes-5uwvCb3h.mjs.map → useAmlNotes-DKnx9a8x.mjs.map} +1 -1
  166. package/.output/server/chunks/build/{useAmlPredict-lxUv7lAO.mjs → useAmlPredict-Bp4ehwKw.mjs} +1 -1
  167. package/.output/server/chunks/build/{useAmlPredict-lxUv7lAO.mjs.map → useAmlPredict-Bp4ehwKw.mjs.map} +1 -1
  168. package/.output/server/chunks/build/{useLogsManual-BLfiSU3u.mjs → useLogsManual-CElmZuJh.mjs} +1 -1
  169. package/.output/server/chunks/build/{useLogsManual-BLfiSU3u.mjs.map → useLogsManual-CElmZuJh.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{useMonitorData-BZ6Z-Sy8.mjs → useMonitorData-DcIfMEiz.mjs} +1 -1
  171. package/.output/server/chunks/build/{useMonitorData-BZ6Z-Sy8.mjs.map → useMonitorData-DcIfMEiz.mjs.map} +1 -1
  172. package/.output/server/chunks/build/{useTeamActions-ahht5J8Y.mjs → useTeamActions-C3_O_AIU.mjs} +1 -1
  173. package/.output/server/chunks/build/{useTeamActions-ahht5J8Y.mjs.map → useTeamActions-C3_O_AIU.mjs.map} +1 -1
  174. package/.output/server/chunks/build/{useTeamAddMemberDialog-DvXxsVy0.mjs → useTeamAddMemberDialog-DWAoZCKd.mjs} +1 -1
  175. package/.output/server/chunks/build/{useTeamAddMemberDialog-DvXxsVy0.mjs.map → useTeamAddMemberDialog-DWAoZCKd.mjs.map} +1 -1
  176. package/.output/server/chunks/build/{useTeamCreateDialog-A_k-XX5B.mjs → useTeamCreateDialog-911mIPWd.mjs} +1 -1
  177. package/.output/server/chunks/build/{useTeamCreateDialog-A_k-XX5B.mjs.map → useTeamCreateDialog-911mIPWd.mjs.map} +1 -1
  178. package/.output/server/chunks/build/{useTeamDeployDialog-CfAFjIr_.mjs → useTeamDeployDialog-D0STROoQ.mjs} +1 -1
  179. package/.output/server/chunks/build/{useTeamDeployDialog-CfAFjIr_.mjs.map → useTeamDeployDialog-D0STROoQ.mjs.map} +1 -1
  180. package/.output/server/chunks/build/{useTeamPluginDialog-Djmkk1Nl.mjs → useTeamPluginDialog-Df6-e2OW.mjs} +1 -1
  181. package/.output/server/chunks/build/{useTeamPluginDialog-Djmkk1Nl.mjs.map → useTeamPluginDialog-Df6-e2OW.mjs.map} +1 -1
  182. package/.output/server/chunks/build/{useTokenCreate-CkWoxSI-.mjs → useTokenCreate-DOojAhM5.mjs} +1 -1
  183. package/.output/server/chunks/build/{useTokenCreate-CkWoxSI-.mjs.map → useTokenCreate-DOojAhM5.mjs.map} +1 -1
  184. package/.output/server/chunks/build/{useTokenRename-BohjnGT0.mjs → useTokenRename-CMA5dLHx.mjs} +1 -1
  185. package/.output/server/chunks/build/{useTokenRename-BohjnGT0.mjs.map → useTokenRename-CMA5dLHx.mjs.map} +1 -1
  186. package/.output/server/chunks/build/{useTokenReveal-BBN5iGz7.mjs → useTokenReveal-C19aCKzt.mjs} +1 -1
  187. package/.output/server/chunks/build/{useTokenReveal-BBN5iGz7.mjs.map → useTokenReveal-C19aCKzt.mjs.map} +1 -1
  188. package/.output/server/chunks/build/{useTokensList-BQX9WqfT.mjs → useTokensList-D0ZpLOhR.mjs} +1 -1
  189. package/.output/server/chunks/build/{useTokensList-BQX9WqfT.mjs.map → useTokensList-D0ZpLOhR.mjs.map} +1 -1
  190. package/.output/server/chunks/build/{useWorkbenchAuth-BTRlS2wZ.mjs → useWorkbenchAuth-CN5E3J5L.mjs} +1 -1
  191. package/.output/server/chunks/build/{useWorkbenchAuth-BTRlS2wZ.mjs.map → useWorkbenchAuth-CN5E3J5L.mjs.map} +1 -1
  192. package/.output/server/chunks/build/{useWorkbenchWorkspaces-C6ky7OJH.mjs → useWorkbenchWorkspaces-ChKByQSD.mjs} +1 -1
  193. package/.output/server/chunks/build/{useWorkbenchWorkspaces-C6ky7OJH.mjs.map → useWorkbenchWorkspaces-ChKByQSD.mjs.map} +1 -1
  194. package/.output/server/chunks/build/{users-BHOEW3Az.mjs → users-BW4jowK4.mjs} +15 -15
  195. package/.output/server/chunks/build/{users-BHOEW3Az.mjs.map → users-BW4jowK4.mjs.map} +1 -1
  196. package/.output/server/chunks/build/{workshop-DyJ1LXwu.mjs → workshop-Bx55czXL.mjs} +11 -11
  197. package/.output/server/chunks/build/{workshop-DyJ1LXwu.mjs.map → workshop-Bx55czXL.mjs.map} +1 -1
  198. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +3 -2
  199. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs.map +1 -1
  200. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +103 -0
  201. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs.map +1 -0
  202. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +6 -2
  226. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  227. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  233. package/.output/server/chunks/routes/renderer.mjs +2 -2
  234. package/.output/server/chunks/virtual/entry.mjs +533 -529
  235. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  236. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  237. package/.output/server/package.json +1 -1
  238. package/app/components/analysis/AnalysisEditModal.vue +192 -0
  239. package/app/components/analysis/AnalysisFilterCard.vue +159 -160
  240. package/app/components/analysis/AnalysisPageHead.vue +47 -47
  241. package/app/components/analysis/AnalysisTable.vue +322 -306
  242. package/app/pages/analysis/composables/useAnalysisFeed.ts +85 -85
  243. package/app/pages/analysis/index.vue +128 -92
  244. package/app/pages/analysis/types.ts +50 -44
  245. package/i18n/locales/en.ts +8 -0
  246. package/i18n/locales/zh-CN.ts +8 -0
  247. package/package.json +1 -1
  248. package/server/api/workshop/analysis/[id].delete.ts +30 -30
  249. package/server/api/workshop/analysis/[id].get.ts +25 -23
  250. package/server/api/workshop/analysis/[id].patch.ts +100 -0
  251. package/server/api/workshop/analysis/index.get.ts +39 -33
  252. package/server/services/workshop/agents/industrial/analysis-tools.ts +242 -242
  253. package/server/services/workshop/analysis/analysis.repo.ts +241 -189
  254. package/server/services/workshop/db/database/migrations.ts +10 -0
  255. package/server/services/workshop/db/database/open.ts +3 -1
  256. package/server/services/workshop/db/database/schema.ts +6 -2
  257. package/server/services/workshop/db/schema.sql +6 -2
  258. package/.output/public/_nuxt/5juo_WO2.js +0 -13
  259. package/.output/public/_nuxt/B-WTxXEK2.js +0 -1
  260. package/.output/public/_nuxt/B1BCga5h2.js +0 -13
  261. package/.output/public/_nuxt/B5lMtA7I2.js +0 -1
  262. package/.output/public/_nuxt/B6_fJd2X.js +0 -1
  263. package/.output/public/_nuxt/B7K5B04W2.js +0 -1
  264. package/.output/public/_nuxt/B7KyS_q2.js +0 -1
  265. package/.output/public/_nuxt/B8q3BGY5.js +0 -37
  266. package/.output/public/_nuxt/B9IK8kDl2.js +0 -1
  267. package/.output/public/_nuxt/BNd2NDxg2.js +0 -1
  268. package/.output/public/_nuxt/BP629NAi.js +0 -1
  269. package/.output/public/_nuxt/BVinTfuN.js +0 -1
  270. package/.output/public/_nuxt/BdE41Y_c.js +0 -28
  271. package/.output/public/_nuxt/Be_StT8b2.js +0 -1
  272. package/.output/public/_nuxt/BsYEYxWv.js +0 -24
  273. package/.output/public/_nuxt/BuNXYpib2.js +0 -1
  274. package/.output/public/_nuxt/CDaZC0_6.js +0 -3
  275. package/.output/public/_nuxt/CE43-V_L.js +0 -2
  276. package/.output/public/_nuxt/CWfBtswB.js +0 -70
  277. package/.output/public/_nuxt/CYtH1bv2.js +0 -1
  278. package/.output/public/_nuxt/ChPNKPw_.js +0 -1
  279. package/.output/public/_nuxt/CktUrk8z.js +0 -1
  280. package/.output/public/_nuxt/DMCoWgSb2.js +0 -1
  281. package/.output/public/_nuxt/Dg1iMuZ-.js +0 -1
  282. package/.output/public/_nuxt/DmwMkvoQ2.js +0 -1
  283. package/.output/public/_nuxt/LwITbamf2.js +0 -47
  284. package/.output/public/_nuxt/_jfzcYrl.js +0 -1
  285. package/.output/public/_nuxt/analysis.D2Pao1rm.css +0 -1
  286. package/.output/public/_nuxt/builds/meta/f78a1992-e424-494d-ac4b-aa18971ffc10.json +0 -1
  287. package/.output/server/chunks/build/analysis-tgzvOWmD.mjs +0 -332
  288. package/.output/server/chunks/build/analysis-tgzvOWmD.mjs.map +0 -1
@@ -1,242 +1,242 @@
1
- /**
2
- * 数据分析系统 · 分析报告留痕工具(analysis_save / analysis_query)。
3
- *
4
- * 定位:Agent Channel 把分析产出(关键结论/正文/支撑指标)持久化到平台台账,
5
- * 实现"分析结果可留痕、随时可查回"。台账 append-only —— 本族无更新/删除工具
6
- * (删仅 REST admin 面),保证留痕不可变。
7
- *
8
- * 权限语义(同族只读工具口径):
9
- * - 目标产线解析:显式 line_id(须在可见范围)→ 频道绑线兜底 → 都没有则拒。
10
- * - 可见产线 = 节点授权线 ∪ 绑定配方所在线 ∪ 频道绑线(agentOpsScope)。
11
- * - 不进 WRITE_TOOLS/grant-guard 写族:留痕是台账写入,非产线控制写;
12
- * 能读该产线数据(≥readonly)的 Agent 才能留痕。
13
- */
14
- import { randomUUID } from 'node:crypto'
15
- import { agentBadgeLabel } from '../agent-badge'
16
- import { getDcwController } from '../../dcw/dcw-controller'
17
- import { getDcwLineRepo } from '../../dcw/dcw-line.repo'
18
- import { recordOps } from '../../ops/ops'
19
- import { getAnalysisRepo } from '../../analysis/analysis.repo'
20
- import { agentOpsScope, channelBoundLineId, fmtAuditAt } from './ops-tools'
21
-
22
- export interface AnalysisSaveInput {
23
- title?: string
24
- summary?: string
25
- conclusions?: string[] | string
26
- report?: string
27
- category?: string
28
- line_id?: string
29
- recipe_id?: string
30
- recipe_version?: string
31
- window_from?: string
32
- window_to?: string
33
- data_sources?: string
34
- metrics?: Record<string, unknown>
35
- }
36
-
37
- export interface AnalysisQueryInput {
38
- report_id?: string
39
- line_id?: string
40
- recipe_id?: string
41
- category?: string
42
- q?: string
43
- from?: string
44
- to?: string
45
- limit?: number | string
46
- }
47
-
48
- /** 可见产线全集 = 节点授权线 ∪ 绑定配方所在线 ∪ 频道绑线(去重) */
49
- function readableLineIdsOf(agentId: string): string[] {
50
- const bound = channelBoundLineId(agentId)
51
- const scope = agentOpsScope(agentId)
52
- if (!scope) return bound ? [bound] : []
53
- return [...new Set([...scope.lineIds, ...scope.boundLineIds, ...(bound ? [bound] : [])])]
54
- }
55
-
56
- /** 目标产线解析:显式 line_id(须可读)→ 频道绑线兜底;返回产线视图或错误文案 */
57
- function resolveTargetLine(agentId: string, explicitLineId?: string): { lineId: string, lineName: string } | { error: string } {
58
- const lineRepo = getDcwLineRepo()
59
- const wanted = String(explicitLineId ?? '').trim() || channelBoundLineId(agentId)
60
- if (!wanted) {
61
- return { error: '无法确定目标产线:本频道未绑定产线,且未指定 line_id。请先绑线,或显式传入可见范围内的 line_id。' }
62
- }
63
- const line = lineRepo.byId(wanted)
64
- if (!line) return { error: `产线不存在: ${wanted}` }
65
- const readable = readableLineIdsOf(agentId)
66
- if (!readable.includes(wanted)) {
67
- return { error: `产线「${line.name}」不在你的可见范围(节点授权线/绑定配方线/频道绑线)。只能对可见产线留痕。` }
68
- }
69
- return { lineId: line.id, lineName: line.name }
70
- }
71
-
72
- /** 时间入参归一:epoch ms 数值串或 ISO 均收,统一出 ISO;无效返回 null(留空=未指明) */
73
- function normTimeArg(raw: unknown): string | null {
74
- const s = String(raw ?? '').trim()
75
- if (!s) return null
76
- if (/^\d{10,}$/.test(s)) {
77
- const ms = Number(s)
78
- return Number.isFinite(ms) ? new Date(ms).toISOString() : null
79
- }
80
- const t = Date.parse(s)
81
- return Number.isNaN(t) ? null : new Date(t).toISOString()
82
- }
83
-
84
- /** conclusions 归一:接受 string[] 或换行分隔的整段字符串(LLM 两种形态都常见) */
85
- function normConclusions(raw: AnalysisSaveInput['conclusions']): string[] {
86
- if (Array.isArray(raw)) return raw.map(x => String(x).trim()).filter(Boolean)
87
- return String(raw ?? '')
88
- .split('\n')
89
- .map(x => x.replace(/^[-*\d.\s]+/, '').trim())
90
- .filter(Boolean)
91
- }
92
-
93
- /** 频道名快照(归因用;经全局 manager 直读,未装配/直调上下文留空 —— 同 channelBoundLineId 模式) */
94
- function channelNameOf(channelId?: string): string {
95
- if (!channelId) return ''
96
- try {
97
- const g = globalThis as typeof globalThis & {
98
- __workshopManager?: { deps: { repos: { channels: { findById(id: string): { name?: string } | undefined } } } }
99
- }
100
- return g.__workshopManager?.deps.repos.channels.findById(channelId)?.name ?? ''
101
- }
102
- catch {
103
- return ''
104
- }
105
- }
106
-
107
- /** 产线上下文快照:保存瞬间把产品/批次/控制模式固化进台账 */
108
- function lineContextSnapshot(lineId: string): Record<string, unknown> {
109
- try {
110
- const ctrl = getDcwController()
111
- const st = ctrl.lineState(lineId)
112
- const line = getDcwLineRepo().byId(lineId)
113
- return {
114
- controlMode: line?.controlMode ?? '',
115
- activeRun: st?.active
116
- ? { runId: st.runId, recipeName: st.recipeName, productName: st.productName, startedAt: st.startedAt }
117
- : null,
118
- }
119
- }
120
- catch {
121
- return {}
122
- }
123
- }
124
-
125
- /** 工具:analysis_save —— 把本次分析的关键结论与产出持久化到平台分析台账(数据留痕)。 */
126
- export async function toolAnalysisSave(agentId: string, args: AnalysisSaveInput, channelId?: string): Promise<{ text: string, isError?: boolean }> {
127
- const title = String(args.title ?? '').trim()
128
- const summary = String(args.summary ?? '').trim()
129
- if (!title) return { text: 'title 必填:分析主题(如「BOPET 线膜厚漂移根因分析」),台账列表靠它辨认。', isError: true }
130
- if (!summary) return { text: 'summary 必填:一句话关键结论 —— 这是留痕的核心产出,人扫一眼列表要能看懂。', isError: true }
131
-
132
- const line = resolveTargetLine(agentId, args.line_id)
133
- if ('error' in line) return { text: line.error, isError: true }
134
-
135
- // 配方联动:校验存在性 + 归属(留痕的 recipe 字段要可信)
136
- const recipeId = String(args.recipe_id ?? '').trim()
137
- let recipeVersion = String(args.recipe_version ?? '').trim()
138
- if (recipeId) {
139
- const recipe = getDcwController().listRecipes().find(r => r.id === recipeId)
140
- if (!recipe) return { text: `配方 ${recipeId} 不存在,recipe_id 留痕被拒(可用 line_context 查看当前配方)。`, isError: true }
141
- if (recipe.lineId && recipe.lineId !== line.lineId) {
142
- return { text: `配方「${recipe.name}」不属于产线「${line.lineName}」,不能挂到该线的分析报告下。`, isError: true }
143
- }
144
- if (!recipeVersion) recipeVersion = String(recipe.version ?? '')
145
- }
146
-
147
- const channelName = channelNameOf(channelId)
148
- const id = `ar-${randomUUID().replace(/-/g, '').slice(0, 8)}`
149
- const now = new Date().toISOString()
150
- const conclusions = normConclusions(args.conclusions)
151
- const windowFrom = normTimeArg(args.window_from)
152
- const windowTo = normTimeArg(args.window_to)
153
-
154
- getAnalysisRepo().insert({
155
- id,
156
- lineId: line.lineId,
157
- lineName: line.lineName,
158
- title,
159
- category: String(args.category ?? '').trim() || 'general',
160
- summary,
161
- conclusions,
162
- report: String(args.report ?? ''),
163
- metrics: (args.metrics && typeof args.metrics === 'object' && !Array.isArray(args.metrics) ? args.metrics : {}) as Record<string, unknown>,
164
- recipeId,
165
- recipeVersion,
166
- windowFrom,
167
- windowTo,
168
- dataSources: String(args.data_sources ?? ''),
169
- context: lineContextSnapshot(line.lineId),
170
- channelId: channelId ?? '',
171
- channelName,
172
- actor: agentId,
173
- actorName: agentBadgeLabel(agentId),
174
- createdAt: now,
175
- })
176
-
177
- try {
178
- recordOps({
179
- actor: agentId, actorName: agentBadgeLabel(agentId), actorKind: 'agent',
180
- action: 'analysis.save', kind: 'analysis', targetKind: 'analysis', targetId: id,
181
- lineId: line.lineId, recipeId,
182
- summary: `Agent 留痕分析报告「${title}」:产线「${line.lineName}」${recipeId ? `,配方 ${recipeId}` : ''} — ${summary}`,
183
- })
184
- }
185
- catch { /* 审计失败不影响留痕 */ }
186
-
187
- const win = windowFrom || windowTo ? `(数据窗 ${windowFrom ?? '?'} ~ ${windowTo ?? '?'})` : ''
188
- return { text: `分析报告已留痕:${id}。产线「${line.lineName}」${win},结论 ${conclusions.length} 条,配方 ${recipeId || '未关联'}。台账 append-only,不可改删;随时可用 analysis_query(report_id="${id}") 查回全文。` }
189
- }
190
-
191
- /** 工具:analysis_query —— 查询历史分析报告(report_id 精确查全文;或按线/配方/时间/关键词列表)。 */
192
- export async function toolAnalysisQuery(agentId: string, args: AnalysisQueryInput): Promise<{ text: string, isError?: boolean }> {
193
- const readable = readableLineIdsOf(agentId)
194
- const reportId = String(args.report_id ?? '').trim()
195
- const repo = getAnalysisRepo()
196
-
197
- if (reportId) {
198
- const report = repo.get(reportId)
199
- if (!report) return { text: `分析报告不存在: ${reportId}(留痕不可变,也没有删除找回;请核对 id)。`, isError: true }
200
- if (report.lineId && !readable.includes(report.lineId)) {
201
- return { text: `分析报告 ${reportId} 属于产线「${report.lineName}」,不在你的可见范围。`, isError: true }
202
- }
203
- const head = [
204
- `分析报告 ${report.id}:「${report.title}」(分类 ${report.category})`,
205
- `产线: ${report.lineName || report.lineId || '-'} | 配方: ${report.recipeId || '-'}${report.recipeVersion ? ` v${report.recipeVersion}` : ''}`,
206
- `分析时间: ${fmtAuditAt(report.createdAt)} | 数据窗: ${report.windowFrom ? fmtAuditAt(report.windowFrom) : '-'} ~ ${report.windowTo ? fmtAuditAt(report.windowTo) : '-'}`,
207
- `来源: ${report.actorName || report.actor}${report.channelName ? ` @频道「${report.channelName}」` : ''}`,
208
- `关键结论: ${report.summary}`,
209
- ...(report.conclusions.length ? [`结论明细:\n${report.conclusions.map((c, i) => ` ${i + 1}. ${c}`).join('\n')}`] : []),
210
- ]
211
- const body = report.report ? `\n\n— 完整分析正文 —\n${report.report}` : ''
212
- const metrics = Object.keys(report.metrics ?? {}).length ? `\n\n— 支撑指标 —\n${JSON.stringify(report.metrics, null, 1)}` : ''
213
- return { text: `${head.join('\n')}${body}${metrics}` }
214
- }
215
-
216
- const explicitLine = String(args.line_id ?? '').trim()
217
- if (explicitLine && !readable.includes(explicitLine)) {
218
- return { text: `产线 ${explicitLine} 不在你的可见范围(节点授权线/绑定配方线/频道绑线)。`, isError: true }
219
- }
220
- // 作用域空集 = 不可见任何产线 → 直接空结果,不得落成"不过滤"(防越权列举全量台账)
221
- if (!explicitLine && readable.length === 0) {
222
- return { text: '你当前没有任何可见产线(无节点授权、无绑定配方、频道未绑线),暂无可查的分析报告。' }
223
- }
224
- const rows = repo.list({
225
- lineId: explicitLine || undefined,
226
- lineIds: explicitLine ? undefined : readable,
227
- recipeId: String(args.recipe_id ?? '').trim() || undefined,
228
- category: String(args.category ?? '').trim() || undefined,
229
- q: String(args.q ?? '').trim() || undefined,
230
- from: normTimeArg(args.from) ?? undefined,
231
- to: normTimeArg(args.to) ?? undefined,
232
- limit: Math.min(50, Math.max(1, Number(args.limit) || 20)),
233
- })
234
- if (rows.length === 0) {
235
- return { text: `可见范围内暂无匹配的分析报告${args.q ? `(关键词「${String(args.q)}」)` : ''}。留痕由各频道的 analysis_save 产生;若是刚分析完,确认保存工具已被调用。` }
236
- }
237
- const lines = rows.map((r) => {
238
- const recipe = r.recipeId ? ` | 配方 ${r.recipeId}${r.recipeVersion ? ` v${r.recipeVersion}` : ''}` : ''
239
- return `[${r.id}] ${fmtAuditAt(r.createdAt)} | ${r.lineName || r.lineId || '-'}${recipe} | ${r.title}(${r.category})\n ${r.summary} —— ${r.actorName || r.actor}${r.channelName ? ` @「${r.channelName}」` : ''}`
240
- })
241
- return { text: `共 ${rows.length} 条分析报告(新→旧):\n${lines.join('\n')}\n\n用 analysis_query(report_id="ar-xxxx") 查看单条完整正文与结论明细。` }
242
- }
1
+ /**
2
+ * 数据分析系统 · 分析报告留痕工具(analysis_save / analysis_query)。
3
+ *
4
+ * 定位:Agent Channel 把分析产出(关键结论/正文/支撑指标)持久化到平台台账,
5
+ * 实现"分析结果可留痕、随时可查回"。台账 append-only —— 本族无更新/删除工具
6
+ * (删仅 REST admin 面),保证留痕不可变。
7
+ *
8
+ * 权限语义(同族只读工具口径):
9
+ * - 目标产线解析:显式 line_id(须在可见范围)→ 频道绑线兜底 → 都没有则拒。
10
+ * - 可见产线 = 节点授权线 ∪ 绑定配方所在线 ∪ 频道绑线(agentOpsScope)。
11
+ * - 不进 WRITE_TOOLS/grant-guard 写族:留痕是台账写入,非产线控制写;
12
+ * 能读该产线数据(≥readonly)的 Agent 才能留痕。
13
+ */
14
+ import { randomUUID } from 'node:crypto'
15
+ import { agentBadgeLabel } from '../agent-badge'
16
+ import { getDcwController } from '../../dcw/dcw-controller'
17
+ import { getDcwLineRepo } from '../../dcw/dcw-line.repo'
18
+ import { recordOps } from '../../ops/ops'
19
+ import { getAnalysisRepo } from '../../analysis/analysis.repo'
20
+ import { agentOpsScope, channelBoundLineId, fmtAuditAt } from './ops-tools'
21
+
22
+ export interface AnalysisSaveInput {
23
+ title?: string
24
+ summary?: string
25
+ conclusions?: string[] | string
26
+ report?: string
27
+ category?: string
28
+ line_id?: string
29
+ recipe_id?: string
30
+ recipe_version?: string
31
+ window_from?: string
32
+ window_to?: string
33
+ data_sources?: string
34
+ metrics?: Record<string, unknown>
35
+ }
36
+
37
+ export interface AnalysisQueryInput {
38
+ report_id?: string
39
+ line_id?: string
40
+ recipe_id?: string
41
+ category?: string
42
+ q?: string
43
+ from?: string
44
+ to?: string
45
+ limit?: number | string
46
+ }
47
+
48
+ /** 可见产线全集 = 节点授权线 ∪ 绑定配方所在线 ∪ 频道绑线(去重) */
49
+ function readableLineIdsOf(agentId: string): string[] {
50
+ const bound = channelBoundLineId(agentId)
51
+ const scope = agentOpsScope(agentId)
52
+ if (!scope) return bound ? [bound] : []
53
+ return [...new Set([...scope.lineIds, ...scope.boundLineIds, ...(bound ? [bound] : [])])]
54
+ }
55
+
56
+ /** 目标产线解析:显式 line_id(须可读)→ 频道绑线兜底;返回产线视图或错误文案 */
57
+ function resolveTargetLine(agentId: string, explicitLineId?: string): { lineId: string, lineName: string } | { error: string } {
58
+ const lineRepo = getDcwLineRepo()
59
+ const wanted = String(explicitLineId ?? '').trim() || channelBoundLineId(agentId)
60
+ if (!wanted) {
61
+ return { error: '无法确定目标产线:本频道未绑定产线,且未指定 line_id。请先绑线,或显式传入可见范围内的 line_id。' }
62
+ }
63
+ const line = lineRepo.byId(wanted)
64
+ if (!line) return { error: `产线不存在: ${wanted}` }
65
+ const readable = readableLineIdsOf(agentId)
66
+ if (!readable.includes(wanted)) {
67
+ return { error: `产线「${line.name}」不在你的可见范围(节点授权线/绑定配方线/频道绑线)。只能对可见产线留痕。` }
68
+ }
69
+ return { lineId: line.id, lineName: line.name }
70
+ }
71
+
72
+ /** 时间入参归一:epoch ms 数值串或 ISO 均收,统一出 ISO;无效返回 null(留空=未指明) */
73
+ function normTimeArg(raw: unknown): string | null {
74
+ const s = String(raw ?? '').trim()
75
+ if (!s) return null
76
+ if (/^\d{10,}$/.test(s)) {
77
+ const ms = Number(s)
78
+ return Number.isFinite(ms) ? new Date(ms).toISOString() : null
79
+ }
80
+ const t = Date.parse(s)
81
+ return Number.isNaN(t) ? null : new Date(t).toISOString()
82
+ }
83
+
84
+ /** conclusions 归一:接受 string[] 或换行分隔的整段字符串(LLM 两种形态都常见) */
85
+ function normConclusions(raw: AnalysisSaveInput['conclusions']): string[] {
86
+ if (Array.isArray(raw)) return raw.map(x => String(x).trim()).filter(Boolean)
87
+ return String(raw ?? '')
88
+ .split('\n')
89
+ .map(x => x.replace(/^[-*\d.\s]+/, '').trim())
90
+ .filter(Boolean)
91
+ }
92
+
93
+ /** 频道名快照(归因用;经全局 manager 直读,未装配/直调上下文留空 —— 同 channelBoundLineId 模式) */
94
+ function channelNameOf(channelId?: string): string {
95
+ if (!channelId) return ''
96
+ try {
97
+ const g = globalThis as typeof globalThis & {
98
+ __workshopManager?: { deps: { repos: { channels: { findById(id: string): { name?: string } | undefined } } } }
99
+ }
100
+ return g.__workshopManager?.deps.repos.channels.findById(channelId)?.name ?? ''
101
+ }
102
+ catch {
103
+ return ''
104
+ }
105
+ }
106
+
107
+ /** 产线上下文快照:保存瞬间把产品/批次/控制模式固化进台账 */
108
+ function lineContextSnapshot(lineId: string): Record<string, unknown> {
109
+ try {
110
+ const ctrl = getDcwController()
111
+ const st = ctrl.lineState(lineId)
112
+ const line = getDcwLineRepo().byId(lineId)
113
+ return {
114
+ controlMode: line?.controlMode ?? '',
115
+ activeRun: st?.active
116
+ ? { runId: st.runId, recipeName: st.recipeName, productName: st.productName, startedAt: st.startedAt }
117
+ : null,
118
+ }
119
+ }
120
+ catch {
121
+ return {}
122
+ }
123
+ }
124
+
125
+ /** 工具:analysis_save —— 把本次分析的关键结论与产出持久化到平台分析台账(数据留痕)。 */
126
+ export async function toolAnalysisSave(agentId: string, args: AnalysisSaveInput, channelId?: string): Promise<{ text: string, isError?: boolean }> {
127
+ const title = String(args.title ?? '').trim()
128
+ const summary = String(args.summary ?? '').trim()
129
+ if (!title) return { text: 'title 必填:分析主题(如「BOPET 线膜厚漂移根因分析」),台账列表靠它辨认。', isError: true }
130
+ if (!summary) return { text: 'summary 必填:一句话关键结论 —— 这是留痕的核心产出,人扫一眼列表要能看懂。', isError: true }
131
+
132
+ const line = resolveTargetLine(agentId, args.line_id)
133
+ if ('error' in line) return { text: line.error, isError: true }
134
+
135
+ // 配方联动:校验存在性 + 归属(留痕的 recipe 字段要可信)
136
+ const recipeId = String(args.recipe_id ?? '').trim()
137
+ let recipeVersion = String(args.recipe_version ?? '').trim()
138
+ if (recipeId) {
139
+ const recipe = getDcwController().listRecipes().find(r => r.id === recipeId)
140
+ if (!recipe) return { text: `配方 ${recipeId} 不存在,recipe_id 留痕被拒(可用 line_context 查看当前配方)。`, isError: true }
141
+ if (recipe.lineId && recipe.lineId !== line.lineId) {
142
+ return { text: `配方「${recipe.name}」不属于产线「${line.lineName}」,不能挂到该线的分析报告下。`, isError: true }
143
+ }
144
+ if (!recipeVersion) recipeVersion = String(recipe.version ?? '')
145
+ }
146
+
147
+ const channelName = channelNameOf(channelId)
148
+ const id = `ar-${randomUUID().replace(/-/g, '').slice(0, 8)}`
149
+ const now = new Date().toISOString()
150
+ const conclusions = normConclusions(args.conclusions)
151
+ const windowFrom = normTimeArg(args.window_from)
152
+ const windowTo = normTimeArg(args.window_to)
153
+
154
+ getAnalysisRepo().insert({
155
+ id,
156
+ lineId: line.lineId,
157
+ lineName: line.lineName,
158
+ title,
159
+ category: String(args.category ?? '').trim() || 'general',
160
+ summary,
161
+ conclusions,
162
+ report: String(args.report ?? ''),
163
+ metrics: (args.metrics && typeof args.metrics === 'object' && !Array.isArray(args.metrics) ? args.metrics : {}) as Record<string, unknown>,
164
+ recipeId,
165
+ recipeVersion,
166
+ windowFrom,
167
+ windowTo,
168
+ dataSources: String(args.data_sources ?? ''),
169
+ context: lineContextSnapshot(line.lineId),
170
+ channelId: channelId ?? '',
171
+ channelName,
172
+ actor: agentId,
173
+ actorName: agentBadgeLabel(agentId),
174
+ createdAt: now,
175
+ })
176
+
177
+ try {
178
+ recordOps({
179
+ actor: agentId, actorName: agentBadgeLabel(agentId), actorKind: 'agent',
180
+ action: 'analysis.save', kind: 'analysis', targetKind: 'analysis', targetId: id,
181
+ lineId: line.lineId, recipeId,
182
+ summary: `Agent 留痕分析报告「${title}」:产线「${line.lineName}」${recipeId ? `,配方 ${recipeId}` : ''} — ${summary}`,
183
+ })
184
+ }
185
+ catch { /* 审计失败不影响留痕 */ }
186
+
187
+ const win = windowFrom || windowTo ? `(数据窗 ${windowFrom ?? '?'} ~ ${windowTo ?? '?'})` : ''
188
+ return { text: `分析报告已留痕:${id}。产线「${line.lineName}」${win},结论 ${conclusions.length} 条,配方 ${recipeId || '未关联'}。台账 append-only,不可改删;随时可用 analysis_query(report_id="${id}") 查回全文。` }
189
+ }
190
+
191
+ /** 工具:analysis_query —— 查询历史分析报告(report_id 精确查全文;或按线/配方/时间/关键词列表)。 */
192
+ export async function toolAnalysisQuery(agentId: string, args: AnalysisQueryInput): Promise<{ text: string, isError?: boolean }> {
193
+ const readable = readableLineIdsOf(agentId)
194
+ const reportId = String(args.report_id ?? '').trim()
195
+ const repo = getAnalysisRepo()
196
+
197
+ if (reportId) {
198
+ const report = repo.get(reportId)
199
+ if (!report) return { text: `分析报告不存在: ${reportId}(留痕不可变,也没有删除找回;请核对 id)。`, isError: true }
200
+ if (report.lineId && !readable.includes(report.lineId)) {
201
+ return { text: `分析报告 ${reportId} 属于产线「${report.lineName}」,不在你的可见范围。`, isError: true }
202
+ }
203
+ const head = [
204
+ `分析报告 ${report.id}:「${report.title}」(分类 ${report.category})`,
205
+ `产线: ${report.lineName || report.lineId || '-'} | 配方: ${report.recipeId || '-'}${report.recipeVersion ? ` v${report.recipeVersion}` : ''}`,
206
+ `分析时间: ${fmtAuditAt(report.createdAt)} | 数据窗: ${report.windowFrom ? fmtAuditAt(report.windowFrom) : '-'} ~ ${report.windowTo ? fmtAuditAt(report.windowTo) : '-'}`,
207
+ `来源: ${report.actorName || report.actor}${report.channelName ? ` @频道「${report.channelName}」` : ''}`,
208
+ `关键结论: ${report.summary}`,
209
+ ...(report.conclusions.length ? [`结论明细:\n${report.conclusions.map((c, i) => ` ${i + 1}. ${c}`).join('\n')}`] : []),
210
+ ]
211
+ const body = report.report ? `\n\n— 完整分析正文 —\n${report.report}` : ''
212
+ const metrics = Object.keys(report.metrics ?? {}).length ? `\n\n— 支撑指标 —\n${JSON.stringify(report.metrics, null, 1)}` : ''
213
+ return { text: `${head.join('\n')}${body}${metrics}` }
214
+ }
215
+
216
+ const explicitLine = String(args.line_id ?? '').trim()
217
+ if (explicitLine && !readable.includes(explicitLine)) {
218
+ return { text: `产线 ${explicitLine} 不在你的可见范围(节点授权线/绑定配方线/频道绑线)。`, isError: true }
219
+ }
220
+ // 作用域空集 = 不可见任何产线 → 直接空结果,不得落成"不过滤"(防越权列举全量台账)
221
+ if (!explicitLine && readable.length === 0) {
222
+ return { text: '你当前没有任何可见产线(无节点授权、无绑定配方、频道未绑线),暂无可查的分析报告。' }
223
+ }
224
+ const rows = repo.list({
225
+ lineId: explicitLine || undefined,
226
+ lineIds: explicitLine ? undefined : readable,
227
+ recipeId: String(args.recipe_id ?? '').trim() || undefined,
228
+ category: String(args.category ?? '').trim() || undefined,
229
+ q: String(args.q ?? '').trim() || undefined,
230
+ from: normTimeArg(args.from) ?? undefined,
231
+ to: normTimeArg(args.to) ?? undefined,
232
+ limit: Math.min(50, Math.max(1, Number(args.limit) || 20)),
233
+ })
234
+ if (rows.length === 0) {
235
+ return { text: `可见范围内暂无匹配的分析报告${args.q ? `(关键词「${String(args.q)}」)` : ''}。留痕由各频道的 analysis_save 产生;若是刚分析完,确认保存工具已被调用。` }
236
+ }
237
+ const lines = rows.map((r) => {
238
+ const recipe = r.recipeId ? ` | 配方 ${r.recipeId}${r.recipeVersion ? ` v${r.recipeVersion}` : ''}` : ''
239
+ return `[${r.id}] ${fmtAuditAt(r.createdAt)} | ${r.lineName || r.lineId || '-'}${recipe} | ${r.title}(${r.category})\n ${r.summary} —— ${r.actorName || r.actor}${r.channelName ? ` @「${r.channelName}」` : ''}`
240
+ })
241
+ return { text: `共 ${rows.length} 条分析报告(新→旧):\n${lines.join('\n')}\n\n用 analysis_query(report_id="ar-xxxx") 查看单条完整正文与结论明细。` }
242
+ }