@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,389 @@
1
+ import {
2
+ registerModuleOverrideApplier,
3
+ type ModuleOverrideEntry,
4
+ } from '@open-mercato/shared/modules/overrides'
5
+
6
+ /**
7
+ * Module-to-module override pipeline for AI agents and AI tools.
8
+ *
9
+ * Modules contribute overrides through two surfaces:
10
+ *
11
+ * 1. Per-module: declare additional `aiAgentOverrides` / `aiToolOverrides`
12
+ * exports in the existing `<module>/ai-agents.ts` / `<module>/ai-tools.ts`
13
+ * files (no separate `ai-overrides.ts` file). The generator picks the
14
+ * exports up alongside `aiAgents` / `aiTools` and emits override entries
15
+ * inside `apps/<app>/.mercato/generated/ai-agents.generated.ts`
16
+ * (`aiAgentOverrideEntries`) and `ai-tools.generated.ts`
17
+ * (`aiToolOverrideEntries`).
18
+ *
19
+ * 2. App-level: declare `aiAgentOverrides` / `aiToolOverrides` directly on a
20
+ * `ModuleEntry` inside the app's `src/modules.ts`. {@link
21
+ * applyAiOverridesFromEnabledModules} feeds these into the runtime; they
22
+ * sit one tier higher than the per-module file-based entries but below
23
+ * explicit programmatic calls.
24
+ *
25
+ * Tests and bootstrap code can also override imperatively via
26
+ * {@link applyAiAgentOverrides} and {@link applyAiToolOverrides}, which
27
+ * supersede every other tier and persist for the process lifetime.
28
+ *
29
+ * `null` always means "remove from the registry"; a definition replaces.
30
+ *
31
+ * @see ../../../../../../.ai/specs/2026-04-30-ai-overrides-and-module-disable.md
32
+ */
33
+ import type { AiAgentDefinition, AiAgentExtension } from './ai-agent-definition'
34
+ import type { AiToolDefinition } from './types'
35
+
36
+ /** Override for a single agent: replace with a definition or remove with `null`. */
37
+ export type AiAgentOverride = AiAgentDefinition | null
38
+
39
+ /** Override for a single tool: replace with a definition or remove with `null`. */
40
+ export type AiToolOverride = AiToolDefinition | null
41
+
42
+ /** Map of agent id → override. Used in the per-module `ai-agents.ts` file. */
43
+ export type AiAgentOverridesMap = Record<string, AiAgentOverride>
44
+
45
+ /** Map of tool name → override. Used in the per-module `ai-tools.ts` file. */
46
+ export type AiToolOverridesMap = Record<string, AiToolOverride>
47
+
48
+ /**
49
+ * Per-entry shape produced by the agent generator. Mirrors the per-module
50
+ * record format used elsewhere in the registry generators so the file
51
+ * stays grep-friendly.
52
+ */
53
+ export interface AiAgentOverrideConfigEntry {
54
+ moduleId: string
55
+ overrides: AiAgentOverridesMap
56
+ }
57
+
58
+ export interface AiAgentExtensionConfigEntry {
59
+ moduleId: string
60
+ extensions: AiAgentExtension[]
61
+ }
62
+
63
+ /**
64
+ * Per-entry shape produced by the tool generator. Same record format as
65
+ * {@link AiAgentOverrideConfigEntry}, but with tool definitions.
66
+ */
67
+ export interface AiToolOverrideConfigEntry {
68
+ moduleId: string
69
+ overrides: AiToolOverridesMap
70
+ }
71
+
72
+ /** Shape of the `entry.overrides.ai` sub-tree on a `modules.ts` entry. */
73
+ export interface AiModuleOverridesShape {
74
+ agents?: AiAgentOverridesMap
75
+ tools?: AiToolOverridesMap
76
+ extensions?: AiAgentExtension[]
77
+ }
78
+
79
+ /** Shape of a `modules.ts` `ModuleEntry` with the umbrella `overrides.ai`. */
80
+ export interface EnabledModuleAiOverrides {
81
+ id: string
82
+ overrides?: { ai?: AiModuleOverridesShape }
83
+ }
84
+
85
+ const programmaticAgentOverrides: AiAgentOverridesMap = {}
86
+ const programmaticToolOverrides: AiToolOverridesMap = {}
87
+ const programmaticAgentExtensions: AiAgentExtension[] = []
88
+
89
+ const modulesConfigAgentOverrides: AiAgentOverridesMap = {}
90
+ const modulesConfigToolOverrides: AiToolOverridesMap = {}
91
+ const modulesConfigAgentExtensions: AiAgentExtension[] = []
92
+
93
+ /**
94
+ * Apply programmatic agent overrides — survive after the registries load
95
+ * and take precedence over both file-based and `modules.ts`-tier overrides
96
+ * for the same id.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * applyAiAgentOverrides({
101
+ * 'catalog.catalog_assistant': null, // disable
102
+ * 'catalog.merchandising_assistant': customAgent, // replace
103
+ * })
104
+ * ```
105
+ */
106
+ export function applyAiAgentOverrides(overrides: AiAgentOverridesMap): void {
107
+ for (const [id, value] of Object.entries(overrides)) {
108
+ programmaticAgentOverrides[id] = value
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Apply programmatic tool overrides — survive after the registries load
114
+ * and take precedence over both file-based and `modules.ts`-tier overrides
115
+ * for the same name.
116
+ */
117
+ export function applyAiToolOverrides(overrides: AiToolOverridesMap): void {
118
+ for (const [name, value] of Object.entries(overrides)) {
119
+ programmaticToolOverrides[name] = value
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Apply programmatic additive agent extensions. Extensions append to an
125
+ * already-registered agent after replacements/disable overrides resolve.
126
+ */
127
+ export function applyAiAgentExtensions(extensions: readonly AiAgentExtension[]): void {
128
+ programmaticAgentExtensions.push(...extensions)
129
+ }
130
+
131
+ /**
132
+ * Walk a list of `enabledModules` entries (the `apps/<app>/src/modules.ts`
133
+ * shape) and register their `overrides.ai.agents` / `overrides.ai.tools`
134
+ * into the `modules.ts` tier. Tier precedence (highest first):
135
+ *
136
+ * 1. {@link applyAiAgentOverrides} / {@link applyAiToolOverrides}
137
+ * 2. `modules.ts` inline (this function)
138
+ * 3. `<module>/ai-agents.ts` `aiAgentOverrides` / `<module>/ai-tools.ts`
139
+ * `aiToolOverrides`
140
+ * 4. base `aiAgents` / `aiTools`
141
+ *
142
+ * Calling this multiple times is additive: later calls overlay on the
143
+ * existing tier (last wins per id). Use only at boot time — re-entering
144
+ * mid-request blurs the resolution order.
145
+ *
146
+ * In practice this is invoked from `applyModuleOverridesFromEnabledModules`
147
+ * (the umbrella dispatcher in `@open-mercato/shared/modules/overrides`)
148
+ * via the registered `'ai'` applier; downstream apps call the dispatcher
149
+ * once from `bootstrap.ts`. The standalone signature is kept for tests
150
+ * and ad-hoc use.
151
+ */
152
+ export function applyAiOverridesFromEnabledModules(
153
+ modules: ReadonlyArray<EnabledModuleAiOverrides>,
154
+ ): void {
155
+ for (const entry of modules) {
156
+ if (!entry || typeof entry.id !== 'string' || !entry.id) continue
157
+ const ai = entry.overrides?.ai
158
+ if (!ai || typeof ai !== 'object') continue
159
+ if (ai.agents && typeof ai.agents === 'object') {
160
+ for (const [id, value] of Object.entries(ai.agents)) {
161
+ modulesConfigAgentOverrides[id] = value as AiAgentOverride
162
+ }
163
+ }
164
+ if (ai.tools && typeof ai.tools === 'object') {
165
+ for (const [name, value] of Object.entries(ai.tools)) {
166
+ modulesConfigToolOverrides[name] = value as AiToolOverride
167
+ }
168
+ }
169
+ if (Array.isArray(ai.extensions)) {
170
+ modulesConfigAgentExtensions.push(...ai.extensions)
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Bucketed entry shape passed to the umbrella dispatcher's per-domain
177
+ * applier. Each entry carries one module's `overrides.ai` sub-tree.
178
+ */
179
+ type AiOverrideEntryFromDispatcher = {
180
+ moduleId: string
181
+ overrides: AiModuleOverridesShape
182
+ }
183
+
184
+ /**
185
+ * Applier registered with `@open-mercato/shared/modules/overrides` for
186
+ * the `'ai'` domain. The dispatcher hands us per-module entries already
187
+ * scoped to `overrides.ai`; we re-shape into `EnabledModuleAiOverrides`
188
+ * and reuse {@link applyAiOverridesFromEnabledModules} so the AI tier
189
+ * has exactly one code path.
190
+ */
191
+ export function applyAiOverridesDispatcherEntries(
192
+ entries: ReadonlyArray<AiOverrideEntryFromDispatcher>,
193
+ ): void {
194
+ applyAiOverridesFromEnabledModules(
195
+ entries.map((entry) => ({
196
+ id: entry.moduleId,
197
+ overrides: { ai: entry.overrides },
198
+ })),
199
+ )
200
+ }
201
+
202
+ // Side-effect: register the `'ai'` applier on first module load so the
203
+ // umbrella dispatcher in `@open-mercato/shared/modules/overrides` can
204
+ // route `entry.overrides.ai` here. Any consumer that imports
205
+ // `@open-mercato/ai-assistant` (which apps do via `bootstrap.ts`) gets
206
+ // the registration for free — no second import needed.
207
+ registerModuleOverrideApplier<AiModuleOverridesShape>(
208
+ 'ai',
209
+ (entries: ReadonlyArray<ModuleOverrideEntry<AiModuleOverridesShape>>) => {
210
+ applyAiOverridesDispatcherEntries(entries)
211
+ },
212
+ )
213
+
214
+ /** @__internal Test-only hook — reset programmatic + modules.ts override state. */
215
+ export function resetProgrammaticOverridesForTests(): void {
216
+ for (const key of Object.keys(programmaticAgentOverrides)) {
217
+ delete programmaticAgentOverrides[key]
218
+ }
219
+ for (const key of Object.keys(programmaticToolOverrides)) {
220
+ delete programmaticToolOverrides[key]
221
+ }
222
+ for (const key of Object.keys(modulesConfigAgentOverrides)) {
223
+ delete modulesConfigAgentOverrides[key]
224
+ }
225
+ for (const key of Object.keys(modulesConfigToolOverrides)) {
226
+ delete modulesConfigToolOverrides[key]
227
+ }
228
+ programmaticAgentExtensions.length = 0
229
+ modulesConfigAgentExtensions.length = 0
230
+ }
231
+
232
+ /**
233
+ * Resolve the final agent override map from a list of file-based entries
234
+ * plus the `modules.ts` and programmatic state.
235
+ *
236
+ * Resolution order (lowest precedence → highest):
237
+ * 1. file entries in module load order
238
+ * 2. modules.ts entries
239
+ * 3. programmatic
240
+ */
241
+ export function composeAgentOverrideMap(
242
+ fileEntries: readonly AiAgentOverrideConfigEntry[],
243
+ ): AiAgentOverridesMap {
244
+ const out: AiAgentOverridesMap = {}
245
+ for (const entry of fileEntries) {
246
+ const overrides = entry?.overrides
247
+ if (!overrides || typeof overrides !== 'object') continue
248
+ for (const [id, value] of Object.entries(overrides)) {
249
+ if (typeof id !== 'string' || !id) continue
250
+ out[id] = value as AiAgentOverride
251
+ }
252
+ }
253
+ for (const [id, value] of Object.entries(modulesConfigAgentOverrides)) {
254
+ out[id] = value
255
+ }
256
+ for (const [id, value] of Object.entries(programmaticAgentOverrides)) {
257
+ out[id] = value
258
+ }
259
+ return out
260
+ }
261
+
262
+ /**
263
+ * Resolve the final tool override map from a list of file-based entries
264
+ * plus the `modules.ts` and programmatic state.
265
+ */
266
+ export function composeToolOverrideMap(
267
+ fileEntries: readonly AiToolOverrideConfigEntry[],
268
+ ): AiToolOverridesMap {
269
+ const out: AiToolOverridesMap = {}
270
+ for (const entry of fileEntries) {
271
+ const overrides = entry?.overrides
272
+ if (!overrides || typeof overrides !== 'object') continue
273
+ for (const [name, value] of Object.entries(overrides)) {
274
+ if (typeof name !== 'string' || !name) continue
275
+ out[name] = value as AiToolOverride
276
+ }
277
+ }
278
+ for (const [name, value] of Object.entries(modulesConfigToolOverrides)) {
279
+ out[name] = value
280
+ }
281
+ for (const [name, value] of Object.entries(programmaticToolOverrides)) {
282
+ out[name] = value
283
+ }
284
+ return out
285
+ }
286
+
287
+ export function composeAgentExtensionEntries(
288
+ fileEntries: readonly AiAgentExtensionConfigEntry[],
289
+ ): AiAgentExtension[] {
290
+ const out: AiAgentExtension[] = []
291
+ for (const entry of fileEntries) {
292
+ if (Array.isArray(entry?.extensions)) out.push(...entry.extensions)
293
+ }
294
+ out.push(...modulesConfigAgentExtensions)
295
+ out.push(...programmaticAgentExtensions)
296
+ return out
297
+ }
298
+
299
+ /**
300
+ * Apply an agent override map to a base list. Returns a new array.
301
+ * `null` removes the entry; a non-null override replaces it. Override
302
+ * entries naming an id that is not in `base` log a structured warning so
303
+ * an operator can spot stale override files.
304
+ */
305
+ export function applyAgentOverrideMap(
306
+ base: readonly AiAgentDefinition[],
307
+ overrides: AiAgentOverridesMap,
308
+ ): AiAgentDefinition[] {
309
+ if (!overrides || Object.keys(overrides).length === 0) return base.slice()
310
+ const byId = new Map<string, AiAgentDefinition>()
311
+ for (const agent of base) {
312
+ if (agent && typeof agent.id === 'string' && agent.id) {
313
+ byId.set(agent.id, agent)
314
+ }
315
+ }
316
+ for (const [id, value] of Object.entries(overrides)) {
317
+ if (!byId.has(id) && value !== null) {
318
+ // Allow registering a brand-new agent through the override surface
319
+ // — useful for app-level "synthetic" agents without authoring a
320
+ // module file. Warn at the structured logger so the operator
321
+ // notices a stale id slipping through.
322
+ console.warn(
323
+ `[AI Overrides] Override registers a new agent "${id}" — no base entry to replace.`,
324
+ )
325
+ }
326
+ if (value === null) {
327
+ byId.delete(id)
328
+ continue
329
+ }
330
+ if (!value || typeof value.id !== 'string' || value.id !== id) {
331
+ console.warn(
332
+ `[AI Overrides] Skipping malformed agent override for id "${id}" — id mismatch or missing fields.`,
333
+ )
334
+ continue
335
+ }
336
+ byId.set(id, value)
337
+ }
338
+ return Array.from(byId.values())
339
+ }
340
+
341
+ /**
342
+ * Apply a tool override map to a base map. Returns a new Map.
343
+ * `null` removes the entry; a non-null override replaces it.
344
+ */
345
+ export function applyToolOverrideMap<TTool extends { name: string }>(
346
+ base: ReadonlyMap<string, TTool>,
347
+ overrides: Record<string, TTool | null | undefined>,
348
+ ): Map<string, TTool> {
349
+ const out = new Map<string, TTool>(base)
350
+ if (!overrides) return out
351
+ for (const [name, value] of Object.entries(overrides)) {
352
+ if (value === null) {
353
+ out.delete(name)
354
+ continue
355
+ }
356
+ if (value === undefined) continue
357
+ if (!value || typeof (value as TTool).name !== 'string' || (value as TTool).name !== name) {
358
+ console.warn(
359
+ `[AI Overrides] Skipping malformed tool override for name "${name}" — name mismatch or missing fields.`,
360
+ )
361
+ continue
362
+ }
363
+ out.set(name, value as TTool)
364
+ }
365
+ return out
366
+ }
367
+
368
+ /**
369
+ * @__internal — read the snapshot of programmatic + modules.ts overrides.
370
+ * Used by tests and by the diagnostic helper that reports which overrides
371
+ * are in effect.
372
+ */
373
+ export function snapshotProgrammaticOverrides(): {
374
+ agents: Readonly<AiAgentOverridesMap>
375
+ tools: Readonly<AiToolOverridesMap>
376
+ modulesConfigAgents: Readonly<AiAgentOverridesMap>
377
+ modulesConfigTools: Readonly<AiToolOverridesMap>
378
+ agentExtensions: readonly AiAgentExtension[]
379
+ modulesConfigAgentExtensions: readonly AiAgentExtension[]
380
+ } {
381
+ return {
382
+ agents: { ...programmaticAgentOverrides },
383
+ tools: { ...programmaticToolOverrides },
384
+ modulesConfigAgents: { ...modulesConfigAgentOverrides },
385
+ modulesConfigTools: { ...modulesConfigToolOverrides },
386
+ agentExtensions: programmaticAgentExtensions.slice(),
387
+ modulesConfigAgentExtensions: modulesConfigAgentExtensions.slice(),
388
+ }
389
+ }
@@ -0,0 +1,7 @@
1
+ import type { AiToolDefinition } from './types'
2
+
3
+ export function defineAiTool<TInput = unknown, TOutput = unknown>(
4
+ tool: AiToolDefinition<TInput, TOutput>,
5
+ ): AiToolDefinition<TInput, TOutput> {
6
+ return tool
7
+ }
@@ -0,0 +1,7 @@
1
+ declare module '@/.mercato/generated/ai-tools.generated' {
2
+ export const aiToolConfigEntries: Array<{
3
+ moduleId: string
4
+ tools: unknown[]
5
+ }>
6
+ export const allAiTools: unknown[]
7
+ }
@@ -0,0 +1,85 @@
1
+ // Phase 2 of spec 2026-04-27-ai-tools-api-backed-dry-refactor.md.
2
+ //
3
+ // Sugar over `defineAiTool` that wires the in-process API operation runner so
4
+ // typed AI tools can reuse documented API route logic without HTTP, fetch, or
5
+ // a second RBAC pass. The synthesized handler delegates to
6
+ // `createAiApiOperationRunner(ctx).run(toOperation(input, ctx))` and pipes the
7
+ // response through `mapResponse(...)`. All other tool-runtime concerns
8
+ // (registry indexing, schema serialization, mutation policy, pending-action
9
+ // flow, `loadBeforeRecord(s)`, telemetry) remain owned by `defineAiTool`.
10
+ import type { z } from 'zod'
11
+ import { defineAiTool } from './ai-tool-definition'
12
+ import {
13
+ createAiApiOperationRunner,
14
+ type AiApiOperationRequest,
15
+ type AiApiOperationResponse,
16
+ type AiToolExecutionContext,
17
+ } from './ai-api-operation-runner'
18
+ import type { AiToolDefinition, McpToolContext } from './types'
19
+
20
+ export type ApiBackedAiToolConfig<TInput, TApi, TOutput> = {
21
+ name: string
22
+ displayName?: string
23
+ description: string
24
+ inputSchema: z.ZodType<TInput>
25
+ requiredFeatures: string[]
26
+ isMutation?: boolean
27
+ toOperation: (
28
+ input: TInput,
29
+ ctx: AiToolExecutionContext,
30
+ ) => AiApiOperationRequest | Promise<AiApiOperationRequest>
31
+ mapResponse: (
32
+ response: AiApiOperationResponse<TApi>,
33
+ input: TInput,
34
+ ctx: AiToolExecutionContext,
35
+ ) => TOutput | Promise<TOutput>
36
+ loadBeforeRecord?: AiToolDefinition<TInput, TOutput>['loadBeforeRecord']
37
+ loadBeforeRecords?: AiToolDefinition<TInput, TOutput>['loadBeforeRecords']
38
+ }
39
+
40
+ export function defineApiBackedAiTool<TInput, TApi, TOutput>(
41
+ config: ApiBackedAiToolConfig<TInput, TApi, TOutput>,
42
+ ): AiToolDefinition<TInput, TOutput> {
43
+ const {
44
+ name,
45
+ displayName,
46
+ description,
47
+ inputSchema,
48
+ requiredFeatures,
49
+ isMutation,
50
+ toOperation,
51
+ mapResponse,
52
+ loadBeforeRecord,
53
+ loadBeforeRecords,
54
+ } = config
55
+
56
+ let definition: AiToolDefinition<TInput, TOutput>
57
+
58
+ const handler = async (input: TInput, context: McpToolContext): Promise<TOutput> => {
59
+ const toolCtx: AiToolExecutionContext = {
60
+ ...context,
61
+ tool: definition as unknown as AiToolDefinition,
62
+ }
63
+ const operation = await toOperation(input, toolCtx)
64
+ const runner = createAiApiOperationRunner(toolCtx)
65
+ const response = await runner.run<TApi>(operation)
66
+ if (!response.success) {
67
+ throw new Error(response.error ?? `API operation failed for tool "${name}"`)
68
+ }
69
+ return await mapResponse(response, input, toolCtx)
70
+ }
71
+
72
+ definition = defineAiTool<TInput, TOutput>({
73
+ name,
74
+ description,
75
+ inputSchema,
76
+ requiredFeatures,
77
+ handler,
78
+ ...(displayName !== undefined ? { displayName } : {}),
79
+ ...(isMutation !== undefined ? { isMutation } : {}),
80
+ ...(loadBeforeRecord !== undefined ? { loadBeforeRecord } : {}),
81
+ ...(loadBeforeRecords !== undefined ? { loadBeforeRecords } : {}),
82
+ })
83
+
84
+ return definition
85
+ }
@@ -0,0 +1,24 @@
1
+ export type AttachmentSource = 'bytes' | 'signed-url' | 'text' | 'metadata-only'
2
+
3
+ export interface AiResolvedAttachmentPart {
4
+ attachmentId: string
5
+ fileName: string
6
+ mediaType: string
7
+ source: AttachmentSource
8
+ textContent?: string | null
9
+ url?: string | null
10
+ data?: Uint8Array | string | null
11
+ }
12
+
13
+ export interface AiUiPart {
14
+ componentId: string
15
+ props: Record<string, unknown>
16
+ }
17
+
18
+ export interface AiChatRequestContext {
19
+ tenantId: string | null
20
+ organizationId: string | null
21
+ userId: string
22
+ features: string[]
23
+ isSuperAdmin: boolean
24
+ }