@open-mercato/ai-assistant 0.5.1-develop.3036.f02c281f23 → 0.5.1-develop.3045.b4b3320cc2

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 (273) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +361 -0
  3. package/README.md +5 -0
  4. package/dist/index.js +154 -0
  5. package/dist/index.js.map +2 -2
  6. package/dist/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.js +73 -0
  7. package/dist/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.js.map +7 -0
  8. package/dist/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.js +484 -0
  9. package/dist/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.js.map +7 -0
  10. package/dist/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.js +251 -0
  11. package/dist/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.js.map +7 -0
  12. package/dist/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.js +91 -0
  13. package/dist/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.js.map +7 -0
  14. package/dist/modules/ai_assistant/ai-tools/attachments-pack.js +202 -0
  15. package/dist/modules/ai_assistant/ai-tools/attachments-pack.js.map +7 -0
  16. package/dist/modules/ai_assistant/ai-tools/meta-pack.js +121 -0
  17. package/dist/modules/ai_assistant/ai-tools/meta-pack.js.map +7 -0
  18. package/dist/modules/ai_assistant/ai-tools/search-pack.js +94 -0
  19. package/dist/modules/ai_assistant/ai-tools/search-pack.js.map +7 -0
  20. package/dist/modules/ai_assistant/ai-tools.js +14 -0
  21. package/dist/modules/ai_assistant/ai-tools.js.map +7 -0
  22. package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js +175 -0
  23. package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js.map +7 -0
  24. package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js +174 -0
  25. package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js.map +7 -0
  26. package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js +101 -0
  27. package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js.map +7 -0
  28. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js +311 -0
  29. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js.map +7 -0
  30. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js +246 -0
  31. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js.map +7 -0
  32. package/dist/modules/ai_assistant/api/ai/agents/route.js +94 -0
  33. package/dist/modules/ai_assistant/api/ai/agents/route.js.map +7 -0
  34. package/dist/modules/ai_assistant/api/ai/chat/route.js +173 -0
  35. package/dist/modules/ai_assistant/api/ai/chat/route.js.map +7 -0
  36. package/dist/modules/ai_assistant/api/ai/run-object/route.js +167 -0
  37. package/dist/modules/ai_assistant/api/ai/run-object/route.js.map +7 -0
  38. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js +1111 -0
  39. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js.map +7 -0
  40. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.js +10 -0
  41. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.js.map +7 -0
  42. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.js +28 -0
  43. package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.js.map +7 -0
  44. package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.js +10 -0
  45. package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.js.map +7 -0
  46. package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.js +30 -0
  47. package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.js.map +7 -0
  48. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js +4 -6
  49. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js.map +2 -2
  50. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js +1 -21
  51. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js.map +2 -2
  52. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js +462 -0
  53. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js.map +7 -0
  54. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.js +10 -0
  55. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.js.map +7 -0
  56. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.js +28 -0
  57. package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.js.map +7 -0
  58. package/dist/modules/ai_assistant/cli.js +78 -12
  59. package/dist/modules/ai_assistant/cli.js.map +2 -2
  60. package/dist/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.js +5 -0
  61. package/dist/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.js.map +7 -0
  62. package/dist/modules/ai_assistant/data/entities/AiAgentPromptOverride.js +5 -0
  63. package/dist/modules/ai_assistant/data/entities/AiAgentPromptOverride.js.map +7 -0
  64. package/dist/modules/ai_assistant/data/entities/AiPendingAction.js +5 -0
  65. package/dist/modules/ai_assistant/data/entities/AiPendingAction.js.map +7 -0
  66. package/dist/modules/ai_assistant/data/entities.js +228 -0
  67. package/dist/modules/ai_assistant/data/entities.js.map +7 -0
  68. package/dist/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.js +95 -0
  69. package/dist/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.js.map +7 -0
  70. package/dist/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.js +95 -0
  71. package/dist/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.js.map +7 -0
  72. package/dist/modules/ai_assistant/data/repositories/AiPendingActionRepository.js +223 -0
  73. package/dist/modules/ai_assistant/data/repositories/AiPendingActionRepository.js.map +7 -0
  74. package/dist/modules/ai_assistant/events.js +33 -0
  75. package/dist/modules/ai_assistant/events.js.map +7 -0
  76. package/dist/modules/ai_assistant/i18n/de.json +252 -0
  77. package/dist/modules/ai_assistant/i18n/en.json +252 -0
  78. package/dist/modules/ai_assistant/i18n/es.json +252 -0
  79. package/dist/modules/ai_assistant/i18n/pl.json +252 -0
  80. package/dist/modules/ai_assistant/lib/agent-policy.js +168 -0
  81. package/dist/modules/ai_assistant/lib/agent-policy.js.map +7 -0
  82. package/dist/modules/ai_assistant/lib/agent-registry.js +195 -0
  83. package/dist/modules/ai_assistant/lib/agent-registry.js.map +7 -0
  84. package/dist/modules/ai_assistant/lib/agent-runtime.js +451 -0
  85. package/dist/modules/ai_assistant/lib/agent-runtime.js.map +7 -0
  86. package/dist/modules/ai_assistant/lib/agent-tools.js +223 -0
  87. package/dist/modules/ai_assistant/lib/agent-tools.js.map +7 -0
  88. package/dist/modules/ai_assistant/lib/agent-transport.js +25 -0
  89. package/dist/modules/ai_assistant/lib/agent-transport.js.map +7 -0
  90. package/dist/modules/ai_assistant/lib/ai-agent-definition.js +11 -0
  91. package/dist/modules/ai_assistant/lib/ai-agent-definition.js.map +7 -0
  92. package/dist/modules/ai_assistant/lib/ai-agents-generated.d.js +1 -0
  93. package/dist/modules/ai_assistant/lib/ai-agents-generated.d.js.map +7 -0
  94. package/dist/modules/ai_assistant/lib/ai-api-operation-runner.js +239 -0
  95. package/dist/modules/ai_assistant/lib/ai-api-operation-runner.js.map +7 -0
  96. package/dist/modules/ai_assistant/lib/ai-overrides.js +189 -0
  97. package/dist/modules/ai_assistant/lib/ai-overrides.js.map +7 -0
  98. package/dist/modules/ai_assistant/lib/ai-tool-definition.js +7 -0
  99. package/dist/modules/ai_assistant/lib/ai-tool-definition.js.map +7 -0
  100. package/dist/modules/ai_assistant/lib/ai-tools-generated.d.js +1 -0
  101. package/dist/modules/ai_assistant/lib/ai-tools-generated.d.js.map +7 -0
  102. package/dist/modules/ai_assistant/lib/api-backed-tool.js +48 -0
  103. package/dist/modules/ai_assistant/lib/api-backed-tool.js.map +7 -0
  104. package/dist/modules/ai_assistant/lib/attachment-bridge-types.js +1 -0
  105. package/dist/modules/ai_assistant/lib/attachment-bridge-types.js.map +7 -0
  106. package/dist/modules/ai_assistant/lib/attachment-parts.js +276 -0
  107. package/dist/modules/ai_assistant/lib/attachment-parts.js.map +7 -0
  108. package/dist/modules/ai_assistant/lib/model-factory.js +68 -0
  109. package/dist/modules/ai_assistant/lib/model-factory.js.map +7 -0
  110. package/dist/modules/ai_assistant/lib/pending-action-cancel.js +86 -0
  111. package/dist/modules/ai_assistant/lib/pending-action-cancel.js.map +7 -0
  112. package/dist/modules/ai_assistant/lib/pending-action-client.js +35 -0
  113. package/dist/modules/ai_assistant/lib/pending-action-client.js.map +7 -0
  114. package/dist/modules/ai_assistant/lib/pending-action-executor.js +243 -0
  115. package/dist/modules/ai_assistant/lib/pending-action-executor.js.map +7 -0
  116. package/dist/modules/ai_assistant/lib/pending-action-recheck.js +246 -0
  117. package/dist/modules/ai_assistant/lib/pending-action-recheck.js.map +7 -0
  118. package/dist/modules/ai_assistant/lib/pending-action-types.js +70 -0
  119. package/dist/modules/ai_assistant/lib/pending-action-types.js.map +7 -0
  120. package/dist/modules/ai_assistant/lib/prepare-mutation.js +315 -0
  121. package/dist/modules/ai_assistant/lib/prepare-mutation.js.map +7 -0
  122. package/dist/modules/ai_assistant/lib/prompt-composition-types.js +7 -0
  123. package/dist/modules/ai_assistant/lib/prompt-composition-types.js.map +7 -0
  124. package/dist/modules/ai_assistant/lib/prompt-override-merge.js +175 -0
  125. package/dist/modules/ai_assistant/lib/prompt-override-merge.js.map +7 -0
  126. package/dist/modules/ai_assistant/lib/schema-utils.js +5 -1
  127. package/dist/modules/ai_assistant/lib/schema-utils.js.map +2 -2
  128. package/dist/modules/ai_assistant/lib/tool-executor.js +13 -2
  129. package/dist/modules/ai_assistant/lib/tool-executor.js.map +2 -2
  130. package/dist/modules/ai_assistant/lib/tool-loader.js +86 -11
  131. package/dist/modules/ai_assistant/lib/tool-loader.js.map +2 -2
  132. package/dist/modules/ai_assistant/lib/tool-test-fixtures.js +120 -0
  133. package/dist/modules/ai_assistant/lib/tool-test-fixtures.js.map +7 -0
  134. package/dist/modules/ai_assistant/lib/tool-test-runner.js +418 -0
  135. package/dist/modules/ai_assistant/lib/tool-test-runner.js.map +7 -0
  136. package/dist/modules/ai_assistant/migrations/Migration20260419100521.js +17 -0
  137. package/dist/modules/ai_assistant/migrations/Migration20260419100521.js.map +7 -0
  138. package/dist/modules/ai_assistant/migrations/Migration20260419132948.js +16 -0
  139. package/dist/modules/ai_assistant/migrations/Migration20260419132948.js.map +7 -0
  140. package/dist/modules/ai_assistant/migrations/Migration20260419134235.js +17 -0
  141. package/dist/modules/ai_assistant/migrations/Migration20260419134235.js.map +7 -0
  142. package/dist/modules/ai_assistant/setup.js +36 -0
  143. package/dist/modules/ai_assistant/setup.js.map +2 -2
  144. package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js +161 -0
  145. package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js.map +7 -0
  146. package/generated/entities/ai_agent_mutation_policy_override/index.ts +9 -0
  147. package/generated/entities/ai_agent_prompt_override/index.ts +10 -0
  148. package/generated/entities/ai_pending_action/index.ts +24 -0
  149. package/generated/entities.ids.generated.ts +13 -0
  150. package/generated/entity-fields-registry.ts +57 -0
  151. package/jest.config.cjs +7 -0
  152. package/package.json +4 -4
  153. package/src/index.ts +215 -0
  154. package/src/modules/ai_assistant/__integration__/README.md +5 -0
  155. package/src/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.ts +115 -0
  156. package/src/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.ts +574 -0
  157. package/src/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.ts +333 -0
  158. package/src/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.ts +135 -0
  159. package/src/modules/ai_assistant/__tests__/events.test.ts +145 -0
  160. package/src/modules/ai_assistant/__tests__/integration/pending-action-contract.test.ts +1015 -0
  161. package/src/modules/ai_assistant/__tests__/integration/ws-c-attachment-bridge.test.ts +235 -0
  162. package/src/modules/ai_assistant/__tests__/integration/ws-c-policy-and-tools.test.ts +330 -0
  163. package/src/modules/ai_assistant/__tests__/integration/ws-c-tool-pack-coverage.test.ts +285 -0
  164. package/src/modules/ai_assistant/ai-tools/__tests__/attachments-pack.test.ts +322 -0
  165. package/src/modules/ai_assistant/ai-tools/__tests__/meta-pack.test.ts +218 -0
  166. package/src/modules/ai_assistant/ai-tools/__tests__/search-pack.test.ts +192 -0
  167. package/src/modules/ai_assistant/ai-tools/attachments-pack.ts +269 -0
  168. package/src/modules/ai_assistant/ai-tools/meta-pack.ts +140 -0
  169. package/src/modules/ai_assistant/ai-tools/search-pack.ts +122 -0
  170. package/src/modules/ai_assistant/ai-tools.ts +21 -0
  171. package/src/modules/ai_assistant/api/ai/actions/[id]/__tests__/route.test.ts +222 -0
  172. package/src/modules/ai_assistant/api/ai/actions/[id]/cancel/__tests__/route.test.ts +286 -0
  173. package/src/modules/ai_assistant/api/ai/actions/[id]/cancel/route.ts +237 -0
  174. package/src/modules/ai_assistant/api/ai/actions/[id]/confirm/__tests__/route.test.ts +339 -0
  175. package/src/modules/ai_assistant/api/ai/actions/[id]/confirm/route.ts +229 -0
  176. package/src/modules/ai_assistant/api/ai/actions/[id]/route.ts +142 -0
  177. package/src/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/__tests__/route.test.ts +367 -0
  178. package/src/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.ts +380 -0
  179. package/src/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/__tests__/route.test.ts +333 -0
  180. package/src/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.ts +307 -0
  181. package/src/modules/ai_assistant/api/ai/agents/route.ts +107 -0
  182. package/src/modules/ai_assistant/api/ai/chat/__tests__/route.test.ts +282 -0
  183. package/src/modules/ai_assistant/api/ai/chat/route.ts +207 -0
  184. package/src/modules/ai_assistant/api/ai/run-object/__tests__/route.test.ts +282 -0
  185. package/src/modules/ai_assistant/api/ai/run-object/route.ts +204 -0
  186. package/src/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.tsx +1419 -0
  187. package/src/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.ts +26 -0
  188. package/src/modules/ai_assistant/backend/config/ai-assistant/agents/page.tsx +12 -0
  189. package/src/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.ts +28 -0
  190. package/src/modules/ai_assistant/backend/config/ai-assistant/legacy/page.tsx +12 -0
  191. package/src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts +8 -23
  192. package/src/modules/ai_assistant/backend/config/ai-assistant/page.tsx +15 -10
  193. package/src/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.tsx +604 -0
  194. package/src/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.ts +26 -0
  195. package/src/modules/ai_assistant/backend/config/ai-assistant/playground/page.tsx +12 -0
  196. package/src/modules/ai_assistant/cli.ts +99 -24
  197. package/src/modules/ai_assistant/data/__tests__/schema-unique-indexes.test.ts +69 -0
  198. package/src/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.ts +7 -0
  199. package/src/modules/ai_assistant/data/entities/AiAgentPromptOverride.ts +7 -0
  200. package/src/modules/ai_assistant/data/entities/AiPendingAction.ts +7 -0
  201. package/src/modules/ai_assistant/data/entities.ts +270 -0
  202. package/src/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.ts +129 -0
  203. package/src/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.ts +132 -0
  204. package/src/modules/ai_assistant/data/repositories/AiPendingActionRepository.ts +334 -0
  205. package/src/modules/ai_assistant/data/repositories/__tests__/AiAgentMutationPolicyOverrideRepository.test.ts +195 -0
  206. package/src/modules/ai_assistant/data/repositories/__tests__/AiAgentPromptOverrideRepository.test.ts +197 -0
  207. package/src/modules/ai_assistant/data/repositories/__tests__/AiPendingActionRepository.test.ts +357 -0
  208. package/src/modules/ai_assistant/events.ts +112 -0
  209. package/src/modules/ai_assistant/i18n/de.json +252 -0
  210. package/src/modules/ai_assistant/i18n/en.json +252 -0
  211. package/src/modules/ai_assistant/i18n/es.json +252 -0
  212. package/src/modules/ai_assistant/i18n/pl.json +252 -0
  213. package/src/modules/ai_assistant/lib/__tests__/agent-policy.mutation-override.test.ts +203 -0
  214. package/src/modules/ai_assistant/lib/__tests__/agent-policy.test.ts +385 -0
  215. package/src/modules/ai_assistant/lib/__tests__/agent-registry.test.ts +217 -0
  216. package/src/modules/ai_assistant/lib/__tests__/agent-runtime-object.test.ts +329 -0
  217. package/src/modules/ai_assistant/lib/__tests__/agent-runtime-parity.test.ts +573 -0
  218. package/src/modules/ai_assistant/lib/__tests__/agent-runtime.test.ts +291 -0
  219. package/src/modules/ai_assistant/lib/__tests__/agent-tools.test.ts +172 -0
  220. package/src/modules/ai_assistant/lib/__tests__/agent-transport.test.ts +41 -0
  221. package/src/modules/ai_assistant/lib/__tests__/ai-agent-definition.test.ts +183 -0
  222. package/src/modules/ai_assistant/lib/__tests__/ai-api-operation-runner.test.ts +432 -0
  223. package/src/modules/ai_assistant/lib/__tests__/ai-overrides.test.ts +308 -0
  224. package/src/modules/ai_assistant/lib/__tests__/api-backed-tool.test.ts +302 -0
  225. package/src/modules/ai_assistant/lib/__tests__/attachment-bridge-and-prompt-types.test.ts +188 -0
  226. package/src/modules/ai_assistant/lib/__tests__/attachment-parts.test.ts +531 -0
  227. package/src/modules/ai_assistant/lib/__tests__/max-steps-budget.integration.test.ts +263 -0
  228. package/src/modules/ai_assistant/lib/__tests__/model-factory.integration.test.ts +183 -0
  229. package/src/modules/ai_assistant/lib/__tests__/model-factory.test.ts +168 -0
  230. package/src/modules/ai_assistant/lib/__tests__/pending-action-cancel.test.ts +235 -0
  231. package/src/modules/ai_assistant/lib/__tests__/pending-action-client.test.ts +148 -0
  232. package/src/modules/ai_assistant/lib/__tests__/pending-action-executor.test.ts +348 -0
  233. package/src/modules/ai_assistant/lib/__tests__/pending-action-recheck.test.ts +378 -0
  234. package/src/modules/ai_assistant/lib/__tests__/phase-0-additive-contract.test.ts +299 -0
  235. package/src/modules/ai_assistant/lib/__tests__/prepare-mutation.test.ts +610 -0
  236. package/src/modules/ai_assistant/lib/__tests__/prompt-override-merge.test.ts +136 -0
  237. package/src/modules/ai_assistant/lib/__tests__/tool-loader.test.ts +125 -0
  238. package/src/modules/ai_assistant/lib/agent-policy.ts +270 -0
  239. package/src/modules/ai_assistant/lib/agent-registry.ts +277 -0
  240. package/src/modules/ai_assistant/lib/agent-runtime.ts +751 -0
  241. package/src/modules/ai_assistant/lib/agent-tools.ts +396 -0
  242. package/src/modules/ai_assistant/lib/agent-transport.ts +51 -0
  243. package/src/modules/ai_assistant/lib/ai-agent-definition.ts +86 -0
  244. package/src/modules/ai_assistant/lib/ai-agents-generated.d.ts +18 -0
  245. package/src/modules/ai_assistant/lib/ai-api-operation-runner.ts +333 -0
  246. package/src/modules/ai_assistant/lib/ai-overrides.ts +389 -0
  247. package/src/modules/ai_assistant/lib/ai-tool-definition.ts +7 -0
  248. package/src/modules/ai_assistant/lib/ai-tools-generated.d.ts +7 -0
  249. package/src/modules/ai_assistant/lib/api-backed-tool.ts +85 -0
  250. package/src/modules/ai_assistant/lib/attachment-bridge-types.ts +24 -0
  251. package/src/modules/ai_assistant/lib/attachment-parts.ts +433 -0
  252. package/src/modules/ai_assistant/lib/model-factory.ts +212 -0
  253. package/src/modules/ai_assistant/lib/pending-action-cancel.ts +179 -0
  254. package/src/modules/ai_assistant/lib/pending-action-client.ts +126 -0
  255. package/src/modules/ai_assistant/lib/pending-action-executor.ts +424 -0
  256. package/src/modules/ai_assistant/lib/pending-action-recheck.ts +410 -0
  257. package/src/modules/ai_assistant/lib/pending-action-types.ts +194 -0
  258. package/src/modules/ai_assistant/lib/prepare-mutation.ts +448 -0
  259. package/src/modules/ai_assistant/lib/prompt-composition-types.ts +24 -0
  260. package/src/modules/ai_assistant/lib/prompt-override-merge.ts +253 -0
  261. package/src/modules/ai_assistant/lib/schema-utils.ts +14 -2
  262. package/src/modules/ai_assistant/lib/tool-executor.ts +25 -3
  263. package/src/modules/ai_assistant/lib/tool-loader.ts +159 -13
  264. package/src/modules/ai_assistant/lib/tool-test-fixtures.ts +160 -0
  265. package/src/modules/ai_assistant/lib/tool-test-runner.ts +596 -0
  266. package/src/modules/ai_assistant/lib/types.ts +105 -2
  267. package/src/modules/ai_assistant/migrations/.snapshot-open-mercato.json +871 -0
  268. package/src/modules/ai_assistant/migrations/Migration20260419100521.ts +17 -0
  269. package/src/modules/ai_assistant/migrations/Migration20260419132948.ts +16 -0
  270. package/src/modules/ai_assistant/migrations/Migration20260419134235.ts +17 -0
  271. package/src/modules/ai_assistant/setup.ts +53 -0
  272. package/src/modules/ai_assistant/workers/__tests__/ai-pending-action-cleanup.test.ts +333 -0
  273. package/src/modules/ai_assistant/workers/ai-pending-action-cleanup.ts +269 -0
