agentworkshop 0.7.60 → 0.7.62

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 (292) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +1 -1
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +1 -1
  3. package/.output/nitro.json +1 -1
  4. package/.output/public/_nuxt/B5RD2ZST.js +2 -0
  5. package/.output/public/_nuxt/{KXQppTXc.js → BTXdYngG.js} +1 -1
  6. package/.output/public/_nuxt/{Ce5SiMQR2.js → BXbKTAwC2.js} +1 -1
  7. package/.output/public/_nuxt/B_6yBa_Z.js +1 -0
  8. package/.output/public/_nuxt/B_ic601Y.js +1 -0
  9. package/.output/public/_nuxt/{DhSlJyZD2.js → BegV7-FE2.js} +1 -1
  10. package/.output/public/_nuxt/{D9sgxxsM2.js → BrRXGr472.js} +1 -1
  11. package/.output/public/_nuxt/{BeNdseTX.js → BtBgrPNT.js} +1 -1
  12. package/.output/public/_nuxt/{Cyd68Xbv2.js → C5MPzgon2.js} +1 -1
  13. package/.output/public/_nuxt/{DBdwjOGB2.js → CI5sliIF2.js} +1 -1
  14. package/.output/public/_nuxt/CI8awYVQ2.js +1 -0
  15. package/.output/public/_nuxt/{Cfp00Rdo.js → CK2ts9sD.js} +1 -1
  16. package/.output/public/_nuxt/{BjUpWKS6.js → CPZKwmLQ.js} +1 -1
  17. package/.output/public/_nuxt/{CjeMxUv8.js → CVUMEGa1.js} +1 -1
  18. package/.output/public/_nuxt/{p2sDc0tO2.js → CcLFZjCI2.js} +1 -1
  19. package/.output/public/_nuxt/{C93LpBMF.js → CfIGBe_4.js} +3 -3
  20. package/.output/public/_nuxt/{DTcsb0fG.js → Ci5kuU1q.js} +1 -1
  21. package/.output/public/_nuxt/CiyTTgqr.js +106 -0
  22. package/.output/public/_nuxt/{CgbP5yJk2.js → CkYk8bj02.js} +7 -7
  23. package/.output/public/_nuxt/Cmiz_VOb2.js +47 -0
  24. package/.output/public/_nuxt/Cnf1PFhB2.js +1 -0
  25. package/.output/public/_nuxt/CoTm7jd3.js +28 -0
  26. package/.output/public/_nuxt/{C0sNwDTK2.js → CsN8RHJ02.js} +1 -1
  27. package/.output/public/_nuxt/D-jg-SoR.js +1 -0
  28. package/.output/public/_nuxt/{CEHT9inW.js → D-z6N1Cz.js} +1 -1
  29. package/.output/public/_nuxt/D3gfSKKi2.js +1 -0
  30. package/.output/public/_nuxt/D4elH6Bo2.js +1 -0
  31. package/.output/public/_nuxt/{C5OSTzBh.js → D4tAdwYm.js} +1 -1
  32. package/.output/public/_nuxt/{C4AICl3l.js → DAfWhONg.js} +4 -4
  33. package/.output/public/_nuxt/{BlEJRYAn2.js → DC7WzYCf2.js} +1 -1
  34. package/.output/public/_nuxt/{VeOVO2sE2.js → DE-qkHRd2.js} +1 -1
  35. package/.output/public/_nuxt/DE2kUGPK.js +1 -0
  36. package/.output/public/_nuxt/DI4sdLmu2.js +1 -0
  37. package/.output/public/_nuxt/{zVupTo2z2.js → DL6fliAT.js} +2 -2
  38. package/.output/public/_nuxt/{CMDAjShv2.js → DP6tsk912.js} +1 -1
  39. package/.output/public/_nuxt/DP_e7Vwv.js +24 -0
  40. package/.output/public/_nuxt/{C8XVZGSZ.js → DR83EvmX.js} +1 -1
  41. package/.output/public/_nuxt/{BtXwFpv42.js → DSWuWYx_2.js} +1 -1
  42. package/.output/public/_nuxt/DSdxfFX_.js +1 -0
  43. package/.output/public/_nuxt/DVS06wUy2.js +13 -0
  44. package/.output/public/_nuxt/DXlAfhEi.js +3 -0
  45. package/.output/public/_nuxt/Dc5NeCDq.js +1 -0
  46. package/.output/public/_nuxt/{B_JLVF30.js → DiHL9ehB.js} +1 -1
  47. package/.output/public/_nuxt/{Bdq2LNSO.js → DjtDexGg.js} +1 -1
  48. package/.output/public/_nuxt/DnunMTRD2.js +1 -0
  49. package/.output/public/_nuxt/{KXvRkBgg.js → Dok0B4Ol.js} +2 -2
  50. package/.output/public/_nuxt/{BFBysc2M2.js → DqT2_Jtw2.js} +1 -1
  51. package/.output/public/_nuxt/{B_BYwIf22.js → DtMlAxCm2.js} +1 -1
  52. package/.output/public/_nuxt/{BplhglEM.js → DwzJpr7P.js} +1 -1
  53. package/.output/public/_nuxt/J94L7hHq2.js +1 -0
  54. package/.output/public/_nuxt/LQBLwrYS2.js +1 -0
  55. package/.output/public/_nuxt/QSY9fE482.js +1 -0
  56. package/.output/public/_nuxt/{iCvdSYYN2.js → Qa9rS9oK2.js} +2 -2
  57. package/.output/public/_nuxt/{Cyuxcv5s2.js → R3gBFghJ2.js} +1 -1
  58. package/.output/public/_nuxt/ZxBwmbs9.js +1 -0
  59. package/.output/public/_nuxt/{BGFhOMVM.js → _mD4IkJj.js} +2 -2
  60. package/.output/public/_nuxt/analysis.BwhKdel9.css +1 -0
  61. package/.output/public/_nuxt/builds/latest.json +1 -1
  62. package/.output/public/_nuxt/builds/meta/603a62a6-71d7-4d9c-bb1d-e8264a58798e.json +1 -0
  63. package/.output/public/_nuxt/{CZmMgjIK.js → c_nqArmG.js} +1 -1
  64. package/.output/public/_nuxt/h8ddxY892.js +1 -0
  65. package/.output/public/_nuxt/i3KBHle7.js +1 -0
  66. package/.output/public/_nuxt/jmKfTQMN.js +13 -0
  67. package/.output/public/_nuxt/{59a6cSgj.js → taHLOXkS.js} +1 -1
  68. package/.output/public/_nuxt/{EQijmkCh2.js → uYP6z4G72.js} +1 -1
  69. package/.output/public/_nuxt/{D0vmf1z9.js → yuIP6K9s.js} +1 -1
  70. package/.output/public/_nuxt/{Ddc_Pn7D.js → zWg-9WN6.js} +4 -4
  71. package/.output/public/_nuxt/zrgcKVTq.js +2 -0
  72. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  73. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  74. package/.output/server/chunks/_/nitro.mjs +2444 -2394
  75. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  76. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  77. package/.output/server/chunks/build/{AuthGate-CZYkvPrg.mjs → AuthGate-BK2RqkbD.mjs} +5 -5
  78. package/.output/server/chunks/build/{AuthGate-CZYkvPrg.mjs.map → AuthGate-BK2RqkbD.mjs.map} +1 -1
  79. package/.output/server/chunks/build/{FormItemContext-DcWIIAaK.mjs → FormItemContext-BqtgOBDe.mjs} +1 -1
  80. package/.output/server/chunks/build/{FormItemContext-DcWIIAaK.mjs.map → FormItemContext-BqtgOBDe.mjs.map} +1 -1
  81. package/.output/server/chunks/build/{OmpTerminalPanel-CtFJ6Kc8.mjs → OmpTerminalPanel-Bun6rpAk.mjs} +4 -4
  82. package/.output/server/chunks/build/{OmpTerminalPanel-CtFJ6Kc8.mjs.map → OmpTerminalPanel-Bun6rpAk.mjs.map} +1 -1
  83. package/.output/server/chunks/build/{PluginSlot-BT7kYQgK.mjs → PluginSlot-Do6dX0RE.mjs} +1 -1
  84. package/.output/server/chunks/build/{PluginSlot-BT7kYQgK.mjs.map → PluginSlot-Do6dX0RE.mjs.map} +1 -1
  85. package/.output/server/chunks/build/{_wsId_-DOEw9jgZ.mjs → _wsId_-Dp3ACbQ5.mjs} +19 -19
  86. package/.output/server/chunks/build/{_wsId_-DOEw9jgZ.mjs.map → _wsId_-Dp3ACbQ5.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{agents-C36wR56A.mjs → agents-BfIoGr_p.mjs} +18 -18
  88. package/.output/server/chunks/build/{agents-C36wR56A.mjs.map → agents-BfIoGr_p.mjs.map} +1 -1
  89. package/.output/server/chunks/build/{aml-CBGndvHT.mjs → aml-B5zKrvB3.mjs} +7 -7
  90. package/.output/server/chunks/build/{aml-CBGndvHT.mjs.map → aml-B5zKrvB3.mjs.map} +1 -1
  91. package/.output/server/chunks/build/analysis-CPIxT0FP.mjs +531 -0
  92. package/.output/server/chunks/build/analysis-CPIxT0FP.mjs.map +1 -0
  93. package/.output/server/chunks/build/{card-Db7OB49d.mjs → card-IyQjdGXA.mjs} +3 -3
  94. package/.output/server/chunks/build/{card-Db7OB49d.mjs.map → card-IyQjdGXA.mjs.map} +1 -1
  95. package/.output/server/chunks/build/{channel-templates-BixUrDmU.mjs → channel-templates-Bd8bgBCh.mjs} +11 -11
  96. package/.output/server/chunks/build/{channel-templates-BixUrDmU.mjs.map → channel-templates-Bd8bgBCh.mjs.map} +1 -1
  97. package/.output/server/chunks/build/{checkbox-CyF96D30.mjs → checkbox-NnjtOam0.mjs} +2 -2
  98. package/.output/server/chunks/build/{checkbox-CyF96D30.mjs.map → checkbox-NnjtOam0.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{daq-DLMLufDq.mjs → daq-mC3-5A0L.mjs} +1 -1
  100. package/.output/server/chunks/build/{daq-DLMLufDq.mjs.map → daq-mC3-5A0L.mjs.map} +1 -1
  101. package/.output/server/chunks/build/{default-C7Qmdyz_.mjs → default-flcNWlNg.mjs} +12 -12
  102. package/.output/server/chunks/build/{default-C7Qmdyz_.mjs.map → default-flcNWlNg.mjs.map} +1 -1
  103. package/.output/server/chunks/build/{descriptions-1bH81YsZ.mjs → descriptions-DuAefuzp.mjs} +1 -1
  104. package/.output/server/chunks/build/{descriptions-1bH81YsZ.mjs.map → descriptions-DuAefuzp.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{drawer-C7shdEHy.mjs → drawer-DEIB1_X6.mjs} +1 -1
  106. package/.output/server/chunks/build/{drawer-C7shdEHy.mjs.map → drawer-DEIB1_X6.mjs.map} +1 -1
  107. package/.output/server/chunks/build/{dropdown-BiwcuXDi.mjs → dropdown-BuD1pxH2.mjs} +5 -5
  108. package/.output/server/chunks/build/{dropdown-BiwcuXDi.mjs.map → dropdown-BuD1pxH2.mjs.map} +1 -1
  109. package/.output/server/chunks/build/{dropdown-BhLSIp5A.mjs → dropdown-w7qhyN2D.mjs} +2 -2
  110. package/.output/server/chunks/build/{dropdown-BhLSIp5A.mjs.map → dropdown-w7qhyN2D.mjs.map} +1 -1
  111. package/.output/server/chunks/build/es-DfgEl5n-.mjs +42 -0
  112. package/.output/server/chunks/build/es-DfgEl5n-.mjs.map +1 -0
  113. package/.output/server/chunks/build/{form-nE8C0G8B.mjs → form-CMLL_-Xx.mjs} +6 -6
  114. package/.output/server/chunks/build/{form-nE8C0G8B.mjs.map → form-CMLL_-Xx.mjs.map} +1 -1
  115. package/.output/server/chunks/build/{input-DwF72eVI.mjs → input-DZcioTwL.mjs} +3 -3
  116. package/.output/server/chunks/build/{input-DwF72eVI.mjs.map → input-DZcioTwL.mjs.map} +1 -1
  117. package/.output/server/chunks/build/{input-number-TSq6ltkz.mjs → input-number-BRnbiKLd.mjs} +5 -5
  118. package/.output/server/chunks/build/{input-number-TSq6ltkz.mjs.map → input-number-BRnbiKLd.mjs.map} +1 -1
  119. package/.output/server/chunks/build/{logs-hOEVuxqm.mjs → logs-BYop3JfX.mjs} +2 -2
  120. package/.output/server/chunks/build/{logs-hOEVuxqm.mjs.map → logs-BYop3JfX.mjs.map} +1 -1
  121. package/.output/server/chunks/build/{menu-Cy5Nrecn.mjs → menu-DXfhc0qN.mjs} +3 -3
  122. package/.output/server/chunks/build/{menu-Cy5Nrecn.mjs.map → menu-DXfhc0qN.mjs.map} +1 -1
  123. package/.output/server/chunks/build/{monitor-CfVoiavp.mjs → monitor-BjBGkUm2.mjs} +19 -19
  124. package/.output/server/chunks/build/{monitor-CfVoiavp.mjs.map → monitor-BjBGkUm2.mjs.map} +1 -1
  125. package/.output/server/chunks/build/{permissions-XPtQJSaO.mjs → permissions-u5SZL8Fe.mjs} +14 -14
  126. package/.output/server/chunks/build/{permissions-XPtQJSaO.mjs.map → permissions-u5SZL8Fe.mjs.map} +1 -1
  127. package/.output/server/chunks/build/{plugins-DjBSG9pV.mjs → plugins-Cas6KOF-.mjs} +5 -5
  128. package/.output/server/chunks/build/{plugins-DjBSG9pV.mjs.map → plugins-Cas6KOF-.mjs.map} +1 -1
  129. package/.output/server/chunks/build/{popconfirm-DKeEbaGd.mjs → popconfirm-BWxt-53K.mjs} +2 -2
  130. package/.output/server/chunks/build/{popconfirm-DKeEbaGd.mjs.map → popconfirm-BWxt-53K.mjs.map} +1 -1
  131. package/.output/server/chunks/build/{schedules-PcDLCUWN.mjs → schedules-Ct68Jrvw.mjs} +19 -19
  132. package/.output/server/chunks/build/{schedules-PcDLCUWN.mjs.map → schedules-Ct68Jrvw.mjs.map} +1 -1
  133. package/.output/server/chunks/build/{segmented-BdWCdZUM.mjs → segmented-DN62bOFu.mjs} +2 -2
  134. package/.output/server/chunks/build/{segmented-BdWCdZUM.mjs.map → segmented-DN62bOFu.mjs.map} +1 -1
  135. package/.output/server/chunks/build/{select-C5yighj8.mjs → select-DQv1DXcW.mjs} +4 -4
  136. package/.output/server/chunks/build/{select-C5yighj8.mjs.map → select-DQv1DXcW.mjs.map} +1 -1
  137. package/.output/server/chunks/build/{settings-90zT_h9w.mjs → settings-CQzR1YXR.mjs} +13 -13
  138. package/.output/server/chunks/build/{settings-90zT_h9w.mjs.map → settings-CQzR1YXR.mjs.map} +1 -1
  139. package/.output/server/chunks/build/{space-BCffbXIG.mjs → space-6FfG3llN.mjs} +3 -3
  140. package/.output/server/chunks/build/{space-BCffbXIG.mjs.map → space-6FfG3llN.mjs.map} +1 -1
  141. package/.output/server/chunks/build/{switch-OG0SM_Px.mjs → switch-CfsCVFQP.mjs} +2 -2
  142. package/.output/server/chunks/build/{switch-OG0SM_Px.mjs.map → switch-CfsCVFQP.mjs.map} +1 -1
  143. package/.output/server/chunks/build/{table-UpVzu50c.mjs → table-HOjbB5YY.mjs} +9 -9
  144. package/.output/server/chunks/build/{table-UpVzu50c.mjs.map → table-HOjbB5YY.mjs.map} +1 -1
  145. package/.output/server/chunks/build/{tabs-CWwoL33v.mjs → tabs-CC26Rbcw.mjs} +4 -4
  146. package/.output/server/chunks/build/{tabs-CWwoL33v.mjs.map → tabs-CC26Rbcw.mjs.map} +1 -1
  147. package/.output/server/chunks/build/{tag-CS7mwrfG.mjs → tag-BtOMjpDx.mjs} +4 -4
  148. package/.output/server/chunks/build/{tag-CS7mwrfG.mjs.map → tag-BtOMjpDx.mjs.map} +1 -1
  149. package/.output/server/chunks/build/{teams-BIAFvRw1.mjs → teams-Re0wY2SQ.mjs} +19 -19
  150. package/.output/server/chunks/build/{teams-BIAFvRw1.mjs.map → teams-Re0wY2SQ.mjs.map} +1 -1
  151. package/.output/server/chunks/build/{tokens-CLpdrzQ7.mjs → tokens-DLFIUvXE.mjs} +19 -19
  152. package/.output/server/chunks/build/{tokens-CLpdrzQ7.mjs.map → tokens-DLFIUvXE.mjs.map} +1 -1
  153. package/.output/server/chunks/build/{tooltip-CJlH_8ZK.mjs → tooltip-BSDwL_LM.mjs} +4 -4
  154. package/.output/server/chunks/build/{tooltip-CJlH_8ZK.mjs.map → tooltip-BSDwL_LM.mjs.map} +1 -1
  155. package/.output/server/chunks/build/{useAgentTemplateActions-6VyAHgu5.mjs → useAgentTemplateActions-CjBwCb3u.mjs} +1 -1
  156. package/.output/server/chunks/build/{useAgentTemplateActions-6VyAHgu5.mjs.map → useAgentTemplateActions-CjBwCb3u.mjs.map} +1 -1
  157. package/.output/server/chunks/build/{useAgentTemplateForm-DWa-ezNq.mjs → useAgentTemplateForm-BX9_xqj8.mjs} +1 -1
  158. package/.output/server/chunks/build/{useAgentTemplateForm-DWa-ezNq.mjs.map → useAgentTemplateForm-BX9_xqj8.mjs.map} +1 -1
  159. package/.output/server/chunks/build/{useAmlEntities-Co2fgjzh.mjs → useAmlEntities-BrcTqHwa.mjs} +2 -2
  160. package/.output/server/chunks/build/{useAmlEntities-Co2fgjzh.mjs.map → useAmlEntities-BrcTqHwa.mjs.map} +1 -1
  161. package/.output/server/chunks/build/{useAmlEnv-JTiWPrzH.mjs → useAmlEnv-jiGYK790.mjs} +1 -1
  162. package/.output/server/chunks/build/{useAmlEnv-JTiWPrzH.mjs.map → useAmlEnv-jiGYK790.mjs.map} +1 -1
  163. package/.output/server/chunks/build/{useAmlJobs-By4pjOzc.mjs → useAmlJobs-CVZ1btzg.mjs} +1 -1
  164. package/.output/server/chunks/build/{useAmlJobs-By4pjOzc.mjs.map → useAmlJobs-CVZ1btzg.mjs.map} +1 -1
  165. package/.output/server/chunks/build/{useAmlModels-B1_5vjMA.mjs → useAmlModels-DJkQzcCU.mjs} +1 -1
  166. package/.output/server/chunks/build/{useAmlModels-B1_5vjMA.mjs.map → useAmlModels-DJkQzcCU.mjs.map} +1 -1
  167. package/.output/server/chunks/build/{useAmlNotes-5uwvCb3h.mjs → useAmlNotes-DKnx9a8x.mjs} +1 -1
  168. package/.output/server/chunks/build/{useAmlNotes-5uwvCb3h.mjs.map → useAmlNotes-DKnx9a8x.mjs.map} +1 -1
  169. package/.output/server/chunks/build/{useAmlPredict-lxUv7lAO.mjs → useAmlPredict-Bp4ehwKw.mjs} +1 -1
  170. package/.output/server/chunks/build/{useAmlPredict-lxUv7lAO.mjs.map → useAmlPredict-Bp4ehwKw.mjs.map} +1 -1
  171. package/.output/server/chunks/build/{useLogsManual-BLfiSU3u.mjs → useLogsManual-CElmZuJh.mjs} +1 -1
  172. package/.output/server/chunks/build/{useLogsManual-BLfiSU3u.mjs.map → useLogsManual-CElmZuJh.mjs.map} +1 -1
  173. package/.output/server/chunks/build/{useMonitorData-BZ6Z-Sy8.mjs → useMonitorData-DcIfMEiz.mjs} +1 -1
  174. package/.output/server/chunks/build/{useMonitorData-BZ6Z-Sy8.mjs.map → useMonitorData-DcIfMEiz.mjs.map} +1 -1
  175. package/.output/server/chunks/build/{useTeamActions-ahht5J8Y.mjs → useTeamActions-C3_O_AIU.mjs} +1 -1
  176. package/.output/server/chunks/build/{useTeamActions-ahht5J8Y.mjs.map → useTeamActions-C3_O_AIU.mjs.map} +1 -1
  177. package/.output/server/chunks/build/{useTeamAddMemberDialog-DvXxsVy0.mjs → useTeamAddMemberDialog-DWAoZCKd.mjs} +1 -1
  178. package/.output/server/chunks/build/{useTeamAddMemberDialog-DvXxsVy0.mjs.map → useTeamAddMemberDialog-DWAoZCKd.mjs.map} +1 -1
  179. package/.output/server/chunks/build/{useTeamCreateDialog-A_k-XX5B.mjs → useTeamCreateDialog-911mIPWd.mjs} +1 -1
  180. package/.output/server/chunks/build/{useTeamCreateDialog-A_k-XX5B.mjs.map → useTeamCreateDialog-911mIPWd.mjs.map} +1 -1
  181. package/.output/server/chunks/build/{useTeamDeployDialog-CfAFjIr_.mjs → useTeamDeployDialog-D0STROoQ.mjs} +1 -1
  182. package/.output/server/chunks/build/{useTeamDeployDialog-CfAFjIr_.mjs.map → useTeamDeployDialog-D0STROoQ.mjs.map} +1 -1
  183. package/.output/server/chunks/build/{useTeamPluginDialog-Djmkk1Nl.mjs → useTeamPluginDialog-Df6-e2OW.mjs} +1 -1
  184. package/.output/server/chunks/build/{useTeamPluginDialog-Djmkk1Nl.mjs.map → useTeamPluginDialog-Df6-e2OW.mjs.map} +1 -1
  185. package/.output/server/chunks/build/{useTokenCreate-CkWoxSI-.mjs → useTokenCreate-DOojAhM5.mjs} +1 -1
  186. package/.output/server/chunks/build/{useTokenCreate-CkWoxSI-.mjs.map → useTokenCreate-DOojAhM5.mjs.map} +1 -1
  187. package/.output/server/chunks/build/{useTokenRename-BohjnGT0.mjs → useTokenRename-CMA5dLHx.mjs} +1 -1
  188. package/.output/server/chunks/build/{useTokenRename-BohjnGT0.mjs.map → useTokenRename-CMA5dLHx.mjs.map} +1 -1
  189. package/.output/server/chunks/build/{useTokenReveal-BBN5iGz7.mjs → useTokenReveal-C19aCKzt.mjs} +1 -1
  190. package/.output/server/chunks/build/{useTokenReveal-BBN5iGz7.mjs.map → useTokenReveal-C19aCKzt.mjs.map} +1 -1
  191. package/.output/server/chunks/build/{useTokensList-BQX9WqfT.mjs → useTokensList-D0ZpLOhR.mjs} +1 -1
  192. package/.output/server/chunks/build/{useTokensList-BQX9WqfT.mjs.map → useTokensList-D0ZpLOhR.mjs.map} +1 -1
  193. package/.output/server/chunks/build/{useWorkbenchAuth-BTRlS2wZ.mjs → useWorkbenchAuth-CN5E3J5L.mjs} +1 -1
  194. package/.output/server/chunks/build/{useWorkbenchAuth-BTRlS2wZ.mjs.map → useWorkbenchAuth-CN5E3J5L.mjs.map} +1 -1
  195. package/.output/server/chunks/build/{useWorkbenchWorkspaces-C6ky7OJH.mjs → useWorkbenchWorkspaces-ChKByQSD.mjs} +1 -1
  196. package/.output/server/chunks/build/{useWorkbenchWorkspaces-C6ky7OJH.mjs.map → useWorkbenchWorkspaces-ChKByQSD.mjs.map} +1 -1
  197. package/.output/server/chunks/build/{users-BHOEW3Az.mjs → users-BW4jowK4.mjs} +15 -15
  198. package/.output/server/chunks/build/{users-BHOEW3Az.mjs.map → users-BW4jowK4.mjs.map} +1 -1
  199. package/.output/server/chunks/build/{workshop-DyJ1LXwu.mjs → workshop-Bx55czXL.mjs} +11 -11
  200. package/.output/server/chunks/build/{workshop-DyJ1LXwu.mjs.map → workshop-Bx55czXL.mjs.map} +1 -1
  201. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +3 -2
  202. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs.map +1 -1
  203. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +103 -0
  204. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs.map +1 -0
  205. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +6 -2
  229. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  230. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  235. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  236. package/.output/server/chunks/routes/renderer.mjs +2 -2
  237. package/.output/server/chunks/virtual/entry.mjs +533 -529
  238. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  239. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  240. package/.output/server/package.json +1 -1
  241. package/app/components/analysis/AnalysisEditModal.vue +192 -0
  242. package/app/components/analysis/AnalysisFilterCard.vue +159 -160
  243. package/app/components/analysis/AnalysisPageHead.vue +47 -47
  244. package/app/components/analysis/AnalysisTable.vue +322 -306
  245. package/app/pages/analysis/composables/useAnalysisFeed.ts +85 -85
  246. package/app/pages/analysis/index.vue +128 -92
  247. package/app/pages/analysis/types.ts +50 -44
  248. package/i18n/locales/en.ts +8 -0
  249. package/i18n/locales/zh-CN.ts +8 -0
  250. package/package.json +1 -1
  251. package/server/api/workshop/analysis/[id].delete.ts +30 -30
  252. package/server/api/workshop/analysis/[id].get.ts +25 -23
  253. package/server/api/workshop/analysis/[id].patch.ts +100 -0
  254. package/server/api/workshop/analysis/index.get.ts +39 -33
  255. package/server/services/workshop/agents/industrial/analysis-tools.ts +242 -242
  256. package/server/services/workshop/agents/industrial/daq-tools.ts +16 -7
  257. package/server/services/workshop/analysis/analysis.repo.ts +241 -189
  258. package/server/services/workshop/db/database/migrations.ts +10 -0
  259. package/server/services/workshop/db/database/open.ts +3 -1
  260. package/server/services/workshop/db/database/schema.ts +6 -2
  261. package/server/services/workshop/db/schema.sql +6 -2
  262. package/.output/public/_nuxt/5juo_WO2.js +0 -13
  263. package/.output/public/_nuxt/B-WTxXEK2.js +0 -1
  264. package/.output/public/_nuxt/B1BCga5h2.js +0 -13
  265. package/.output/public/_nuxt/B5lMtA7I2.js +0 -1
  266. package/.output/public/_nuxt/B6_fJd2X.js +0 -1
  267. package/.output/public/_nuxt/B7K5B04W2.js +0 -1
  268. package/.output/public/_nuxt/B7KyS_q2.js +0 -1
  269. package/.output/public/_nuxt/B8q3BGY5.js +0 -37
  270. package/.output/public/_nuxt/B9IK8kDl2.js +0 -1
  271. package/.output/public/_nuxt/BNd2NDxg2.js +0 -1
  272. package/.output/public/_nuxt/BP629NAi.js +0 -1
  273. package/.output/public/_nuxt/BVinTfuN.js +0 -1
  274. package/.output/public/_nuxt/BdE41Y_c.js +0 -28
  275. package/.output/public/_nuxt/Be_StT8b2.js +0 -1
  276. package/.output/public/_nuxt/BsYEYxWv.js +0 -24
  277. package/.output/public/_nuxt/BuNXYpib2.js +0 -1
  278. package/.output/public/_nuxt/CDaZC0_6.js +0 -3
  279. package/.output/public/_nuxt/CE43-V_L.js +0 -2
  280. package/.output/public/_nuxt/CWfBtswB.js +0 -70
  281. package/.output/public/_nuxt/CYtH1bv2.js +0 -1
  282. package/.output/public/_nuxt/ChPNKPw_.js +0 -1
  283. package/.output/public/_nuxt/CktUrk8z.js +0 -1
  284. package/.output/public/_nuxt/DMCoWgSb2.js +0 -1
  285. package/.output/public/_nuxt/Dg1iMuZ-.js +0 -1
  286. package/.output/public/_nuxt/DmwMkvoQ2.js +0 -1
  287. package/.output/public/_nuxt/LwITbamf2.js +0 -47
  288. package/.output/public/_nuxt/_jfzcYrl.js +0 -1
  289. package/.output/public/_nuxt/analysis.D2Pao1rm.css +0 -1
  290. package/.output/public/_nuxt/builds/meta/f78a1992-e424-494d-ac4b-aa18971ffc10.json +0 -1
  291. package/.output/server/chunks/build/analysis-tgzvOWmD.mjs +0 -332
  292. 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
+ }
@@ -8,9 +8,12 @@ import { getActiveLineRun } from '../../dcw/line-run'
8
8
  import { getAgentNodeBindingRepo } from '../node-bindings.repo'
9
9
  import { getDaqNodeRepo } from '../../daq/daq-node.repo'
10
10
  import { getDcwController } from '../../dcw/dcw-controller'
11
+ import { channelBoundLineId } from './ops-tools'
11
12
 
12
13
  /**
13
- * 数采目标集解析(工具共用鉴权面):Agent 绑定(kind=daq)为权限边界 ——
14
+ * 数采目标集解析(工具共用鉴权面):
15
+ * ① Agent 绑定(kind=daq);② v28 频道绑线只读扩权 —— 频道绑定产线下的数采节点
16
+ * 并入读取集(与 ops_log/line_context 的绑线只读扩权同族;本函数仅服务只读查询面)。
14
17
  * node_id/line_id 只能缩小范围,不能放大(越权节点一律拒绝)。
15
18
  */
16
19
  export function daqTargetsOf(agentId: string, nodeIdArg: unknown, lineIdArg: unknown):
@@ -18,23 +21,29 @@ export function daqTargetsOf(agentId: string, nodeIdArg: unknown, lineIdArg: unk
18
21
  | { error: { text: string, isError: true } } {
19
22
  const repo = getAgentNodeBindingRepo()
20
23
  const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
21
- if (daqBindings.length === 0) {
22
- return { error: { text: '你尚未绑定任何数采节点,无权查询采集数据。请在数字孪生界面绑定数采节点。', isError: true } }
24
+ // v28:频道绑线的数采节点并入可见集(只读)
25
+ const boundLine = channelBoundLineId(agentId)
26
+ const boundLineNodes = boundLine
27
+ ? getDaqNodeRepo().all().filter(n => n.lineId === boundLine).map(n => n.id)
28
+ : []
29
+ const readable = new Set([...daqBindings.map(b => b.nodeId), ...boundLineNodes])
30
+ if (readable.size === 0) {
31
+ return { error: { text: '你尚未绑定任何数采节点,频道也未绑定产线,无权查询采集数据。请在数字孪生界面绑定数采节点,或将频道绑定到目标产线(绑线后可只读查询该线数采数据)。', isError: true } }
23
32
  }
24
33
  const wanted = nodeIdArg ? String(nodeIdArg) : ''
25
- if (wanted && !daqBindings.some(b => b.nodeId === wanted)) {
26
- return { error: { text: `无权查询节点 ${wanted}。你有权访问的数采节点:${daqBindings.map(b => b.nodeId).join(', ')}`, isError: true } }
34
+ if (wanted && !readable.has(wanted)) {
35
+ return { error: { text: `无权查询节点 ${wanted}。你有权访问的数采节点:${[...readable].join(', ')}`, isError: true } }
27
36
  }
28
37
  const lineFilter = lineIdArg ? String(lineIdArg).trim() : ''
29
38
  const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
30
39
  if (lineFilter && wanted && lineOf(wanted) !== lineFilter) {
31
40
  return { error: { text: `节点 ${wanted} 不属于产线 ${lineFilter}(实际归属:${lineOf(wanted) || '未分配'}),line_id 与 node_id 过滤冲突。`, isError: true } }
32
41
  }
33
- let targets = wanted ? [wanted] : daqBindings.map(b => b.nodeId)
42
+ let targets = wanted ? [wanted] : [...readable]
34
43
  if (lineFilter && !wanted) {
35
44
  const onLine = targets.filter(id => lineOf(id) === lineFilter)
36
45
  if (onLine.length === 0) {
37
- return { error: { text: `你绑定的数采节点中没有归属产线 ${lineFilter} 的(各节点归属:${daqBindings.map(b => `${b.nodeId}=${lineOf(b.nodeId) || '未分配'}`).join('; ')})。`, isError: true } }
46
+ return { error: { text: `你有权访问的数采节点中没有归属产线 ${lineFilter} 的(各节点归属:${[...readable].map(id => `${id}=${lineOf(id) || '未分配'}`).join('; ')})。`, isError: true } }
38
47
  }
39
48
  targets = onLine
40
49
  }