@adonis-agora/agent 0.1.0

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 (314) hide show
  1. package/LICENSE +21 -0
  2. package/dist/configure.d.ts +18 -0
  3. package/dist/configure.d.ts.map +1 -0
  4. package/dist/configure.js +29 -0
  5. package/dist/configure.js.map +1 -0
  6. package/dist/providers/agent_provider.d.ts +25 -0
  7. package/dist/providers/agent_provider.d.ts.map +1 -0
  8. package/dist/providers/agent_provider.js +511 -0
  9. package/dist/providers/agent_provider.js.map +1 -0
  10. package/dist/src/actor-resolver.d.ts +41 -0
  11. package/dist/src/actor-resolver.d.ts.map +1 -0
  12. package/dist/src/agent-deps-factory.d.ts +59 -0
  13. package/dist/src/agent-deps-factory.d.ts.map +1 -0
  14. package/dist/src/agent-deps-factory.js +111 -0
  15. package/dist/src/agent-deps-factory.js.map +1 -0
  16. package/dist/src/agent-deps.d.ts +42 -0
  17. package/dist/src/agent-deps.d.ts.map +1 -0
  18. package/dist/src/agent-deps.js +5 -0
  19. package/dist/src/agent-deps.js.map +1 -0
  20. package/dist/src/agent-loop.d.ts +101 -0
  21. package/dist/src/agent-loop.d.ts.map +1 -0
  22. package/dist/src/agent-loop.js +396 -0
  23. package/dist/src/agent-loop.js.map +1 -0
  24. package/dist/src/agent-registry.d.ts +10 -0
  25. package/dist/src/agent-registry.d.ts.map +1 -0
  26. package/dist/src/agent-service.d.ts +50 -0
  27. package/dist/src/agent-service.d.ts.map +1 -0
  28. package/dist/src/agent-service.js +82 -0
  29. package/dist/src/agent-service.js.map +1 -0
  30. package/dist/src/ai-sdk/ai-sdk-model.d.ts +17 -0
  31. package/dist/src/ai-sdk/ai-sdk-model.d.ts.map +1 -0
  32. package/dist/src/ai-sdk/ai-sdk-model.js +263 -0
  33. package/dist/src/ai-sdk/ai-sdk-model.js.map +1 -0
  34. package/dist/src/ai-sdk/index.d.ts +2 -0
  35. package/dist/src/ai-sdk/index.d.ts.map +1 -0
  36. package/dist/src/ai-tool-ref.d.ts +79 -0
  37. package/dist/src/ai-tool-ref.d.ts.map +1 -0
  38. package/dist/src/ai-tool-ref.js +81 -0
  39. package/dist/src/ai-tool-ref.js.map +1 -0
  40. package/dist/src/authorizer.d.ts +18 -0
  41. package/dist/src/authorizer.d.ts.map +1 -0
  42. package/dist/src/authz/authz-tool-authorizer.d.ts +85 -0
  43. package/dist/src/authz/authz-tool-authorizer.d.ts.map +1 -0
  44. package/dist/src/authz/authz-tool-authorizer.js +63 -0
  45. package/dist/src/authz/authz-tool-authorizer.js.map +1 -0
  46. package/dist/src/authz/index.d.ts +3 -0
  47. package/dist/src/authz/index.d.ts.map +1 -0
  48. package/dist/src/authz/index.js +2 -0
  49. package/dist/src/authz/index.js.map +1 -0
  50. package/dist/src/data/data-tool.d.ts +64 -0
  51. package/dist/src/data/data-tool.d.ts.map +1 -0
  52. package/dist/src/data/data-tool.js +146 -0
  53. package/dist/src/data/data-tool.js.map +1 -0
  54. package/dist/src/data/index.d.ts +7 -0
  55. package/dist/src/data/index.d.ts.map +1 -0
  56. package/dist/src/data/index.js +7 -0
  57. package/dist/src/data/index.js.map +1 -0
  58. package/dist/src/data/limit.d.ts +12 -0
  59. package/dist/src/data/limit.d.ts.map +1 -0
  60. package/dist/src/data/limit.js +29 -0
  61. package/dist/src/data/limit.js.map +1 -0
  62. package/dist/src/data/parser.d.ts +27 -0
  63. package/dist/src/data/parser.d.ts.map +1 -0
  64. package/dist/src/data/parser.js +18 -0
  65. package/dist/src/data/parser.js.map +1 -0
  66. package/dist/src/data/sql-validator.d.ts +37 -0
  67. package/dist/src/data/sql-validator.d.ts.map +1 -0
  68. package/dist/src/data/sql-validator.js +92 -0
  69. package/dist/src/data/sql-validator.js.map +1 -0
  70. package/dist/src/data/table-access.d.ts +40 -0
  71. package/dist/src/data/table-access.d.ts.map +1 -0
  72. package/dist/src/data/table-access.js +41 -0
  73. package/dist/src/data/table-access.js.map +1 -0
  74. package/dist/src/data/tenant-scope.d.ts +39 -0
  75. package/dist/src/data/tenant-scope.d.ts.map +1 -0
  76. package/dist/src/data/tenant-scope.js +126 -0
  77. package/dist/src/data/tenant-scope.js.map +1 -0
  78. package/dist/src/define_config.d.ts +153 -0
  79. package/dist/src/define_config.d.ts.map +1 -0
  80. package/dist/src/define_config.js +7 -0
  81. package/dist/src/define_config.js.map +1 -0
  82. package/dist/src/diagnostics.d.ts +82 -0
  83. package/dist/src/diagnostics.d.ts.map +1 -0
  84. package/dist/src/diagnostics.js +50 -0
  85. package/dist/src/diagnostics.js.map +1 -0
  86. package/dist/src/durable/agent-run-context.d.ts +24 -0
  87. package/dist/src/durable/agent-run-context.d.ts.map +1 -0
  88. package/dist/src/durable/agent-run-context.js +17 -0
  89. package/dist/src/durable/agent-run-context.js.map +1 -0
  90. package/dist/src/durable/agent-run-workflow.d.ts +37 -0
  91. package/dist/src/durable/agent-run-workflow.d.ts.map +1 -0
  92. package/dist/src/durable/agent-run-workflow.js +128 -0
  93. package/dist/src/durable/agent-run-workflow.js.map +1 -0
  94. package/dist/src/durable/durable-agent-runner.d.ts +25 -0
  95. package/dist/src/durable/durable-agent-runner.d.ts.map +1 -0
  96. package/dist/src/durable/durable-agent-runner.js +59 -0
  97. package/dist/src/durable/durable-agent-runner.js.map +1 -0
  98. package/dist/src/durable/index.d.ts +17 -0
  99. package/dist/src/durable/index.d.ts.map +1 -0
  100. package/dist/src/durable/index.js +20 -0
  101. package/dist/src/durable/index.js.map +1 -0
  102. package/dist/src/index.d.ts +55 -0
  103. package/dist/src/index.d.ts.map +1 -0
  104. package/dist/src/index.js +45 -0
  105. package/dist/src/index.js.map +1 -0
  106. package/dist/src/personas.d.ts +7 -0
  107. package/dist/src/personas.d.ts.map +1 -0
  108. package/dist/src/rag/chunk.d.ts +14 -0
  109. package/dist/src/rag/chunk.d.ts.map +1 -0
  110. package/dist/src/rag/chunk.js +42 -0
  111. package/dist/src/rag/chunk.js.map +1 -0
  112. package/dist/src/rag/embedding-retriever.d.ts +15 -0
  113. package/dist/src/rag/embedding-retriever.d.ts.map +1 -0
  114. package/dist/src/rag/embedding-retriever.js +24 -0
  115. package/dist/src/rag/embedding-retriever.js.map +1 -0
  116. package/dist/src/rag/filter.d.ts +6 -0
  117. package/dist/src/rag/filter.d.ts.map +1 -0
  118. package/dist/src/rag/filter.js +11 -0
  119. package/dist/src/rag/filter.js.map +1 -0
  120. package/dist/src/rag/index.d.ts +8 -0
  121. package/dist/src/rag/index.d.ts.map +1 -0
  122. package/dist/src/rag/index.js +8 -0
  123. package/dist/src/rag/index.js.map +1 -0
  124. package/dist/src/rag/ingest.d.ts +33 -0
  125. package/dist/src/rag/ingest.d.ts.map +1 -0
  126. package/dist/src/rag/ingest.js +37 -0
  127. package/dist/src/rag/ingest.js.map +1 -0
  128. package/dist/src/rag/memory-vector-store.d.ts +16 -0
  129. package/dist/src/rag/memory-vector-store.d.ts.map +1 -0
  130. package/dist/src/rag/memory-vector-store.js +70 -0
  131. package/dist/src/rag/memory-vector-store.js.map +1 -0
  132. package/dist/src/rag/pg-vector-store.d.ts +84 -0
  133. package/dist/src/rag/pg-vector-store.d.ts.map +1 -0
  134. package/dist/src/rag/pg-vector-store.js +220 -0
  135. package/dist/src/rag/pg-vector-store.js.map +1 -0
  136. package/dist/src/rag/vector-store.d.ts +47 -0
  137. package/dist/src/rag/vector-store.d.ts.map +1 -0
  138. package/dist/src/rag/vector-store.js +5 -0
  139. package/dist/src/rag/vector-store.js.map +1 -0
  140. package/dist/src/rag-media/diagnostics.d.ts +43 -0
  141. package/dist/src/rag-media/diagnostics.d.ts.map +1 -0
  142. package/dist/src/rag-media/diagnostics.js +36 -0
  143. package/dist/src/rag-media/diagnostics.js.map +1 -0
  144. package/dist/src/rag-media/index.d.ts +5 -0
  145. package/dist/src/rag-media/index.d.ts.map +1 -0
  146. package/dist/src/rag-media/index.js +5 -0
  147. package/dist/src/rag-media/index.js.map +1 -0
  148. package/dist/src/rag-media/media-events.d.ts +23 -0
  149. package/dist/src/rag-media/media-events.d.ts.map +1 -0
  150. package/dist/src/rag-media/media-events.js +28 -0
  151. package/dist/src/rag-media/media-events.js.map +1 -0
  152. package/dist/src/rag-media/media-rag-ingestion.d.ts +155 -0
  153. package/dist/src/rag-media/media-rag-ingestion.d.ts.map +1 -0
  154. package/dist/src/rag-media/media-rag-ingestion.js +204 -0
  155. package/dist/src/rag-media/media-rag-ingestion.js.map +1 -0
  156. package/dist/src/rag-media/text-extractor.d.ts +46 -0
  157. package/dist/src/rag-media/text-extractor.d.ts.map +1 -0
  158. package/dist/src/rag-media/text-extractor.js +92 -0
  159. package/dist/src/rag-media/text-extractor.js.map +1 -0
  160. package/dist/src/redis-stream-client.d.ts +29 -0
  161. package/dist/src/redis-stream-client.d.ts.map +1 -0
  162. package/dist/src/redis-stream-client.js +2 -0
  163. package/dist/src/redis-stream-client.js.map +1 -0
  164. package/dist/src/redis-token-stream-sink.d.ts +36 -0
  165. package/dist/src/redis-token-stream-sink.d.ts.map +1 -0
  166. package/dist/src/redis-token-stream-sink.js +94 -0
  167. package/dist/src/redis-token-stream-sink.js.map +1 -0
  168. package/dist/src/runners/inline-agent-runner.d.ts +26 -0
  169. package/dist/src/runners/inline-agent-runner.d.ts.map +1 -0
  170. package/dist/src/runners/inline-agent-runner.js +85 -0
  171. package/dist/src/runners/inline-agent-runner.js.map +1 -0
  172. package/dist/src/spi/actor-directory.d.ts +23 -0
  173. package/dist/src/spi/actor-directory.d.ts.map +1 -0
  174. package/dist/src/spi/actor-directory.js +2 -0
  175. package/dist/src/spi/actor-directory.js.map +1 -0
  176. package/dist/src/spi/actor-resolver.d.ts +18 -0
  177. package/dist/src/spi/actor-resolver.d.ts.map +1 -0
  178. package/dist/src/spi/agent-runner.d.ts +20 -0
  179. package/dist/src/spi/agent-runner.d.ts.map +1 -0
  180. package/dist/src/spi/agent-store.d.ts +104 -0
  181. package/dist/src/spi/agent-store.d.ts.map +1 -0
  182. package/dist/src/spi/agent-store.js +2 -0
  183. package/dist/src/spi/agent-store.js.map +1 -0
  184. package/dist/src/spi/attachment-staging.d.ts +27 -0
  185. package/dist/src/spi/attachment-staging.d.ts.map +1 -0
  186. package/dist/src/spi/attachment-staging.js +2 -0
  187. package/dist/src/spi/attachment-staging.js.map +1 -0
  188. package/dist/src/spi/embedding-provider.d.ts +12 -0
  189. package/dist/src/spi/embedding-provider.d.ts.map +1 -0
  190. package/dist/src/spi/embedding-provider.js +2 -0
  191. package/dist/src/spi/embedding-provider.js.map +1 -0
  192. package/dist/src/spi/governance-queries.d.ts +215 -0
  193. package/dist/src/spi/governance-queries.d.ts.map +1 -0
  194. package/dist/src/spi/governance-queries.js +15 -0
  195. package/dist/src/spi/governance-queries.js.map +1 -0
  196. package/dist/src/spi/model-provider.d.ts +41 -0
  197. package/dist/src/spi/model-provider.d.ts.map +1 -0
  198. package/dist/src/spi/pricing-store.d.ts +45 -0
  199. package/dist/src/spi/pricing-store.d.ts.map +1 -0
  200. package/dist/src/spi/pricing-store.js +24 -0
  201. package/dist/src/spi/pricing-store.js.map +1 -0
  202. package/dist/src/spi/quota-store.d.ts +7 -0
  203. package/dist/src/spi/quota-store.d.ts.map +1 -0
  204. package/dist/src/spi/reranker.d.ts +17 -0
  205. package/dist/src/spi/reranker.d.ts.map +1 -0
  206. package/dist/src/spi/reranker.js +2 -0
  207. package/dist/src/spi/reranker.js.map +1 -0
  208. package/dist/src/spi/retriever.d.ts +28 -0
  209. package/dist/src/spi/retriever.d.ts.map +1 -0
  210. package/dist/src/spi/retriever.js +11 -0
  211. package/dist/src/spi/retriever.js.map +1 -0
  212. package/dist/src/spi/roles-policy.d.ts +11 -0
  213. package/dist/src/spi/roles-policy.d.ts.map +1 -0
  214. package/dist/src/spi/tool.d.ts +21 -0
  215. package/dist/src/spi/tool.d.ts.map +1 -0
  216. package/dist/src/stores/factory.d.ts +363 -0
  217. package/dist/src/stores/factory.d.ts.map +1 -0
  218. package/dist/src/stores/factory.js +341 -0
  219. package/dist/src/stores/factory.js.map +1 -0
  220. package/dist/src/stores/ledger-quota.d.ts +23 -0
  221. package/dist/src/stores/ledger-quota.d.ts.map +1 -0
  222. package/dist/src/stores/ledger-quota.js +32 -0
  223. package/dist/src/stores/ledger-quota.js.map +1 -0
  224. package/dist/src/stores/lucid-governance-queries.d.ts +73 -0
  225. package/dist/src/stores/lucid-governance-queries.d.ts.map +1 -0
  226. package/dist/src/stores/lucid-governance-queries.js +510 -0
  227. package/dist/src/stores/lucid-governance-queries.js.map +1 -0
  228. package/dist/src/stores/lucid-pricing.d.ts +20 -0
  229. package/dist/src/stores/lucid-pricing.d.ts.map +1 -0
  230. package/dist/src/stores/lucid-pricing.js +67 -0
  231. package/dist/src/stores/lucid-pricing.js.map +1 -0
  232. package/dist/src/stores/lucid-schema.d.ts +37 -0
  233. package/dist/src/stores/lucid-schema.d.ts.map +1 -0
  234. package/dist/src/stores/lucid-schema.js +139 -0
  235. package/dist/src/stores/lucid-schema.js.map +1 -0
  236. package/dist/src/stores/lucid.d.ts +73 -0
  237. package/dist/src/stores/lucid.d.ts.map +1 -0
  238. package/dist/src/stores/lucid.js +400 -0
  239. package/dist/src/stores/lucid.js.map +1 -0
  240. package/dist/src/telescope/dashboard.d.ts +21 -0
  241. package/dist/src/telescope/dashboard.d.ts.map +1 -0
  242. package/dist/src/telescope/dashboard.js +140 -0
  243. package/dist/src/telescope/dashboard.js.map +1 -0
  244. package/dist/src/telescope/data-providers.d.ts +39 -0
  245. package/dist/src/telescope/data-providers.d.ts.map +1 -0
  246. package/dist/src/telescope/data-providers.js +345 -0
  247. package/dist/src/telescope/data-providers.js.map +1 -0
  248. package/dist/src/telescope/extension.d.ts +27 -0
  249. package/dist/src/telescope/extension.d.ts.map +1 -0
  250. package/dist/src/telescope/extension.js +45 -0
  251. package/dist/src/telescope/extension.js.map +1 -0
  252. package/dist/src/telescope/index.d.ts +5 -0
  253. package/dist/src/telescope/index.d.ts.map +1 -0
  254. package/dist/src/telescope/index.js +4 -0
  255. package/dist/src/telescope/index.js.map +1 -0
  256. package/dist/src/telescope/telescope-sdk.d.ts +126 -0
  257. package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
  258. package/dist/src/telescope/telescope-sdk.js +15 -0
  259. package/dist/src/telescope/telescope-sdk.js.map +1 -0
  260. package/dist/src/testing/fake-embedding-provider.d.ts +37 -0
  261. package/dist/src/testing/fake-embedding-provider.d.ts.map +1 -0
  262. package/dist/src/testing/fake-embedding-provider.js +67 -0
  263. package/dist/src/testing/fake-embedding-provider.js.map +1 -0
  264. package/dist/src/testing/fake-media.d.ts +44 -0
  265. package/dist/src/testing/fake-media.d.ts.map +1 -0
  266. package/dist/src/testing/fake-media.js +69 -0
  267. package/dist/src/testing/fake-media.js.map +1 -0
  268. package/dist/src/testing/fake-model-provider.d.ts +29 -0
  269. package/dist/src/testing/fake-model-provider.d.ts.map +1 -0
  270. package/dist/src/testing/in-memory-actor-directory.d.ts +14 -0
  271. package/dist/src/testing/in-memory-actor-directory.d.ts.map +1 -0
  272. package/dist/src/testing/in-memory-actor-directory.js +27 -0
  273. package/dist/src/testing/in-memory-actor-directory.js.map +1 -0
  274. package/dist/src/testing/in-memory-attachment-staging.d.ts +22 -0
  275. package/dist/src/testing/in-memory-attachment-staging.d.ts.map +1 -0
  276. package/dist/src/testing/in-memory-attachment-staging.js +28 -0
  277. package/dist/src/testing/in-memory-attachment-staging.js.map +1 -0
  278. package/dist/src/testing/in-memory-governance-queries.d.ts +34 -0
  279. package/dist/src/testing/in-memory-governance-queries.d.ts.map +1 -0
  280. package/dist/src/testing/in-memory-governance-queries.js +373 -0
  281. package/dist/src/testing/in-memory-governance-queries.js.map +1 -0
  282. package/dist/src/testing/in-memory-pricing.d.ts +13 -0
  283. package/dist/src/testing/in-memory-pricing.d.ts.map +1 -0
  284. package/dist/src/testing/in-memory-pricing.js +27 -0
  285. package/dist/src/testing/in-memory-pricing.js.map +1 -0
  286. package/dist/src/testing/in-memory-quota.d.ts +11 -0
  287. package/dist/src/testing/in-memory-quota.d.ts.map +1 -0
  288. package/dist/src/testing/in-memory-sink.d.ts +14 -0
  289. package/dist/src/testing/in-memory-sink.d.ts.map +1 -0
  290. package/dist/src/testing/in-memory-store.d.ts +119 -0
  291. package/dist/src/testing/in-memory-store.d.ts.map +1 -0
  292. package/dist/src/testing/in-memory-store.js +317 -0
  293. package/dist/src/testing/in-memory-store.js.map +1 -0
  294. package/dist/src/testing/index.d.ts +11 -0
  295. package/dist/src/testing/index.d.ts.map +1 -0
  296. package/dist/src/testing/index.js +11 -0
  297. package/dist/src/testing/index.js.map +1 -0
  298. package/dist/src/tool-discovery.d.ts +35 -0
  299. package/dist/src/tool-discovery.d.ts.map +1 -0
  300. package/dist/src/tool-registry.d.ts +45 -0
  301. package/dist/src/tool-registry.d.ts.map +1 -0
  302. package/dist/src/tool-retry.d.ts +56 -0
  303. package/dist/src/tool-retry.d.ts.map +1 -0
  304. package/dist/src/tool-retry.js +95 -0
  305. package/dist/src/tool-retry.js.map +1 -0
  306. package/dist/src/types.d.ts +222 -0
  307. package/dist/src/types.d.ts.map +1 -0
  308. package/dist/src/types.js +2 -0
  309. package/dist/src/types.js.map +1 -0
  310. package/dist/stubs/config/agent.stub +55 -0
  311. package/dist/stubs/database/migrations/create_agent_rag_chunks.stub +41 -0
  312. package/dist/stubs/database/migrations/create_agent_run_tracking.stub +80 -0
  313. package/dist/stubs/database/migrations/create_agent_tables.stub +113 -0
  314. package/package.json +174 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The `@adonis-agora/diagnostics` emit capability, published on this global slot at that package's