@@ -0,0 +1,95 @@
1
+ import {
2
+ findOneWithDecryption,
3
+ findWithDecryption
4
+ } from "@open-mercato/shared/lib/encryption/find";
5
+ import { AiAgentPromptOverride } from "../entities.js";
6
+ class AiAgentPromptOverrideRepository {
7
+ constructor(em) {
8
+ this.em = em;
9
+ }
10
+ async getLatest(agentId, ctx) {
11
+ if (!agentId || !ctx?.tenantId) return null;
12
+ const row = await findOneWithDecryption(
13
+ this.em,
14
+ AiAgentPromptOverride,
15
+ {
16
+ tenantId: ctx.tenantId,
17
+ organizationId: ctx.organizationId ?? null,
18
+ agentId
19
+ },
20
+ { orderBy: { version: "desc" } },
21
+ { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null }
22
+ );
23
+ return row ?? null;
24
+ }
25
+ async listVersions(agentId, ctx, limit = 10) {
26
+ if (!agentId || !ctx?.tenantId) return [];
27
+ const capped = Math.max(1, Math.min(Math.floor(limit), 100));
28
+ const rows = await findWithDecryption(
29
+ this.em,
30
+ AiAgentPromptOverride,
31
+ {
32
+ tenantId: ctx.tenantId,
33
+ organizationId: ctx.organizationId ?? null,
34
+ agentId
35
+ },
36
+ {
37
+ orderBy: { version: "desc" },
38
+ limit: capped
39
+ },
40
+ { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null }
41
+ );
42
+ return rows;
43
+ }
44
+ async save(input, ctx) {
45
+ if (!ctx?.tenantId) {
46
+ throw new Error("AiAgentPromptOverrideRepository.save requires tenantId");
47
+ }
48
+ if (!input?.agentId) {
49
+ throw new Error("AiAgentPromptOverrideRepository.save requires agentId");
50
+ }
51
+ const sanitizedSections = sanitizeSections(input.sections);
52
+ return this.em.transactional(async (tx) => {
53
+ const latest = await findOneWithDecryption(
54
+ tx,
55
+ AiAgentPromptOverride,
56
+ {
57
+ tenantId: ctx.tenantId,
58
+ organizationId: ctx.organizationId ?? null,
59
+ agentId: input.agentId
60
+ },
61
+ { orderBy: { version: "desc" } },
62
+ { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null }
63
+ );
64
+ const nextVersion = (latest?.version ?? 0) + 1;
65
+ const row = tx.create(AiAgentPromptOverride, {
66
+ tenantId: ctx.tenantId,
67
+ organizationId: ctx.organizationId ?? null,
68
+ agentId: input.agentId,
69
+ version: nextVersion,
70
+ sections: sanitizedSections,
71
+ notes: input.notes ?? null,
72
+ createdByUserId: ctx.userId ?? null
73
+ });
74
+ await tx.persist(row).flush();
75
+ return row;
76
+ });
77
+ }
78
+ }
79
+ function sanitizeSections(sections) {
80
+ if (!sections || typeof sections !== "object") return {};
81
+ const out = {};
82
+ for (const [key, value] of Object.entries(sections)) {
83
+ if (typeof value !== "string") continue;
84
+ const trimmed = value.trim();
85
+ if (!trimmed) continue;
86
+ out[key] = value;
87
+ }
88
+ return out;
89
+ }
90
+ var AiAgentPromptOverrideRepository_default = AiAgentPromptOverrideRepository;
91
+ export {
92
+ AiAgentPromptOverrideRepository,
93
+ AiAgentPromptOverrideRepository_default as default
94
+ };
95
+ //# sourceMappingURL=AiAgentPromptOverrideRepository.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.ts"],
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport {\n findOneWithDecryption,\n findWithDecryption,\n} from '@open-mercato/shared/lib/encryption/find'\nimport { AiAgentPromptOverride } from '../entities'\n\nexport interface AiAgentPromptOverrideContext {\n tenantId: string\n organizationId?: string | null\n userId?: string | null\n}\n\nexport interface AiAgentPromptOverrideInput {\n agentId: string\n sections: Record<string, string>\n notes?: string | null\n}\n\n/**\n * Versioned prompt-override repository (Step 5.3).\n *\n * Every write produces a new row with a monotonically-increasing `version`\n * scoped to `(tenantId, organizationId, agentId)`. We allocate the next\n * version inside a transaction so two concurrent writers cannot collide on\n * the same version number.\n *\n * Reads ALWAYS go through `findOneWithDecryption` / `findWithDecryption` \u2014\n * the `sections` column isn't encrypted today, but the repo sticks to the\n * shared encrypted-read helpers so future GDPR-flagged columns are handled\n * automatically.\n */\nexport class AiAgentPromptOverrideRepository {\n constructor(private readonly em: EntityManager) {}\n\n async getLatest(\n agentId: string,\n ctx: AiAgentPromptOverrideContext,\n ): Promise<AiAgentPromptOverride | null> {\n if (!agentId || !ctx?.tenantId) return null\n const row = await findOneWithDecryption<AiAgentPromptOverride>(\n this.em,\n AiAgentPromptOverride,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId,\n } as any,\n { orderBy: { version: 'desc' } as any },\n { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null },\n )\n return row ?? null\n }\n\n async listVersions(\n agentId: string,\n ctx: AiAgentPromptOverrideContext,\n limit: number = 10,\n ): Promise<AiAgentPromptOverride[]> {\n if (!agentId || !ctx?.tenantId) return []\n const capped = Math.max(1, Math.min(Math.floor(limit), 100))\n const rows = await findWithDecryption<AiAgentPromptOverride>(\n this.em,\n AiAgentPromptOverride,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId,\n } as any,\n {\n orderBy: { version: 'desc' } as any,\n limit: capped,\n },\n { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null },\n )\n return rows\n }\n\n async save(\n input: AiAgentPromptOverrideInput,\n ctx: AiAgentPromptOverrideContext,\n ): Promise<AiAgentPromptOverride> {\n if (!ctx?.tenantId) {\n throw new Error('AiAgentPromptOverrideRepository.save requires tenantId')\n }\n if (!input?.agentId) {\n throw new Error('AiAgentPromptOverrideRepository.save requires agentId')\n }\n const sanitizedSections = sanitizeSections(input.sections)\n return this.em.transactional(async (tx) => {\n const latest = await findOneWithDecryption<AiAgentPromptOverride>(\n tx as unknown as EntityManager,\n AiAgentPromptOverride,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId: input.agentId,\n } as any,\n { orderBy: { version: 'desc' } as any },\n { tenantId: ctx.tenantId ?? null, organizationId: ctx.organizationId ?? null },\n )\n const nextVersion = (latest?.version ?? 0) + 1\n const row = tx.create(AiAgentPromptOverride, {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId: input.agentId,\n version: nextVersion,\n sections: sanitizedSections,\n notes: input.notes ?? null,\n createdByUserId: ctx.userId ?? null,\n } as unknown as AiAgentPromptOverride)\n await tx.persist(row).flush()\n return row\n })\n }\n}\n\nfunction sanitizeSections(\n sections: Record<string, string> | null | undefined,\n): Record<string, string> {\n if (!sections || typeof sections !== 'object') return {}\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(sections)) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (!trimmed) continue\n out[key] = value\n }\n return out\n}\n\nexport default AiAgentPromptOverrideRepository\n"],
5
+ "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AA2B/B,MAAM,gCAAgC;AAAA,EAC3C,YAA6B,IAAmB;AAAnB;AAAA,EAAoB;AAAA,EAEjD,MAAM,UACJ,SACA,KACuC;AACvC,QAAI,CAAC,WAAW,CAAC,KAAK,SAAU,QAAO;AACvC,UAAM,MAAM,MAAM;AAAA,MAChB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE,UAAU,IAAI;AAAA,QACd,gBAAgB,IAAI,kBAAkB;AAAA,QACtC;AAAA,MACF;AAAA,MACA,EAAE,SAAS,EAAE,SAAS,OAAO,EAAS;AAAA,MACtC,EAAE,UAAU,IAAI,YAAY,MAAM,gBAAgB,IAAI,kBAAkB,KAAK;AAAA,IAC/E;AACA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,aACJ,SACA,KACA,QAAgB,IACkB;AAClC,QAAI,CAAC,WAAW,CAAC,KAAK,SAAU,QAAO,CAAC;AACxC,UAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG,CAAC;AAC3D,UAAM,OAAO,MAAM;AAAA,MACjB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE,UAAU,IAAI;AAAA,QACd,gBAAgB,IAAI,kBAAkB;AAAA,QACtC;AAAA,MACF;AAAA,MACA;AAAA,QACE,SAAS,EAAE,SAAS,OAAO;AAAA,QAC3B,OAAO;AAAA,MACT;AAAA,MACA,EAAE,UAAU,IAAI,YAAY,MAAM,gBAAgB,IAAI,kBAAkB,KAAK;AAAA,IAC/E;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KACJ,OACA,KACgC;AAChC,QAAI,CAAC,KAAK,UAAU;AAClB,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AACA,UAAM,oBAAoB,iBAAiB,MAAM,QAAQ;AACzD,WAAO,KAAK,GAAG,cAAc,OAAO,OAAO;AACzC,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,UACE,UAAU,IAAI;AAAA,UACd,gBAAgB,IAAI,kBAAkB;AAAA,UACtC,SAAS,MAAM;AAAA,QACjB;AAAA,QACA,EAAE,SAAS,EAAE,SAAS,OAAO,EAAS;AAAA,QACtC,EAAE,UAAU,IAAI,YAAY,MAAM,gBAAgB,IAAI,kBAAkB,KAAK;AAAA,MAC/E;AACA,YAAM,eAAe,QAAQ,WAAW,KAAK;AAC7C,YAAM,MAAM,GAAG,OAAO,uBAAuB;AAAA,QAC3C,UAAU,IAAI;AAAA,QACd,gBAAgB,IAAI,kBAAkB;AAAA,QACtC,SAAS,MAAM;AAAA,QACf,SAAS;AAAA,QACT,UAAU;AAAA,QACV,OAAO,MAAM,SAAS;AAAA,QACtB,iBAAiB,IAAI,UAAU;AAAA,MACjC,CAAqC;AACrC,YAAM,GAAG,QAAQ,GAAG,EAAE,MAAM;AAC5B,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,SAAS,iBACP,UACwB;AACxB,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO,CAAC;AACvD,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,QAAS;AACd,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAEA,IAAO,0CAAQ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,223 @@
1
+ import {
2
+ findOneWithDecryption,
3
+ findWithDecryption
4
+ } from "@open-mercato/shared/lib/encryption/find";
5
+ import { AiPendingAction } from "../entities.js";
6
+ import {
7
+ AI_PENDING_ACTION_ALLOWED_TRANSITIONS,
8
+ AiPendingActionStateError,
9
+ resolveAiPendingActionTtlSeconds
10
+ } from "../../lib/pending-action-types.js";
11
+ class AiPendingActionRepository {
12
+ constructor(em) {
13
+ this.em = em;
14
+ }
15
+ async create(input, ctx) {
16
+ if (!ctx?.tenantId) {
17
+ throw new Error("AiPendingActionRepository.create requires tenantId");
18
+ }
19
+ if (!input?.agentId) {
20
+ throw new Error("AiPendingActionRepository.create requires agentId");
21
+ }
22
+ if (!input?.toolName) {
23
+ throw new Error("AiPendingActionRepository.create requires toolName");
24
+ }
25
+ if (!input?.idempotencyKey) {
26
+ throw new Error(
27
+ "AiPendingActionRepository.create requires idempotencyKey"
28
+ );
29
+ }
30
+ if (!input?.createdByUserId) {
31
+ throw new Error(
32
+ "AiPendingActionRepository.create requires createdByUserId"
33
+ );
34
+ }
35
+ const now = input.now ?? /* @__PURE__ */ new Date();
36
+ const ttlSeconds = Math.max(
37
+ 1,
38
+ Math.floor(
39
+ typeof input.ttlSeconds === "number" && Number.isFinite(input.ttlSeconds) ? input.ttlSeconds : resolveAiPendingActionTtlSeconds()
40
+ )
41
+ );
42
+ const expiresAt = new Date(now.getTime() + ttlSeconds * 1e3);
43
+ return this.em.transactional(async (tx) => {
44
+ const existing = await findOneWithDecryption(
45
+ tx,
46
+ AiPendingAction,
47
+ {
48
+ tenantId: ctx.tenantId,
49
+ organizationId: ctx.organizationId ?? null,
50
+ idempotencyKey: input.idempotencyKey
51
+ },
52
+ { orderBy: { createdAt: "desc" } },
53
+ {
54
+ tenantId: ctx.tenantId ?? null,
55
+ organizationId: ctx.organizationId ?? null
56
+ }
57
+ );
58
+ if (existing && existing.status === "pending") {
59
+ return existing;
60
+ }
61
+ if (existing && (existing.status === "failed" || existing.status === "cancelled" || existing.status === "expired")) {
62
+ await tx.remove(existing).flush();
63
+ }
64
+ const row = tx.create(AiPendingAction, {
65
+ tenantId: ctx.tenantId,
66
+ organizationId: ctx.organizationId ?? null,
67
+ agentId: input.agentId,
68
+ toolName: input.toolName,
69
+ conversationId: input.conversationId ?? null,
70
+ targetEntityType: input.targetEntityType ?? null,
71
+ targetRecordId: input.targetRecordId ?? null,
72
+ normalizedInput: input.normalizedInput ?? {},
73
+ fieldDiff: Array.isArray(input.fieldDiff) ? input.fieldDiff : [],
74
+ records: normalizeRecords(input.records),
75
+ failedRecords: null,
76
+ sideEffectsSummary: input.sideEffectsSummary ?? null,
77
+ recordVersion: input.recordVersion ?? null,
78
+ attachmentIds: Array.isArray(input.attachmentIds) ? input.attachmentIds : [],
79
+ idempotencyKey: input.idempotencyKey,
80
+ createdByUserId: input.createdByUserId,
81
+ status: "pending",
82
+ queueMode: input.queueMode ?? "inline",
83
+ executionResult: null,
84
+ createdAt: now,
85
+ expiresAt,
86
+ resolvedAt: null,
87
+ resolvedByUserId: null
88
+ });
89
+ await tx.persist(row).flush();
90
+ return row;
91
+ });
92
+ }
93
+ async getById(id, ctx) {
94
+ if (!id || !ctx?.tenantId) return null;
95
+ const row = await findOneWithDecryption(
96
+ this.em,
97
+ AiPendingAction,
98
+ {
99
+ id,
100
+ tenantId: ctx.tenantId,
101
+ organizationId: ctx.organizationId ?? null
102
+ },
103
+ {},
104
+ {
105
+ tenantId: ctx.tenantId ?? null,
106
+ organizationId: ctx.organizationId ?? null
107
+ }
108
+ );
109
+ return row ?? null;
110
+ }
111
+ async listPendingForAgent(agentId, ctx, limit = 50) {
112
+ if (!agentId || !ctx?.tenantId) return [];
113
+ const capped = Math.max(1, Math.min(Math.floor(limit), 200));
114
+ const rows = await findWithDecryption(
115
+ this.em,
116
+ AiPendingAction,
117
+ {
118
+ tenantId: ctx.tenantId,
119
+ organizationId: ctx.organizationId ?? null,
120
+ agentId,
121
+ status: "pending"
122
+ },
123
+ {
124
+ orderBy: { createdAt: "desc" },
125
+ limit: capped
126
+ },
127
+ {
128
+ tenantId: ctx.tenantId ?? null,
129
+ organizationId: ctx.organizationId ?? null
130
+ }
131
+ );
132
+ return rows;
133
+ }
134
+ async setStatus(id, nextStatus, ctx, extra) {
135
+ if (!ctx?.tenantId) {
136
+ throw new Error("AiPendingActionRepository.setStatus requires tenantId");
137
+ }
138
+ if (!id) {
139
+ throw new Error("AiPendingActionRepository.setStatus requires id");
140
+ }
141
+ return this.em.transactional(async (tx) => {
142
+ const existing = await findOneWithDecryption(
143
+ tx,
144
+ AiPendingAction,
145
+ {
146
+ id,
147
+ tenantId: ctx.tenantId,
148
+ organizationId: ctx.organizationId ?? null
149
+ },
150
+ {},
151
+ {
152
+ tenantId: ctx.tenantId ?? null,
153
+ organizationId: ctx.organizationId ?? null
154
+ }
155
+ );
156
+ if (!existing) {
157
+ throw new Error(`AiPendingAction not found: ${id}`);
158
+ }
159
+ if (existing.status === nextStatus) {
160
+ return existing;
161
+ }
162
+ const allowed = AI_PENDING_ACTION_ALLOWED_TRANSITIONS[existing.status] ?? [];
163
+ if (!allowed.includes(nextStatus)) {
164
+ throw new AiPendingActionStateError(existing.status, nextStatus);
165
+ }
166
+ const now = extra?.now ?? /* @__PURE__ */ new Date();
167
+ existing.status = nextStatus;
168
+ if (nextStatus === "confirmed" || nextStatus === "cancelled" || nextStatus === "expired" || nextStatus === "failed") {
169
+ existing.resolvedAt = existing.resolvedAt ?? now;
170
+ if (extra && Object.prototype.hasOwnProperty.call(extra, "resolvedByUserId")) {
171
+ existing.resolvedByUserId = extra.resolvedByUserId ?? null;
172
+ } else if (nextStatus === "expired") {
173
+ existing.resolvedByUserId = null;
174
+ }
175
+ }
176
+ if (extra && Object.prototype.hasOwnProperty.call(extra, "executionResult")) {
177
+ existing.executionResult = extra.executionResult ?? null;
178
+ }
179
+ if (extra && Object.prototype.hasOwnProperty.call(extra, "failedRecords")) {
180
+ existing.failedRecords = normalizeFailedRecords(extra.failedRecords);
181
+ }
182
+ await tx.persist(existing).flush();
183
+ return existing;
184
+ });
185
+ }
186
+ async listExpired(ctx, now, limit = 100) {
187
+ if (!ctx?.tenantId) return [];
188
+ const capped = Math.max(1, Math.min(Math.floor(limit), 500));
189
+ const rows = await findWithDecryption(
190
+ this.em,
191
+ AiPendingAction,
192
+ {
193
+ tenantId: ctx.tenantId,
194
+ organizationId: ctx.organizationId ?? null,
195
+ status: "pending",
196
+ expiresAt: { $lt: now }
197
+ },
198
+ {
199
+ orderBy: { expiresAt: "asc" },
200
+ limit: capped
201
+ },
202
+ {
203
+ tenantId: ctx.tenantId ?? null,
204
+ organizationId: ctx.organizationId ?? null
205
+ }
206
+ );
207
+ return rows;
208
+ }
209
+ }
210
+ function normalizeRecords(records) {
211
+ if (!Array.isArray(records) || records.length === 0) return null;
212
+ return records;
213
+ }
214
+ function normalizeFailedRecords(failed) {
215
+ if (!Array.isArray(failed) || failed.length === 0) return null;
216
+ return failed;
217
+ }
218
+ var AiPendingActionRepository_default = AiPendingActionRepository;
219
+ export {
220
+ AiPendingActionRepository,
221
+ AiPendingActionRepository_default as default
222
+ };
223
+ //# sourceMappingURL=AiPendingActionRepository.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/ai_assistant/data/repositories/AiPendingActionRepository.ts"],
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport {\n findOneWithDecryption,\n findWithDecryption,\n} from '@open-mercato/shared/lib/encryption/find'\nimport { AiPendingAction } from '../entities'\nimport {\n AI_PENDING_ACTION_ALLOWED_TRANSITIONS,\n AiPendingActionStateError,\n resolveAiPendingActionTtlSeconds,\n type AiPendingActionExecutionResult,\n type AiPendingActionFailedRecord,\n type AiPendingActionFieldDiff,\n type AiPendingActionQueueMode,\n type AiPendingActionRecordDiff,\n type AiPendingActionStatus,\n} from '../../lib/pending-action-types'\n\nexport interface AiPendingActionContext {\n tenantId: string\n organizationId?: string | null\n userId?: string | null\n}\n\nexport interface AiPendingActionCreateInput {\n agentId: string\n toolName: string\n idempotencyKey: string\n createdByUserId: string\n normalizedInput: Record<string, unknown>\n conversationId?: string | null\n targetEntityType?: string | null\n targetRecordId?: string | null\n fieldDiff?: AiPendingActionFieldDiff[]\n records?: AiPendingActionRecordDiff[] | null\n sideEffectsSummary?: string | null\n recordVersion?: string | null\n attachmentIds?: string[]\n queueMode?: AiPendingActionQueueMode\n /** Optional explicit TTL in seconds; overrides the env/default TTL. */\n ttlSeconds?: number\n /** Optional explicit `now` for deterministic tests. */\n now?: Date\n}\n\nexport interface AiPendingActionSetStatusExtra {\n resolvedByUserId?: string | null\n executionResult?: AiPendingActionExecutionResult | null\n failedRecords?: AiPendingActionFailedRecord[] | null\n /** Optional explicit `now` for deterministic tests. */\n now?: Date\n}\n\n/**\n * Persistent store for the Phase 3 WS-C mutation approval gate (Step 5.5).\n *\n * Responsibilities:\n * - Create new pending rows with a TTL-derived `expiresAt`, honoring\n * idempotency within the window (same `idempotencyKey` returns the same\n * row as long as it is still `pending`; any terminal state mints a new row).\n * - Tenant-scoped lookups for the confirm/cancel/reconnect routes and the\n * in-app UI's \"open actions\" list.\n * - State-machine enforcement: `setStatus` rejects illegal transitions via\n * {@link AiPendingActionStateError}. The runtime callers translate this\n * to a 409 Conflict response.\n * - `listExpired` for the cleanup worker (Step 5.12).\n *\n * Every read goes through `findOneWithDecryption` / `findWithDecryption`\n * even though today no column is GDPR-flagged. This keeps the repo\n * consistent with the rest of the module and preps for a future encrypted\n * `normalizedInput` without a second refactor.\n */\nexport class AiPendingActionRepository {\n constructor(private readonly em: EntityManager) {}\n\n async create(\n input: AiPendingActionCreateInput,\n ctx: AiPendingActionContext,\n ): Promise<AiPendingAction> {\n if (!ctx?.tenantId) {\n throw new Error('AiPendingActionRepository.create requires tenantId')\n }\n if (!input?.agentId) {\n throw new Error('AiPendingActionRepository.create requires agentId')\n }\n if (!input?.toolName) {\n throw new Error('AiPendingActionRepository.create requires toolName')\n }\n if (!input?.idempotencyKey) {\n throw new Error(\n 'AiPendingActionRepository.create requires idempotencyKey',\n )\n }\n if (!input?.createdByUserId) {\n throw new Error(\n 'AiPendingActionRepository.create requires createdByUserId',\n )\n }\n\n const now = input.now ?? new Date()\n const ttlSeconds = Math.max(\n 1,\n Math.floor(\n typeof input.ttlSeconds === 'number' && Number.isFinite(input.ttlSeconds)\n ? input.ttlSeconds\n : resolveAiPendingActionTtlSeconds(),\n ),\n )\n const expiresAt = new Date(now.getTime() + ttlSeconds * 1000)\n\n return this.em.transactional(async (tx) => {\n const existing = await findOneWithDecryption<AiPendingAction>(\n tx as unknown as EntityManager,\n AiPendingAction,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n idempotencyKey: input.idempotencyKey,\n } as any,\n { orderBy: { createdAt: 'desc' } as any },\n {\n tenantId: ctx.tenantId ?? null,\n organizationId: ctx.organizationId ?? null,\n },\n )\n if (existing && existing.status === 'pending') {\n return existing\n }\n // Terminal stale row would collide on the unique\n // `(tenantId, organizationId, idempotencyKey)` constraint when we\n // try to insert a fresh one with the same hash \u2014 and that exact\n // collision happens whenever the operator clicks \"Fix with AI\"\n // and the model retries the SAME tool with the SAME args. Remove\n // the stale row first so a retry can always proceed; success rows\n // stay (they represent a real, applied change), and failed /\n // cancelled / expired rows are cleared because they're blocking\n // exactly the recovery flow they were created to enable.\n if (\n existing &&\n (existing.status === 'failed' ||\n existing.status === 'cancelled' ||\n existing.status === 'expired')\n ) {\n await tx.remove(existing).flush()\n }\n const row = tx.create(AiPendingAction, {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId: input.agentId,\n toolName: input.toolName,\n conversationId: input.conversationId ?? null,\n targetEntityType: input.targetEntityType ?? null,\n targetRecordId: input.targetRecordId ?? null,\n normalizedInput: input.normalizedInput ?? {},\n fieldDiff: Array.isArray(input.fieldDiff) ? input.fieldDiff : [],\n records: normalizeRecords(input.records),\n failedRecords: null,\n sideEffectsSummary: input.sideEffectsSummary ?? null,\n recordVersion: input.recordVersion ?? null,\n attachmentIds: Array.isArray(input.attachmentIds)\n ? input.attachmentIds\n : [],\n idempotencyKey: input.idempotencyKey,\n createdByUserId: input.createdByUserId,\n status: 'pending' as AiPendingActionStatus,\n queueMode: (input.queueMode ?? 'inline') as AiPendingActionQueueMode,\n executionResult: null,\n createdAt: now,\n expiresAt,\n resolvedAt: null,\n resolvedByUserId: null,\n } as unknown as AiPendingAction)\n await tx.persist(row).flush()\n return row\n })\n }\n\n async getById(\n id: string,\n ctx: AiPendingActionContext,\n ): Promise<AiPendingAction | null> {\n if (!id || !ctx?.tenantId) return null\n const row = await findOneWithDecryption<AiPendingAction>(\n this.em,\n AiPendingAction,\n {\n id,\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n } as any,\n {},\n {\n tenantId: ctx.tenantId ?? null,\n organizationId: ctx.organizationId ?? null,\n },\n )\n return row ?? null\n }\n\n async listPendingForAgent(\n agentId: string,\n ctx: AiPendingActionContext,\n limit: number = 50,\n ): Promise<AiPendingAction[]> {\n if (!agentId || !ctx?.tenantId) return []\n const capped = Math.max(1, Math.min(Math.floor(limit), 200))\n const rows = await findWithDecryption<AiPendingAction>(\n this.em,\n AiPendingAction,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n agentId,\n status: 'pending',\n } as any,\n {\n orderBy: { createdAt: 'desc' } as any,\n limit: capped,\n },\n {\n tenantId: ctx.tenantId ?? null,\n organizationId: ctx.organizationId ?? null,\n },\n )\n return rows\n }\n\n async setStatus(\n id: string,\n nextStatus: AiPendingActionStatus,\n ctx: AiPendingActionContext,\n extra?: AiPendingActionSetStatusExtra,\n ): Promise<AiPendingAction> {\n if (!ctx?.tenantId) {\n throw new Error('AiPendingActionRepository.setStatus requires tenantId')\n }\n if (!id) {\n throw new Error('AiPendingActionRepository.setStatus requires id')\n }\n return this.em.transactional(async (tx) => {\n const existing = await findOneWithDecryption<AiPendingAction>(\n tx as unknown as EntityManager,\n AiPendingAction,\n {\n id,\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n } as any,\n {},\n {\n tenantId: ctx.tenantId ?? null,\n organizationId: ctx.organizationId ?? null,\n },\n )\n if (!existing) {\n throw new Error(`AiPendingAction not found: ${id}`)\n }\n if (existing.status === nextStatus) {\n return existing\n }\n const allowed = AI_PENDING_ACTION_ALLOWED_TRANSITIONS[existing.status] ?? []\n if (!allowed.includes(nextStatus)) {\n throw new AiPendingActionStateError(existing.status, nextStatus)\n }\n const now = extra?.now ?? new Date()\n existing.status = nextStatus\n if (\n nextStatus === 'confirmed' ||\n nextStatus === 'cancelled' ||\n nextStatus === 'expired' ||\n nextStatus === 'failed'\n ) {\n existing.resolvedAt = existing.resolvedAt ?? now\n if (extra && Object.prototype.hasOwnProperty.call(extra, 'resolvedByUserId')) {\n existing.resolvedByUserId = extra.resolvedByUserId ?? null\n } else if (nextStatus === 'expired') {\n existing.resolvedByUserId = null\n }\n }\n if (extra && Object.prototype.hasOwnProperty.call(extra, 'executionResult')) {\n existing.executionResult = extra.executionResult ?? null\n }\n if (extra && Object.prototype.hasOwnProperty.call(extra, 'failedRecords')) {\n existing.failedRecords = normalizeFailedRecords(extra.failedRecords)\n }\n await tx.persist(existing).flush()\n return existing\n })\n }\n\n async listExpired(\n ctx: AiPendingActionContext,\n now: Date,\n limit: number = 100,\n ): Promise<AiPendingAction[]> {\n if (!ctx?.tenantId) return []\n const capped = Math.max(1, Math.min(Math.floor(limit), 500))\n const rows = await findWithDecryption<AiPendingAction>(\n this.em,\n AiPendingAction,\n {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId ?? null,\n status: 'pending',\n expiresAt: { $lt: now } as any,\n } as any,\n {\n orderBy: { expiresAt: 'asc' } as any,\n limit: capped,\n },\n {\n tenantId: ctx.tenantId ?? null,\n organizationId: ctx.organizationId ?? null,\n },\n )\n return rows\n }\n}\n\nfunction normalizeRecords(\n records: AiPendingActionRecordDiff[] | null | undefined,\n): AiPendingActionRecordDiff[] | null {\n if (!Array.isArray(records) || records.length === 0) return null\n return records\n}\n\nfunction normalizeFailedRecords(\n failed: AiPendingActionFailedRecord[] | null | undefined,\n): AiPendingActionFailedRecord[] | null {\n if (!Array.isArray(failed) || failed.length === 0) return null\n return failed\n}\n\nexport default AiPendingActionRepository\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,33 @@
1
+ import { createModuleEvents } from "@open-mercato/shared/modules/events";
2
+ const events = [
3
+ {
4
+ id: "ai.action.confirmed",
5
+ label: "AI Pending Action Confirmed",
6
+ entity: "ai_pending_action",
7
+ category: "system"
8
+ },
9
+ {
10
+ id: "ai.action.cancelled",
11
+ label: "AI Pending Action Cancelled",
12
+ entity: "ai_pending_action",
13
+ category: "system"
14
+ },
15
+ {
16
+ id: "ai.action.expired",
17
+ label: "AI Pending Action Expired",
18
+ entity: "ai_pending_action",
19
+ category: "system"
20
+ }
21
+ ];
22
+ const eventsConfig = createModuleEvents({
23
+ moduleId: "ai_assistant",
24
+ events
25
+ });
26
+ const emitAiAssistantEvent = eventsConfig.emit;
27
+ var events_default = eventsConfig;
28
+ export {
29
+ events_default as default,
30
+ emitAiAssistantEvent,
31
+ eventsConfig
32
+ };
33
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/modules/ai_assistant/events.ts"],
4
+ "sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\n/**\n * AI Assistant Module Events\n *\n * Typed declarations for the pending-action lifecycle events emitted by\n * the Phase 3 WS-C mutation approval flow. The event IDs are FROZEN per\n * `BACKWARD_COMPATIBILITY.md` \u00A75 (contract surface #5) and MUST NOT be\n * renamed; additive payload changes are allowed.\n *\n * - `ai.action.confirmed` \u2014 emitted by `executePendingActionConfirm`\n * (Step 5.8) after the `pending \u2192 confirmed \u2192 executing \u2192 {confirmed|\n * failed}` transition. The handler's outcome lives in\n * `executionResult`; partial-stale rows carry the surviving stale\n * records via `failedRecords`.\n * - `ai.action.cancelled` \u2014 emitted by `executePendingActionCancel`\n * (Step 5.9) after the atomic `pending \u2192 cancelled` transition.\n * - `ai.action.expired` \u2014 emitted by the Step 5.9 expired short-circuit\n * AND by the Step 5.12 cleanup worker when the TTL elapses. The\n * worker is the actor in that path, so `resolvedByUserId` is NOT part\n * of the payload.\n */\nconst events = [\n {\n id: 'ai.action.confirmed',\n label: 'AI Pending Action Confirmed',\n entity: 'ai_pending_action',\n category: 'system' as const,\n },\n {\n id: 'ai.action.cancelled',\n label: 'AI Pending Action Cancelled',\n entity: 'ai_pending_action',\n category: 'system' as const,\n },\n {\n id: 'ai.action.expired',\n label: 'AI Pending Action Expired',\n entity: 'ai_pending_action',\n category: 'system' as const,\n },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'ai_assistant',\n events,\n})\n\n/** Type-safe event emitter for the ai_assistant module. */\nexport const emitAiAssistantEvent = eventsConfig.emit\n\n/** Event IDs declared by the ai_assistant module. */\nexport type AiAssistantEventId = (typeof events)[number]['id']\n\n/**\n * Typed payload contracts for each ai_assistant event. Payloads are\n * additive-only \u2014 extend existing fields rather than renaming/removing.\n */\nexport interface AiActionFailedRecordPayload {\n recordId: string\n error: { code: string; message: string }\n}\n\nexport interface AiActionExecutionResultPayload {\n recordId?: string\n commandName?: string\n error?: { code: string; message: string }\n}\n\nexport interface AiActionConfirmedPayload {\n pendingActionId: string\n agentId: string\n toolName: string\n status: string\n tenantId: string | null\n organizationId: string | null\n userId: string\n resolvedByUserId: string\n resolvedAt: string\n executionResult: AiActionExecutionResultPayload | null\n failedRecords?: AiActionFailedRecordPayload[] | null\n}\n\nexport interface AiActionCancelledPayload {\n pendingActionId: string\n agentId: string\n toolName: string\n status: string\n tenantId: string | null\n organizationId: string | null\n userId: string\n resolvedByUserId: string\n resolvedAt: string\n executionResult: AiActionExecutionResultPayload | null\n reason?: string\n}\n\nexport interface AiActionExpiredPayload {\n pendingActionId: string\n agentId: string\n toolName: string\n status: string\n tenantId: string | null\n organizationId: string | null\n userId: string | null\n resolvedByUserId: null\n resolvedAt: string\n expiresAt?: string\n expiredAt?: string\n}\n\nexport default eventsConfig\n"],
5
+ "mappings": "AAAA,SAAS,0BAA0B;AAsBnC,MAAM,SAAS;AAAA,EACb;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEO,MAAM,eAAe,mBAAmB;AAAA,EAC7C,UAAU;AAAA,EACV;AACF,CAAC;AAGM,MAAM,uBAAuB,aAAa;AA8DjD,IAAO,iBAAQ;",
6
+ "names": []
7
+ }