3
+ * module load. This bridge reads it STRUCTURALLY — it never imports or depends on the diagnostics
4
+ * package. When diagnostics isn't installed the slot is empty and emitting is an inert no-op that never
5
+ * throws back into an ingestion. Events land on `agora:rag:media.*`; the payload shapes below are the
6
+ * contract every observer (Telescope / dashboard) reads. Mirrors the agent core's `diagnostics.ts`.
7
+ */
8
+ const EMIT_SLOT = Symbol.for('@agora/diagnostics:emit');
9
+ /**
10
+ * Publish a rag-media event on `agora:rag:<event>` via the structural diagnostics slot. No-op when
11
+ * diagnostics isn't installed (the slot is empty) — and it never throws back into an ingestion.
12
+ */
13
+ export function publishRagMedia(event, payload) {
14
+ const emit = globalThis[EMIT_SLOT];
15
+ if (typeof emit === 'function') {
16
+ try {
17
+ emit('rag', event, payload);
18
+ }
19
+ catch {
20
+ // diagnostics must never break an ingestion
21
+ }
22
+ }
23
+ }
24
+ export function publishRagMediaIngested(payload) {
25
+ publishRagMedia('media.ingested', payload);
26
+ }
27
+ export function publishRagMediaRemoved(payload) {
28
+ publishRagMedia('media.removed', payload);
29
+ }
30
+ export function publishRagMediaSkipped(payload) {
31
+ publishRagMedia('media.skipped', payload);
32
+ }
33
+ export function publishRagMediaFailed(payload) {
34
+ publishRagMedia('media.failed', payload);
35
+ }
36
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../../src/rag-media/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AAwCxD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAQ,EACR,OAAsC;IAEtC,MAAM,IAAI,GAAI,UAAsC,CAAC,SAAS,CAAuB,CAAC;IACtF,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAgC;IACtE,eAAe,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAC,OAA+B;IACpE,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAC,OAA+B;IACpE,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AACD,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { type TextExtractor, type ExtractFn, MimeTextExtractor, UnsupportedContentTypeError, defaultTextExtractor, normalizeContentType, decodeUtf8, extractHtmlText, } from './text-extractor.js';
2
+ export { UPLOAD_COMPLETE_CHANNEL, type UploadCompletePayload, envelopePayload, isUploadCompleteEvent, } from './media-events.js';
3
+ export { mediaRagIngestion, MediaRagIngestion, MediaRagResolveRequiredError, type MediaRagIngestionConfig, type MediaManagerHandle, type DiskBytesReader, type MediaRef, type MediaIngestResult, type MediaIngestSkipReason, type ResolveMediaRef, } from './media-rag-ingestion.js';
4
+ export { publishRagMedia, publishRagMediaIngested, publishRagMediaRemoved, publishRagMediaSkipped, publishRagMediaFailed, type RagMediaDiagnosticEvent, type RagMediaDiagnosticPayloads, type RagMediaIngestedPayload, type RagMediaRemovedPayload, type RagMediaSkippedPayload, type RagMediaFailedPayload, type RagMediaSkipReason, } from './diagnostics.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rag-media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { MimeTextExtractor, UnsupportedContentTypeError, defaultTextExtractor, normalizeContentType, decodeUtf8, extractHtmlText, } from './text-extractor.js';
2
+ export { UPLOAD_COMPLETE_CHANNEL, envelopePayload, isUploadCompleteEvent, } from './media-events.js';
3
+ export { mediaRagIngestion, MediaRagIngestion, MediaRagResolveRequiredError, } from './media-rag-ingestion.js';
4
+ export { publishRagMedia, publishRagMediaIngested, publishRagMediaRemoved, publishRagMediaSkipped, publishRagMediaFailed, } from './diagnostics.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rag-media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,EAEvB,eAAe,EACf,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAQ7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,GAQtB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The `@adonis-agora/media` diagnostics contract this bridge reads, re-declared here so the
3
+ * integration couples to the *wire contract* (the `agora:media:*` channel) rather than importing the
4
+ * media package — `@adonis-agora/media` stays an OPTIONAL, structurally-typed peer. Keep these mirrors
5
+ * in sync with that library's core `diagnostics.ts` (`UploadCompletePayload`).
6
+ */
7
+ /** The channel a media library publishes `upload.complete` on: `agora:media:upload.complete`. */
8
+ export declare const UPLOAD_COMPLETE_CHANNEL = "agora:media:upload.complete";
9
+ /**
10
+ * Emitted on `agora:media:upload.complete` when a stored upload finishes. It carries only the media
11
+ * record `id`, the storage `disk`, and the object `key` — NOT the owner/collection/content-type — so
12
+ * auto-ingesting it needs a `resolve` seam back to the media record (see
13
+ * {@link import('./media-rag-ingestion.js').MediaRagIngestionConfig.resolve}).
14
+ */
15
+ export interface UploadCompletePayload {
16
+ id: string;
17
+ disk: string;
18
+ key: string;
19
+ }
20
+ /** Pull `.payload` off a diagnostics-channel message without an unguarded cast. */
21
+ export declare function envelopePayload(message: unknown): unknown;
22
+ export declare function isUploadCompleteEvent(payload: unknown): payload is UploadCompletePayload;
23
+ //# sourceMappingURL=media-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-events.d.ts","sourceRoot":"","sources":["../../../src/rag-media/media-events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iGAAiG;AACjG,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAOD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAKzD;AAMD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,qBAAqB,CAUxF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The `@adonis-agora/media` diagnostics contract this bridge reads, re-declared here so the
3
+ * integration couples to the *wire contract* (the `agora:media:*` channel) rather than importing the
4
+ * media package — `@adonis-agora/media` stays an OPTIONAL, structurally-typed peer. Keep these mirrors
5
+ * in sync with that library's core `diagnostics.ts` (`UploadCompletePayload`).
6
+ */
7
+ /** The channel a media library publishes `upload.complete` on: `agora:media:upload.complete`. */
8
+ export const UPLOAD_COMPLETE_CHANNEL = 'agora:media:upload.complete';
9
+ /** Pull `.payload` off a diagnostics-channel message without an unguarded cast. */
10
+ export function envelopePayload(message) {
11
+ if (typeof message === 'object' && message !== null && 'payload' in message) {
12
+ return message.payload;
13
+ }
14
+ return undefined;
15
+ }
16
+ function isNonEmptyString(value) {
17
+ return typeof value === 'string' && value.length > 0;
18
+ }
19
+ export function isUploadCompleteEvent(payload) {
20
+ if (typeof payload !== 'object' || payload === null) {
21
+ return false;
22
+ }
23
+ const candidate = payload;
24
+ return (isNonEmptyString(candidate.id) &&
25
+ isNonEmptyString(candidate.disk) &&
26
+ isNonEmptyString(candidate.key));
27
+ }
28
+ //# sourceMappingURL=media-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-events.js","sourceRoot":"","sources":["../../../src/rag-media/media-events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iGAAiG;AACjG,MAAM,CAAC,MAAM,uBAAuB,GAAG,6BAA6B,CAAC;AAmBrE,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;QAC5E,OAAQ,OAA8B,CAAC,OAAO,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,OAAkC,CAAC;IACrD,OAAO,CACL,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC;QAChC,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,CAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,155 @@
1
+ import type { ChunkOptions } from '../rag/chunk.js';
2
+ import type { VectorStore } from '../rag/vector-store.js';
3
+ import type { EmbeddingProvider } from '../spi/embedding-provider.js';
4
+ import { type UploadCompletePayload } from './media-events.js';
5
+ import { type TextExtractor } from './text-extractor.js';
6
+ /** The minimal, structural slice of an `@adonis-agora/media` disk this bridge reads bytes from. */
7
+ export interface DiskBytesReader {
8
+ /** Return the object's raw bytes (a media disk's `getBytes(key)`). */
9
+ getBytes(key: string): Promise<Uint8Array>;
10
+ }
11
+ /**
12
+ * The minimal, structural slice of an `@adonis-agora/media` `MediaManager` this bridge needs — just
13
+ * `disk(name)` yielding a {@link DiskBytesReader}. Structural typing keeps `@adonis-agora/media` an
14
+ * OPTIONAL peer: nothing is imported from it, an app passes its live `MediaManager` (or any handle that
15
+ * satisfies this shape) at wiring time.
16
+ */
17
+ export interface MediaManagerHandle {
18
+ disk(name?: string): DiskBytesReader;
19
+ }
20
+ /**
21
+ * A media file to ingest. `id` becomes the RAG document id (chunk ids `${id}#<n>`); `disk`/`key` locate
22
+ * the bytes through the {@link MediaManagerHandle}; `contentType` drives extractor dispatch. The owner /
23
+ * tenant fields are optional and, when present, tag every chunk's metadata so retrieval can filter by
24
+ * tenant/owner/collection.
25
+ */
26
+ export interface MediaRef {
27
+ id: string;
28
+ disk: string;
29
+ key: string;
30
+ contentType: string;
31
+ ownerType?: string;
32
+ ownerId?: string;
33
+ collection?: string;
34
+ tenantRef?: string;
35
+ /** Byte size, when known up front — used only by the `maxBytes` gate; the bytes are the source of truth. */
36
+ size?: number;
37
+ }
38
+ export type MediaIngestSkipReason = 'unsupported-type' | 'too-large' | 'empty-text';
39
+ export type MediaIngestResult = {
40
+ status: 'ingested';
41
+ chunks: number;
42
+ } | {
43
+ status: 'skipped';
44
+ reason: MediaIngestSkipReason;
45
+ };
46
+ /** Turn an `upload.complete` diagnostics payload into an ingestable {@link MediaRef}, or `null` to skip. */
47
+ export type ResolveMediaRef = (payload: UploadCompletePayload) => MediaRef | null | Promise<MediaRef | null>;
48
+ /**
49
+ * Everything the media→RAG bridge needs. Only `media`, `embedder`, and `store` are required; the
50
+ * extractor defaults to {@link defaultTextExtractor} (text/*, JSON, HTML) so binary formats are skipped
51
+ * rather than indexed as garbage. Register a PDF/DOCX parser on a {@link import('./text-extractor.js').MimeTextExtractor}
52
+ * and pass it as `extractor` — the PDF library stays entirely on the host side (never a dependency here).
53
+ */
54
+ export interface MediaRagIngestionConfig {
55
+ /** The media handle bytes are read through (an `@adonis-agora/media` `MediaManager`, structurally typed). */
56
+ media: MediaManagerHandle;
57
+ /** Embeds each chunk. Pass the same {@link EmbeddingProvider} the agent's retriever uses. */
58
+ embedder: EmbeddingProvider;
59
+ /** The RAG vector store chunks are upserted into (the same store the retriever searches). */
60
+ store: VectorStore;
61
+ /** Bytes → text. Default {@link defaultTextExtractor}. Register a PDF/DOCX hook to widen it. */
62
+ extractor?: TextExtractor;
63
+ /**
64
+ * Restrict ingestion to these content types (checked before the extractor). Omit/empty = every type
65
+ * the extractor supports. A content type not in this allow-list is skipped as `unsupported-type`.
66
+ */
67
+ contentTypes?: string[];
68
+ /** Chunking options forwarded to `chunkDocuments`. */
69
+ chunk?: ChunkOptions;
70
+ /** Skip (don't read) files larger than this many bytes (checked against `ref.size` when present). */
71
+ maxBytes?: number;
72
+ /**
73
+ * Resolve an `upload.complete` diagnostics payload (`{ id, disk, key }`) into a full {@link MediaRef}
74
+ * — the seam the auto-subscriber needs, since the event carries no content-type or owner metadata.
75
+ * Required to call {@link MediaRagIngestion.subscribe}; return `null` to skip an event.
76
+ */
77
+ resolve?: ResolveMediaRef;
78
+ }
79
+ /** Thrown by {@link MediaRagIngestion.subscribe} when no `resolve` seam was configured. */
80
+ export declare class MediaRagResolveRequiredError extends Error {
81
+ constructor();
82
+ }
83
+ /**
84
+ * Bridges `@adonis-agora/media` uploads into the agent's RAG stack: fetch the bytes → extract text by
85
+ * content type → chunk → embed → upsert into the configured {@link VectorStore}, tagging every chunk
86
+ * with `{ mediaId, ownerType, ownerId, collection, tenantRef }` so retrieval can be scoped per
87
+ * tenant/owner/collection. Two triggers, both opt-in and no-op until wired:
88
+ *
89
+ * - {@link ingestMedia} — call it explicitly with a {@link MediaRef} (e.g. from your own upload flow).
90
+ * - {@link subscribe} — subscribe to the media library's `agora:media:upload.complete` diagnostics
91
+ * channel and auto-ingest each finished upload (needs a `resolve` seam).
92
+ *
93
+ * Everything is structural: no import of `@adonis-agora/media`, and `node:diagnostics_channel` is a
94
+ * Node builtin, so there is no hard dependency on `@adonis-agora/diagnostics` for the subscribe path.
95
+ */
96
+ export declare class MediaRagIngestion {
97
+ private readonly config;
98
+ private readonly extractor;
99
+ private readonly contentTypes;
100
+ private readonly inFlight;
101
+ private teardown;
102
+ constructor(config: MediaRagIngestionConfig);
103
+ /**
104
+ * Ingest one media file: content-type filter → size gate → read bytes → extract → remove-then-chunk
105
+ * → embed → upsert. Unsupported/oversized/empty files are skipped (not errors). Chunk metadata carries
106
+ * `{ mediaId, ownerType, ownerId, collection, tenantRef }` (only the fields present on `ref`).
107
+ */
108
+ ingestMedia(ref: MediaRef): Promise<MediaIngestResult>;
109
+ /** Drop a media document's chunks from the vector store — the delete half of keeping RAG in sync. */
110
+ removeMedia(mediaId: string): Promise<void>;
111
+ /**
112
+ * Guard + resolve + ingest one `upload.complete` diagnostics payload. Public so a caller can await it
113
+ * directly (deterministic tests) instead of going through the subscription. A no-op when `resolve`
114
+ * isn't configured, the payload isn't a valid `upload.complete`, or `resolve` returns `null`.
115
+ */
116
+ handleUploadComplete(payload: unknown): Promise<MediaIngestResult | undefined>;
117
+ /**
118
+ * Subscribe to the media library's `agora:media:upload.complete` channel and auto-ingest each finished
119
+ * upload. Idempotent (a second call is a no-op while already subscribed). Returns — and stores — an
120
+ * unsubscribe function; ingestion errors are caught and published on `agora:rag:media.failed` so a bad
121
+ * file never breaks the channel. Requires a `resolve` seam ({@link MediaRagResolveRequiredError}).
122
+ */
123
+ subscribe(): () => void;
124
+ /** Unsubscribe from the media channel (if subscribed) and await every in-flight auto-ingestion. */
125
+ unsubscribe(): Promise<void>;
126
+ /** Await every in-flight auto-ingestion — for graceful shutdown and deterministic tests. */
127
+ settle(): Promise<void>;
128
+ /** Whether the auto-subscriber is currently attached to the media channel. */
129
+ get subscribed(): boolean;
130
+ /** Handle one channel event with the same error boundary the subscriber uses. */
131
+ private ingestFromEvent;
132
+ private track;
133
+ }
134
+ /**
135
+ * Build a media→RAG ingestion bridge (idiomatic factory). Wire it in a provider's `boot()`:
136
+ *
137
+ * ```ts
138
+ * import { mediaRagIngestion } from '@adonis-agora/agent/rag-media'
139
+ *
140
+ * const ingestion = mediaRagIngestion({
141
+ * media: await app.container.make('media.manager'),
142
+ * embedder: myEmbedder,
143
+ * store: myVectorStore,
144
+ * contentTypes: ['text/plain', 'text/markdown', 'application/pdf'],
145
+ * extractor: defaultTextExtractor().register('application/pdf', myPdfExtractor),
146
+ * resolve: async ({ id, disk, key }) => lookupMediaRecord(id), // → MediaRef
147
+ * })
148
+ * const off = ingestion.subscribe() // auto-ingest on upload.complete
149
+ * ```
150
+ *
151
+ * Or trigger it explicitly: `await ingestion.ingestMedia(ref)`. Everything is opt-in and no-op until
152
+ * wired — nothing runs, subscribes, or imports the media/pdf peers unless you call it.
153
+ */
154
+ export declare function mediaRagIngestion(config: MediaRagIngestionConfig): MediaRagIngestion;
155
+ //# sourceMappingURL=media-rag-ingestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-rag-ingestion.d.ts","sourceRoot":"","sources":["../../../src/rag-media/media-rag-ingestion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ import diagnostics_channel from 'node:diagnostics_channel';
2
+ import { chunkDocuments, ingestChunks } from '../rag/ingest.js';
3
+ import { publishRagMediaFailed, publishRagMediaIngested, publishRagMediaRemoved, publishRagMediaSkipped, } from './diagnostics.js';
4
+ import { UPLOAD_COMPLETE_CHANNEL, envelopePayload, isUploadCompleteEvent, } from './media-events.js';
5
+ import { UnsupportedContentTypeError, defaultTextExtractor, normalizeContentType, } from './text-extractor.js';
6
+ /** Thrown by {@link MediaRagIngestion.subscribe} when no `resolve` seam was configured. */
7
+ export class MediaRagResolveRequiredError extends Error {
8
+ constructor() {
9
+ super('mediaRagIngestion: subscribe() needs a `resolve` in the config to turn an upload.complete ' +
10
+ 'payload ({ id, disk, key }) into a MediaRef with contentType/owner metadata.');
11
+ this.name = 'MediaRagResolveRequiredError';
12
+ }
13
+ }
14
+ /**
15
+ * Bridges `@adonis-agora/media` uploads into the agent's RAG stack: fetch the bytes → extract text by
16
+ * content type → chunk → embed → upsert into the configured {@link VectorStore}, tagging every chunk
17
+ * with `{ mediaId, ownerType, ownerId, collection, tenantRef }` so retrieval can be scoped per
18
+ * tenant/owner/collection. Two triggers, both opt-in and no-op until wired:
19
+ *
20
+ * - {@link ingestMedia} — call it explicitly with a {@link MediaRef} (e.g. from your own upload flow).
21
+ * - {@link subscribe} — subscribe to the media library's `agora:media:upload.complete` diagnostics
22
+ * channel and auto-ingest each finished upload (needs a `resolve` seam).
23
+ *
24
+ * Everything is structural: no import of `@adonis-agora/media`, and `node:diagnostics_channel` is a
25
+ * Node builtin, so there is no hard dependency on `@adonis-agora/diagnostics` for the subscribe path.
26
+ */
27
+ export class MediaRagIngestion {
28
+ config;
29
+ extractor;
30
+ contentTypes;
31
+ inFlight = new Set();
32
+ teardown = null;
33
+ constructor(config) {
34
+ this.config = config;
35
+ this.extractor = config.extractor ?? defaultTextExtractor();
36
+ this.contentTypes =
37
+ config.contentTypes !== undefined && config.contentTypes.length > 0
38
+ ? new Set(config.contentTypes.map((type) => normalizeContentType(type)))
39
+ : null;
40
+ }
41
+ /**
42
+ * Ingest one media file: content-type filter → size gate → read bytes → extract → remove-then-chunk
43
+ * → embed → upsert. Unsupported/oversized/empty files are skipped (not errors). Chunk metadata carries
44
+ * `{ mediaId, ownerType, ownerId, collection, tenantRef }` (only the fields present on `ref`).
45
+ */
46
+ async ingestMedia(ref) {
47
+ const contentType = normalizeContentType(ref.contentType);
48
+ if (this.contentTypes !== null && !this.contentTypes.has(contentType)) {
49
+ publishRagMediaSkipped({ mediaId: ref.id, contentType, reason: 'unsupported-type' });
50
+ return { status: 'skipped', reason: 'unsupported-type' };
51
+ }
52
+ if (this.config.maxBytes !== undefined &&
53
+ ref.size !== undefined &&
54
+ ref.size > this.config.maxBytes) {
55
+ publishRagMediaSkipped({ mediaId: ref.id, contentType, reason: 'too-large' });
56
+ return { status: 'skipped', reason: 'too-large' };
57
+ }
58
+ let text;
59
+ try {
60
+ const bytes = await this.config.media.disk(ref.disk).getBytes(ref.key);
61
+ text = await this.extractor.extract(Buffer.from(bytes), ref.contentType);
62
+ }
63
+ catch (error) {
64
+ if (error instanceof UnsupportedContentTypeError) {
65
+ publishRagMediaSkipped({ mediaId: ref.id, contentType, reason: 'unsupported-type' });
66
+ return { status: 'skipped', reason: 'unsupported-type' };
67
+ }
68
+ throw error;
69
+ }
70
+ if (text.trim() === '') {
71
+ publishRagMediaSkipped({ mediaId: ref.id, contentType, reason: 'empty-text' });
72
+ return { status: 'skipped', reason: 'empty-text' };
73
+ }
74
+ // remove-then-ingest so a re-upload that shrinks to fewer chunks doesn't leave a stale tail.
75
+ await this.config.store.remove(ref.id);
76
+ const document = {
77
+ id: ref.id,
78
+ text,
79
+ source: ref.key,
80
+ metadata: {
81
+ mediaId: ref.id,
82
+ ...(ref.ownerType !== undefined ? { ownerType: ref.ownerType } : {}),
83
+ ...(ref.ownerId !== undefined ? { ownerId: ref.ownerId } : {}),
84
+ ...(ref.collection !== undefined ? { collection: ref.collection } : {}),
85
+ ...(ref.tenantRef !== undefined ? { tenantRef: ref.tenantRef } : {}),
86
+ },
87
+ };
88
+ const chunks = chunkDocuments([document], this.config.chunk ?? {});
89
+ const count = await ingestChunks(chunks, {
90
+ embedder: this.config.embedder,
91
+ store: this.config.store,
92
+ });
93
+ publishRagMediaIngested({
94
+ mediaId: ref.id,
95
+ chunks: count,
96
+ ...(ref.ownerType !== undefined ? { ownerType: ref.ownerType } : {}),
97
+ ...(ref.ownerId !== undefined ? { ownerId: ref.ownerId } : {}),
98
+ ...(ref.collection !== undefined ? { collection: ref.collection } : {}),
99
+ ...(ref.tenantRef !== undefined ? { tenantRef: ref.tenantRef } : {}),
100
+ });
101
+ return { status: 'ingested', chunks: count };
102
+ }
103
+ /** Drop a media document's chunks from the vector store — the delete half of keeping RAG in sync. */
104
+ async removeMedia(mediaId) {
105
+ await this.config.store.remove(mediaId);
106
+ publishRagMediaRemoved({ mediaId });
107
+ }
108
+ /**
109
+ * Guard + resolve + ingest one `upload.complete` diagnostics payload. Public so a caller can await it
110
+ * directly (deterministic tests) instead of going through the subscription. A no-op when `resolve`
111
+ * isn't configured, the payload isn't a valid `upload.complete`, or `resolve` returns `null`.
112
+ */
113
+ async handleUploadComplete(payload) {
114
+ if (this.config.resolve === undefined || !isUploadCompleteEvent(payload)) {
115
+ return undefined;
116
+ }
117
+ const ref = await this.config.resolve(payload);
118
+ if (ref === null) {
119
+ return undefined;
120
+ }
121
+ return this.ingestMedia(ref);
122
+ }
123
+ /**
124
+ * Subscribe to the media library's `agora:media:upload.complete` channel and auto-ingest each finished
125
+ * upload. Idempotent (a second call is a no-op while already subscribed). Returns — and stores — an
126
+ * unsubscribe function; ingestion errors are caught and published on `agora:rag:media.failed` so a bad
127
+ * file never breaks the channel. Requires a `resolve` seam ({@link MediaRagResolveRequiredError}).
128
+ */
129
+ subscribe() {
130
+ if (this.config.resolve === undefined) {
131
+ throw new MediaRagResolveRequiredError();
132
+ }
133
+ if (this.teardown !== null) {
134
+ return this.teardown;
135
+ }
136
+ const channel = diagnostics_channel.channel(UPLOAD_COMPLETE_CHANNEL);
137
+ const listener = (message) => {
138
+ this.track(this.ingestFromEvent(envelopePayload(message)));
139
+ };
140
+ channel.subscribe(listener);
141
+ const teardown = () => {
142
+ channel.unsubscribe(listener);
143
+ this.teardown = null;
144
+ };
145
+ this.teardown = teardown;
146
+ return teardown;
147
+ }
148
+ /** Unsubscribe from the media channel (if subscribed) and await every in-flight auto-ingestion. */
149
+ async unsubscribe() {
150
+ this.teardown?.();
151
+ await this.settle();
152
+ }
153
+ /** Await every in-flight auto-ingestion — for graceful shutdown and deterministic tests. */
154
+ async settle() {
155
+ await Promise.allSettled([...this.inFlight]);
156
+ }
157
+ /** Whether the auto-subscriber is currently attached to the media channel. */
158
+ get subscribed() {
159
+ return this.teardown !== null;
160
+ }
161
+ /** Handle one channel event with the same error boundary the subscriber uses. */
162
+ async ingestFromEvent(payload) {
163
+ const mediaId = isUploadCompleteEvent(payload) ? payload.id : 'unknown';
164
+ try {
165
+ await this.handleUploadComplete(payload);
166
+ }
167
+ catch (error) {
168
+ publishRagMediaFailed({ mediaId, error: errorMessage(error) });
169
+ }
170
+ }
171
+ track(promise) {
172
+ const tracked = promise.finally(() => {
173
+ this.inFlight.delete(tracked);
174
+ });
175
+ this.inFlight.add(tracked);
176
+ }
177
+ }
178
+ /**
179
+ * Build a media→RAG ingestion bridge (idiomatic factory). Wire it in a provider's `boot()`:
180
+ *
181
+ * ```ts
182
+ * import { mediaRagIngestion } from '@adonis-agora/agent/rag-media'
183
+ *
184
+ * const ingestion = mediaRagIngestion({
185
+ * media: await app.container.make('media.manager'),
186
+ * embedder: myEmbedder,
187
+ * store: myVectorStore,
188
+ * contentTypes: ['text/plain', 'text/markdown', 'application/pdf'],
189
+ * extractor: defaultTextExtractor().register('application/pdf', myPdfExtractor),
190
+ * resolve: async ({ id, disk, key }) => lookupMediaRecord(id), // → MediaRef
191
+ * })
192
+ * const off = ingestion.subscribe() // auto-ingest on upload.complete
193
+ * ```
194
+ *
195
+ * Or trigger it explicitly: `await ingestion.ingestMedia(ref)`. Everything is opt-in and no-op until
196
+ * wired — nothing runs, subscribes, or imports the media/pdf peers unless you call it.
197
+ */
198
+ export function mediaRagIngestion(config) {
199
+ return new MediaRagIngestion(config);
200
+ }
201
+ function errorMessage(error) {
202
+ return error instanceof Error ? error.message : String(error);
203
+ }
204
+ //# sourceMappingURL=media-rag-ingestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-rag-ingestion.js","sourceRoot":"","sources":["../../../src/rag-media/media-rag-ingestion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Turns a media file's raw bytes into the plain text that gets chunked, embedded, and indexed. The
3
+ * extraction seam — so the RAG stack itself stays format-agnostic. Ships the text-family extractors;
4
+ * bring your own for PDF/DOCX/etc. by registering a parser on a {@link MimeTextExtractor} (so no PDF
5
+ * library is ever a hard dependency of `@adonis-agora/agent`). Mirrors the reference `rag-media`
6
+ * `TextExtractor` contract exactly.
7
+ */
8
+ export interface TextExtractor {
9
+ extract(bytes: Buffer, contentType: string): Promise<string>;
10
+ }
11
+ /** Thrown when no extractor is registered for a content type — ingestion treats it as "skip, don't index". */
12
+ export declare class UnsupportedContentTypeError extends Error {
13
+ readonly contentType: string;
14
+ constructor(contentType: string);
15
+ }
16
+ /** How a single content type (or `type/*` family) turns bytes into text. */
17
+ export type ExtractFn = (bytes: Buffer, contentType: string) => string | Promise<string>;
18
+ /**
19
+ * A {@link TextExtractor} that dispatches by content type. Register exact types (`application/json`) or
20
+ * a whole family (`text/*`); an exact match always wins over a family. Unregistered types throw
21
+ * {@link UnsupportedContentTypeError}. This is the extension point for binary formats:
22
+ * `.register('application/pdf', pdfFn)` — the PDF/DOCX library stays entirely on the host side.
23
+ */
24
+ export declare class MimeTextExtractor implements TextExtractor {
25
+ private readonly exact;
26
+ private readonly families;
27
+ register(contentType: string, fn: ExtractFn): this;
28
+ extract(bytes: Buffer, contentType: string): Promise<string>;
29
+ /** Whether a content type would resolve to an extractor (without reading bytes). */
30
+ supports(contentType: string): boolean;
31
+ private resolve;
32
+ }
33
+ /** Strip any `; charset=…` parameter off a content type and lower-case it. */
34
+ export declare function normalizeContentType(contentType: string): string;
35
+ /** Decode bytes as UTF-8 — the extractor for `text/*` and JSON. */
36
+ export declare function decodeUtf8(bytes: Buffer): string;
37
+ /** Decode UTF-8 then strip HTML: drop `<script>`/`<style>` bodies and tags, decode common entities. */
38
+ export declare function extractHtmlText(bytes: Buffer): string;
39
+ /**
40
+ * The default extractor: `text/plain`, `text/csv`, `text/markdown` (and the whole `text/*` family) plus
41
+ * `application/json` decode as UTF-8, `text/html` is tag-stripped, and everything else — PDF, DOCX,
42
+ * images — throws {@link UnsupportedContentTypeError} (so binary formats are skipped rather than indexed
43
+ * as garbage). Extend it for those: `.register('application/pdf', myPdfExtractor)`.
44
+ */
45
+ export declare function defaultTextExtractor(): MimeTextExtractor;
46
+ //# sourceMappingURL=text-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-extractor.d.ts","sourceRoot":"","sources":["../../../src/rag-media/text-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9D;AAED,8GAA8G;AAC9G,qBAAa,2BAA4B,SAAQ,KAAK;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM;gBAAnB,WAAW,EAAE,MAAM;CAIzC;AAED,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEzF;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IAEpE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI;IAU5C,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASlE,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAItC,OAAO,CAAC,OAAO;CAYhB;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAarD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CAQxD"}