@intelligo-dev/core 1.0.0-beta.1 → 1.0.0-beta.13

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 (355) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +102 -0
  3. package/dist/attachments/errors.d.ts +7 -0
  4. package/dist/attachments/errors.d.ts.map +1 -0
  5. package/dist/attachments/errors.js +11 -0
  6. package/dist/attachments/errors.js.map +1 -0
  7. package/dist/attachments/index.d.ts +8 -0
  8. package/dist/attachments/index.d.ts.map +1 -0
  9. package/dist/attachments/index.js +7 -0
  10. package/dist/attachments/index.js.map +1 -0
  11. package/dist/attachments/service.d.ts +45 -0
  12. package/dist/attachments/service.d.ts.map +1 -0
  13. package/dist/attachments/service.js +100 -0
  14. package/dist/attachments/service.js.map +1 -0
  15. package/dist/attachments/types.d.ts +6 -0
  16. package/dist/attachments/types.d.ts.map +1 -0
  17. package/dist/attachments/types.js +2 -0
  18. package/dist/attachments/types.js.map +1 -0
  19. package/dist/conversations/errors.d.ts +2 -8
  20. package/dist/conversations/errors.d.ts.map +1 -1
  21. package/dist/conversations/errors.js +2 -8
  22. package/dist/conversations/errors.js.map +1 -1
  23. package/dist/conversations/index.d.ts +4 -12
  24. package/dist/conversations/index.d.ts.map +1 -1
  25. package/dist/conversations/index.js +2 -11
  26. package/dist/conversations/index.js.map +1 -1
  27. package/dist/conversations/service.d.ts +49 -61
  28. package/dist/conversations/service.d.ts.map +1 -1
  29. package/dist/conversations/service.js +110 -83
  30. package/dist/conversations/service.js.map +1 -1
  31. package/dist/conversations/types.d.ts +1 -4
  32. package/dist/conversations/types.d.ts.map +1 -1
  33. package/dist/conversations/types.js +0 -3
  34. package/dist/conversations/types.js.map +1 -1
  35. package/dist/db/client.d.ts +21 -10
  36. package/dist/db/client.d.ts.map +1 -1
  37. package/dist/db/client.js +43 -18
  38. package/dist/db/client.js.map +1 -1
  39. package/dist/db/index.d.ts +3 -3
  40. package/dist/db/index.d.ts.map +1 -1
  41. package/dist/db/index.js +3 -7
  42. package/dist/db/index.js.map +1 -1
  43. package/dist/db/schema/agents.d.ts +14 -51
  44. package/dist/db/schema/agents.d.ts.map +1 -1
  45. package/dist/db/schema/agents.js +9 -21
  46. package/dist/db/schema/agents.js.map +1 -1
  47. package/dist/db/schema/ai.d.ts +86 -1556
  48. package/dist/db/schema/ai.d.ts.map +1 -1
  49. package/dist/db/schema/ai.js +32 -236
  50. package/dist/db/schema/ai.js.map +1 -1
  51. package/dist/db/schema/auth.d.ts +5 -34
  52. package/dist/db/schema/auth.d.ts.map +1 -1
  53. package/dist/db/schema/auth.js +25 -56
  54. package/dist/db/schema/auth.js.map +1 -1
  55. package/dist/db/schema/billing.d.ts +136 -107
  56. package/dist/db/schema/billing.d.ts.map +1 -1
  57. package/dist/db/schema/billing.js +72 -60
  58. package/dist/db/schema/billing.js.map +1 -1
  59. package/dist/db/schema/feature-flags.d.ts +3 -12
  60. package/dist/db/schema/feature-flags.d.ts.map +1 -1
  61. package/dist/db/schema/feature-flags.js +3 -12
  62. package/dist/db/schema/feature-flags.js.map +1 -1
  63. package/dist/db/schema/identity.d.ts +12 -274
  64. package/dist/db/schema/identity.d.ts.map +1 -1
  65. package/dist/db/schema/identity.js +19 -104
  66. package/dist/db/schema/identity.js.map +1 -1
  67. package/dist/db/schema/index.d.ts +8 -15
  68. package/dist/db/schema/index.d.ts.map +1 -1
  69. package/dist/db/schema/index.js +12 -42
  70. package/dist/db/schema/index.js.map +1 -1
  71. package/dist/db/schema/notifications.d.ts +3 -17
  72. package/dist/db/schema/notifications.d.ts.map +1 -1
  73. package/dist/db/schema/notifications.js +3 -17
  74. package/dist/db/schema/notifications.js.map +1 -1
  75. package/dist/db/schema/usage.d.ts +94 -77
  76. package/dist/db/schema/usage.d.ts.map +1 -1
  77. package/dist/db/schema/usage.js +59 -89
  78. package/dist/db/schema/usage.js.map +1 -1
  79. package/dist/db/validate.d.ts +2 -11
  80. package/dist/db/validate.d.ts.map +1 -1
  81. package/dist/db/validate.js +6 -17
  82. package/dist/db/validate.js.map +1 -1
  83. package/dist/db/workspace-queries.d.ts +5 -29
  84. package/dist/db/workspace-queries.d.ts.map +1 -1
  85. package/dist/db/workspace-queries.js +5 -29
  86. package/dist/db/workspace-queries.js.map +1 -1
  87. package/dist/documents/classifier.d.ts +5 -12
  88. package/dist/documents/classifier.d.ts.map +1 -1
  89. package/dist/documents/classifier.js +16 -16
  90. package/dist/documents/classifier.js.map +1 -1
  91. package/dist/documents/errors.d.ts +2 -10
  92. package/dist/documents/errors.d.ts.map +1 -1
  93. package/dist/documents/errors.js +2 -10
  94. package/dist/documents/errors.js.map +1 -1
  95. package/dist/documents/index.d.ts +4 -13
  96. package/dist/documents/index.d.ts.map +1 -1
  97. package/dist/documents/index.js +3 -12
  98. package/dist/documents/index.js.map +1 -1
  99. package/dist/documents/service.d.ts +19 -26
  100. package/dist/documents/service.d.ts.map +1 -1
  101. package/dist/documents/service.js +44 -38
  102. package/dist/documents/service.js.map +1 -1
  103. package/dist/documents/types.d.ts +6 -10
  104. package/dist/documents/types.d.ts.map +1 -1
  105. package/dist/documents/types.js +0 -3
  106. package/dist/documents/types.js.map +1 -1
  107. package/dist/email/brand.d.ts +17 -0
  108. package/dist/email/brand.d.ts.map +1 -0
  109. package/dist/email/brand.js +9 -0
  110. package/dist/email/brand.js.map +1 -0
  111. package/dist/email/index.d.ts +4 -4
  112. package/dist/email/index.js +4 -4
  113. package/dist/email/provider.d.ts +1 -7
  114. package/dist/email/provider.d.ts.map +1 -1
  115. package/dist/email/provider.js +10 -19
  116. package/dist/email/provider.js.map +1 -1
  117. package/dist/email/send.d.ts +12 -12
  118. package/dist/email/send.d.ts.map +1 -1
  119. package/dist/email/send.js +5 -19
  120. package/dist/email/send.js.map +1 -1
  121. package/dist/email/senders.d.ts +17 -30
  122. package/dist/email/senders.d.ts.map +1 -1
  123. package/dist/email/senders.js +33 -47
  124. package/dist/email/senders.js.map +1 -1
  125. package/dist/email/templates/base-layout.d.ts +1 -1
  126. package/dist/email/templates/base-layout.d.ts.map +1 -1
  127. package/dist/email/templates/base-layout.js +4 -6
  128. package/dist/email/templates/base-layout.js.map +1 -1
  129. package/dist/email/templates/index.d.ts +10 -10
  130. package/dist/email/templates/index.d.ts.map +1 -1
  131. package/dist/email/templates/index.js +10 -16
  132. package/dist/email/templates/index.js.map +1 -1
  133. package/dist/email/templates/password-reset.d.ts +2 -2
  134. package/dist/email/templates/password-reset.d.ts.map +1 -1
  135. package/dist/email/templates/password-reset.js +10 -22
  136. package/dist/email/templates/password-reset.js.map +1 -1
  137. package/dist/email/templates/payment-failed.d.ts +2 -2
  138. package/dist/email/templates/payment-failed.d.ts.map +1 -1
  139. package/dist/email/templates/payment-failed.js +11 -24
  140. package/dist/email/templates/payment-failed.js.map +1 -1
  141. package/dist/email/templates/quota-warning.d.ts +4 -4
  142. package/dist/email/templates/quota-warning.d.ts.map +1 -1
  143. package/dist/email/templates/quota-warning.js +19 -39
  144. package/dist/email/templates/quota-warning.js.map +1 -1
  145. package/dist/email/templates/subscription-confirmed.d.ts +2 -2
  146. package/dist/email/templates/subscription-confirmed.d.ts.map +1 -1
  147. package/dist/email/templates/subscription-confirmed.js +13 -28
  148. package/dist/email/templates/subscription-confirmed.js.map +1 -1
  149. package/dist/email/templates/trial-expiry.d.ts +2 -2
  150. package/dist/email/templates/trial-expiry.d.ts.map +1 -1
  151. package/dist/email/templates/trial-expiry.js +12 -36
  152. package/dist/email/templates/trial-expiry.js.map +1 -1
  153. package/dist/email/templates/trial-warning.d.ts +2 -2
  154. package/dist/email/templates/trial-warning.d.ts.map +1 -1
  155. package/dist/email/templates/trial-warning.js +15 -32
  156. package/dist/email/templates/trial-warning.js.map +1 -1
  157. package/dist/email/templates/verify-email.d.ts +2 -2
  158. package/dist/email/templates/verify-email.d.ts.map +1 -1
  159. package/dist/email/templates/verify-email.js +10 -22
  160. package/dist/email/templates/verify-email.js.map +1 -1
  161. package/dist/email/templates/welcome.d.ts +2 -2
  162. package/dist/email/templates/welcome.d.ts.map +1 -1
  163. package/dist/email/templates/welcome.js +13 -20
  164. package/dist/email/templates/welcome.js.map +1 -1
  165. package/dist/email/templates/workspace-invitation.d.ts +2 -2
  166. package/dist/email/templates/workspace-invitation.d.ts.map +1 -1
  167. package/dist/email/templates/workspace-invitation.js +12 -26
  168. package/dist/email/templates/workspace-invitation.js.map +1 -1
  169. package/dist/env.d.ts +5 -10
  170. package/dist/env.d.ts.map +1 -1
  171. package/dist/env.js +41 -31
  172. package/dist/env.js.map +1 -1
  173. package/dist/identity/audit.d.ts +11 -24
  174. package/dist/identity/audit.d.ts.map +1 -1
  175. package/dist/identity/audit.js +13 -27
  176. package/dist/identity/audit.js.map +1 -1
  177. package/dist/identity/errors.d.ts +4 -12
  178. package/dist/identity/errors.d.ts.map +1 -1
  179. package/dist/identity/errors.js +2 -8
  180. package/dist/identity/errors.js.map +1 -1
  181. package/dist/identity/index.d.ts +5 -13
  182. package/dist/identity/index.d.ts.map +1 -1
  183. package/dist/identity/index.js +4 -12
  184. package/dist/identity/index.js.map +1 -1
  185. package/dist/identity/service.d.ts +13 -47
  186. package/dist/identity/service.d.ts.map +1 -1
  187. package/dist/identity/service.js +31 -78
  188. package/dist/identity/service.js.map +1 -1
  189. package/dist/identity/types.d.ts +1 -4
  190. package/dist/identity/types.d.ts.map +1 -1
  191. package/dist/identity/types.js +0 -3
  192. package/dist/identity/types.js.map +1 -1
  193. package/dist/index.d.ts +1 -2
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +3 -10
  196. package/dist/index.js.map +1 -1
  197. package/dist/logger.d.ts +7 -18
  198. package/dist/logger.d.ts.map +1 -1
  199. package/dist/logger.js +45 -49
  200. package/dist/logger.js.map +1 -1
  201. package/dist/money.d.ts +95 -0
  202. package/dist/money.d.ts.map +1 -0
  203. package/dist/money.js +208 -0
  204. package/dist/money.js.map +1 -0
  205. package/dist/notifications/index.d.ts +9 -43
  206. package/dist/notifications/index.d.ts.map +1 -1
  207. package/dist/notifications/index.js +9 -49
  208. package/dist/notifications/index.js.map +1 -1
  209. package/dist/notifications/triggers.d.ts +9 -32
  210. package/dist/notifications/triggers.d.ts.map +1 -1
  211. package/dist/notifications/triggers.js +21 -58
  212. package/dist/notifications/triggers.js.map +1 -1
  213. package/dist/notifications/types.d.ts +1 -10
  214. package/dist/notifications/types.d.ts.map +1 -1
  215. package/dist/notifications/types.js +0 -9
  216. package/dist/notifications/types.js.map +1 -1
  217. package/dist/prompt.d.ts +38 -0
  218. package/dist/prompt.d.ts.map +1 -0
  219. package/dist/prompt.js +118 -0
  220. package/dist/prompt.js.map +1 -0
  221. package/dist/registry.d.ts +32 -0
  222. package/dist/registry.d.ts.map +1 -0
  223. package/dist/registry.js +60 -0
  224. package/dist/registry.js.map +1 -0
  225. package/dist/request-context.d.ts +49 -0
  226. package/dist/request-context.d.ts.map +1 -0
  227. package/dist/request-context.js +100 -0
  228. package/dist/request-context.js.map +1 -0
  229. package/dist/storage/index.d.ts +65 -0
  230. package/dist/storage/index.d.ts.map +1 -0
  231. package/dist/storage/index.js +109 -0
  232. package/dist/storage/index.js.map +1 -0
  233. package/package.json +74 -24
  234. package/src/attachments/errors.ts +18 -0
  235. package/src/attachments/index.ts +22 -0
  236. package/src/attachments/service.ts +178 -0
  237. package/src/attachments/types.ts +6 -0
  238. package/src/conversations/errors.ts +45 -0
  239. package/src/conversations/index.ts +39 -0
  240. package/src/conversations/service.ts +594 -0
  241. package/src/conversations/types.ts +15 -0
  242. package/src/db/client.ts +91 -0
  243. package/src/db/index.ts +3 -0
  244. package/src/db/migrations/0000_baseline.sql +652 -0
  245. package/src/db/migrations/0001_reconcile_chain_built_databases.sql +53 -0
  246. package/src/db/migrations/0002_webhook_claim_lease.sql +1 -0
  247. package/src/db/migrations/README.md +74 -36
  248. package/src/db/migrations/legacy-chain.json +197 -0
  249. package/src/db/migrations/meta/0000_snapshot.json +4182 -157
  250. package/src/db/migrations/meta/0002_snapshot.json +2478 -368
  251. package/src/db/migrations/meta/_journal.json +6 -279
  252. package/src/db/schema/agents.ts +57 -0
  253. package/src/db/schema/ai.ts +174 -0
  254. package/src/db/schema/auth.ts +183 -0
  255. package/src/db/schema/billing.ts +209 -0
  256. package/src/db/schema/feature-flags.ts +20 -0
  257. package/src/db/schema/identity.ts +250 -0
  258. package/src/db/schema/index.ts +12 -0
  259. package/src/db/schema/notifications.ts +31 -0
  260. package/src/db/schema/usage.ts +269 -0
  261. package/src/db/validate.ts +63 -0
  262. package/src/db/workspace-queries.ts +64 -0
  263. package/src/documents/classifier.ts +61 -0
  264. package/src/documents/errors.ts +44 -0
  265. package/src/documents/index.ts +24 -0
  266. package/src/documents/service.ts +256 -0
  267. package/src/documents/types.ts +24 -0
  268. package/src/email/brand.ts +24 -0
  269. package/src/email/index.ts +19 -0
  270. package/src/email/provider.ts +278 -0
  271. package/src/email/send.ts +169 -0
  272. package/src/email/senders.ts +292 -0
  273. package/src/email/templates/base-layout.tsx +145 -0
  274. package/src/email/templates/index.ts +28 -0
  275. package/src/email/templates/password-reset.tsx +72 -0
  276. package/src/email/templates/payment-failed.tsx +77 -0
  277. package/src/email/templates/quota-warning.tsx +118 -0
  278. package/src/email/templates/subscription-confirmed.tsx +91 -0
  279. package/src/email/templates/trial-expiry.tsx +124 -0
  280. package/src/email/templates/trial-warning.tsx +104 -0
  281. package/src/email/templates/verify-email.tsx +72 -0
  282. package/src/email/templates/welcome.tsx +64 -0
  283. package/src/email/templates/workspace-invitation.tsx +105 -0
  284. package/src/env.ts +180 -0
  285. package/src/identity/audit.ts +65 -0
  286. package/src/identity/errors.ts +44 -0
  287. package/src/identity/index.ts +26 -0
  288. package/src/identity/service.ts +202 -0
  289. package/src/identity/types.ts +28 -0
  290. package/src/index.ts +4 -0
  291. package/src/logger.ts +198 -0
  292. package/src/money.ts +270 -0
  293. package/src/notifications/index.ts +108 -0
  294. package/src/notifications/triggers.ts +158 -0
  295. package/src/notifications/types.ts +18 -0
  296. package/src/prompt.ts +142 -0
  297. package/src/registry.ts +75 -0
  298. package/src/request-context.ts +137 -0
  299. package/src/storage/index.ts +153 -0
  300. package/dist/db/schema/rag.d.ts +0 -171
  301. package/dist/db/schema/rag.d.ts.map +0 -1
  302. package/dist/db/schema/rag.js +0 -42
  303. package/dist/db/schema/rag.js.map +0 -1
  304. package/src/db/migrations/0000_sharp_night_nurse.sql +0 -52
  305. package/src/db/migrations/0001_hesitant_vapor.sql +0 -40
  306. package/src/db/migrations/0002_numerous_lady_vermin.sql +0 -235
  307. package/src/db/migrations/0003_mighty_jean_grey.sql +0 -37
  308. package/src/db/migrations/0004_cynical_grandmaster.sql +0 -2
  309. package/src/db/migrations/0005_careful_switch.sql +0 -8
  310. package/src/db/migrations/0006_tense_blue_marvel.sql +0 -16
  311. package/src/db/migrations/0007_next_squadron_sinister.sql +0 -1
  312. package/src/db/migrations/0008_powerful_scream.sql +0 -39
  313. package/src/db/migrations/0009_sad_ink.sql +0 -1
  314. package/src/db/migrations/0010_shocking_omega_flight.sql +0 -2
  315. package/src/db/migrations/0011_ambiguous_otto_octavius.sql +0 -151
  316. package/src/db/migrations/0011_hnsw_vector_index.sql +0 -17
  317. package/src/db/migrations/0012_user_profiles.sql +0 -30
  318. package/src/db/migrations/0013_trending_seasonal_columns.sql +0 -9
  319. package/src/db/migrations/0014_add_product_type_to_agents.sql +0 -6
  320. package/src/db/migrations/0015_new_v1_tables.sql +0 -149
  321. package/src/db/migrations/0016_document_types.sql +0 -30
  322. package/src/db/migrations/0017_document_metadata.sql +0 -2
  323. package/src/db/migrations/0018_identity_graph.sql +0 -200
  324. package/src/db/migrations/0019_db_driven_prompts.sql +0 -20
  325. package/src/db/migrations/0020_pending_extractions.sql +0 -35
  326. package/src/db/migrations/0021_rag_documents.sql +0 -39
  327. package/src/db/migrations/0022_user_quotas_usage_jsonb.sql +0 -70
  328. package/src/db/migrations/0023_user_facts_user_scoped_unique.sql +0 -17
  329. package/src/db/migrations/0024_user_memories_hnsw.sql +0 -23
  330. package/src/db/migrations/0025_audit_trigger_errcode.sql +0 -21
  331. package/src/db/migrations/0026_user_profile_snapshots_composite_pk.sql +0 -17
  332. package/src/db/migrations/0027_billing_settings_mnt_columns.sql +0 -54
  333. package/src/db/migrations/0028_trial_credits_normalized_email.sql +0 -37
  334. package/src/db/migrations/0029_usage_records_conversation_idx.sql +0 -13
  335. package/src/db/migrations/0030_pending_extractions_composite_idx.sql +0 -11
  336. package/src/db/migrations/0031_rag_documents_hnsw.sql +0 -16
  337. package/src/db/migrations/0032_rate_limit_unique_idx.sql +0 -16
  338. package/src/db/migrations/0033_pending_extractions_partial_idx.sql +0 -18
  339. package/src/db/migrations/0034_rate_limit_count.sql +0 -9
  340. package/src/db/migrations/0035_credit_reservations.sql +0 -24
  341. package/src/db/migrations/0036_executions_audit_jobs.sql +0 -96
  342. package/src/db/migrations/0037_rate_limit_minute_bucket.sql +0 -46
  343. package/src/db/migrations/0038_user_quotas_generic_usage.sql +0 -25
  344. package/src/db/migrations/0039_platform_admin_impersonation.sql +0 -27
  345. package/src/db/migrations/0040_ee_audit_chain.sql +0 -23
  346. package/src/db/migrations/meta/0001_snapshot.json +0 -631
  347. package/src/db/migrations/meta/0003_snapshot.json +0 -2488
  348. package/src/db/migrations/meta/0004_snapshot.json +0 -2500
  349. package/src/db/migrations/meta/0005_snapshot.json +0 -2548
  350. package/src/db/migrations/meta/0006_snapshot.json +0 -2650
  351. package/src/db/migrations/meta/0007_snapshot.json +0 -2657
  352. package/src/db/migrations/meta/0008_snapshot.json +0 -2719
  353. package/src/db/migrations/meta/0009_snapshot.json +0 -2726
  354. package/src/db/migrations/meta/0010_snapshot.json +0 -2739
  355. package/src/db/migrations/meta/0011_snapshot.json +0 -3886
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Where files live. The framework stores attachment rows and hands out URLs;
3
+ * the application binds one adapter (S3, R2, Vercel Blob, disk) from its
4
+ * composition root:
5
+ *
6
+ * import { setStorageAdapter } from "@intelligo-dev/core/storage";
7
+ * setStorageAdapter(createS3Storage({ bucket, region })); // the app's lib/storage.ts
8
+ *
9
+ * An unbound adapter throws where a file is needed. Keys carry the tenant —
10
+ * `ws/<workspaceId>/att/<id>` — so a signed URL for one workspace's file can
11
+ * never be minted from another's row.
12
+ */
13
+ import { createRegistryRef } from "../registry.js";
14
+ export class StorageUnavailableError extends Error {
15
+ constructor() {
16
+ super("No storage adapter is bound. Call setStorageAdapter() from your " +
17
+ "composition root with your bucket's adapter (S3, R2, Blob), or " +
18
+ "createMemoryStorage() for tests.");
19
+ this.code = "storage_unavailable";
20
+ this.name = "StorageUnavailableError";
21
+ }
22
+ }
23
+ const adapter = createRegistryRef("core/storage-adapter", undefined);
24
+ export function setStorageAdapter(next) {
25
+ adapter.set(next);
26
+ }
27
+ /** Forget the bound adapter. For tests composing a fresh root. */
28
+ export function clearStorageAdapter() {
29
+ adapter.set(undefined);
30
+ }
31
+ export function hasStorageAdapter() {
32
+ return adapter.get() !== undefined;
33
+ }
34
+ /** @throws {StorageUnavailableError} when nothing is bound. */
35
+ export function getStorageAdapter() {
36
+ const bound = adapter.get();
37
+ if (!bound)
38
+ throw new StorageUnavailableError();
39
+ return bound;
40
+ }
41
+ /** The key a chat attachment is stored under. */
42
+ export function attachmentStorageKey(workspaceId, id) {
43
+ return `ws/${workspaceId}/att/${id}`;
44
+ }
45
+ async function toBytes(body) {
46
+ if (body instanceof Uint8Array)
47
+ return body;
48
+ if (body instanceof Blob)
49
+ return new Uint8Array(await body.arrayBuffer());
50
+ const chunks = [];
51
+ const reader = body.getReader();
52
+ for (;;) {
53
+ const { done, value } = await reader.read();
54
+ if (done)
55
+ break;
56
+ chunks.push(value);
57
+ }
58
+ const size = chunks.reduce((n, c) => n + c.byteLength, 0);
59
+ const out = new Uint8Array(size);
60
+ let offset = 0;
61
+ for (const chunk of chunks) {
62
+ out.set(chunk, offset);
63
+ offset += chunk.byteLength;
64
+ }
65
+ return out;
66
+ }
67
+ function toBase64(bytes) {
68
+ if (typeof Buffer !== "undefined")
69
+ return Buffer.from(bytes).toString("base64");
70
+ let binary = "";
71
+ for (const byte of bytes)
72
+ binary += String.fromCharCode(byte);
73
+ return btoa(binary);
74
+ }
75
+ /**
76
+ * Files in memory, "signed" as data URLs, for tests and apps without a
77
+ * bucket. Nothing survives a restart.
78
+ */
79
+ export function createMemoryStorage() {
80
+ const objects = new Map();
81
+ return {
82
+ objects,
83
+ async put({ key, body, contentType }) {
84
+ const bytes = await toBytes(body);
85
+ objects.set(key, { bytes, contentType });
86
+ return { key, contentType, size: bytes.byteLength };
87
+ },
88
+ async getSignedUrl(key) {
89
+ const object = objects.get(key);
90
+ if (!object)
91
+ throw new Error(`No object at ${key}`);
92
+ return `data:${object.contentType};base64,${toBase64(object.bytes)}`;
93
+ },
94
+ async get(key) {
95
+ const object = objects.get(key);
96
+ if (!object)
97
+ throw new Error(`No object at ${key}`);
98
+ return {
99
+ body: new Blob([object.bytes]).stream(),
100
+ contentType: object.contentType,
101
+ size: object.bytes.byteLength,
102
+ };
103
+ },
104
+ async delete(key) {
105
+ objects.delete(key);
106
+ },
107
+ };
108
+ }
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,15 +1,28 @@
1
1
  {
2
2
  "name": "@intelligo-dev/core",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.13",
4
+ "description": "Database schema, email, logging, notifications, and the conversation, document and identity contracts.",
5
+ "keywords": [
6
+ "intelligo",
7
+ "ai-saas",
8
+ "saas",
9
+ "typescript",
10
+ "drizzle",
11
+ "postgres",
12
+ "pgvector",
13
+ "conversations",
14
+ "documents"
15
+ ],
4
16
  "license": "Apache-2.0",
17
+ "author": "Turtuvshin Byambaa <toroo.byamba@gmail.com>",
5
18
  "repository": {
6
19
  "type": "git",
7
- "url": "git+https://github.com/intelligo-mn/framework.git",
20
+ "url": "git+https://github.com/intelligo-dev/intelligo.git",
8
21
  "directory": "packages/core"
9
22
  },
10
- "homepage": "https://github.com/intelligo-mn/framework#readme",
23
+ "homepage": "https://intelligo.dev/docs/packages/core",
11
24
  "bugs": {
12
- "url": "https://github.com/intelligo-mn/framework/issues"
25
+ "url": "https://github.com/intelligo-dev/intelligo/issues"
13
26
  },
14
27
  "type": "module",
15
28
  "exports": {
@@ -45,10 +58,34 @@
45
58
  "types": "./dist/identity/index.d.ts",
46
59
  "default": "./dist/identity/index.js"
47
60
  },
61
+ "./attachments": {
62
+ "types": "./dist/attachments/index.d.ts",
63
+ "default": "./dist/attachments/index.js"
64
+ },
65
+ "./storage": {
66
+ "types": "./dist/storage/index.d.ts",
67
+ "default": "./dist/storage/index.js"
68
+ },
48
69
  "./env": {
49
70
  "types": "./dist/env.d.ts",
50
71
  "default": "./dist/env.js"
51
72
  },
73
+ "./registry": {
74
+ "types": "./dist/registry.d.ts",
75
+ "default": "./dist/registry.js"
76
+ },
77
+ "./money": {
78
+ "types": "./dist/money.d.ts",
79
+ "default": "./dist/money.js"
80
+ },
81
+ "./request-context": {
82
+ "types": "./dist/request-context.d.ts",
83
+ "default": "./dist/request-context.js"
84
+ },
85
+ "./prompt": {
86
+ "types": "./dist/prompt.d.ts",
87
+ "default": "./dist/prompt.js"
88
+ },
52
89
  "./logger": {
53
90
  "types": "./dist/logger.d.ts",
54
91
  "import": "./dist/logger.js",
@@ -56,38 +93,51 @@
56
93
  }
57
94
  },
58
95
  "dependencies": {
59
- "@neondatabase/serverless": "^0.10.4",
60
- "@react-email/components": "^1.0.7",
61
- "dotenv": "^16.4.7",
62
- "drizzle-orm": "^0.45.1",
63
- "pg": "^8.18.0",
96
+ "@neondatabase/serverless": "^1.1.0",
97
+ "@react-email/components": "^1.0.12",
98
+ "dotenv": "^17.4.2",
99
+ "pg": "8.18.0",
64
100
  "pino": "^10.3.1",
65
- "react": "^19.0.0",
66
- "resend": "^6.9.1",
67
- "server-only": "^0.0.1",
68
- "zod": "^3.24.1"
101
+ "resend": "^6.28.1"
69
102
  },
70
103
  "peerDependencies": {
71
- "next": "^15.0.0 || ^16.0.0"
104
+ "drizzle-orm": "^0.45.1",
105
+ "react": "^19.0.0"
106
+ },
107
+ "peerDependenciesMeta": {
108
+ "react": {
109
+ "optional": true
110
+ }
72
111
  },
73
112
  "devDependencies": {
74
- "@types/bcryptjs": "^3.0.0",
75
- "@types/pg": "^8.16.0",
76
- "@types/react": "^19.0.10",
77
- "bcryptjs": "^3.0.3",
78
- "drizzle-kit": "^0.31.8",
79
- "next": "^16.0.7",
113
+ "@types/pg": "^8.23.1",
114
+ "@types/react": "19.2.18",
115
+ "drizzle-kit": "^0.31.10",
116
+ "drizzle-orm": "^0.45.2",
117
+ "next": "~16.3.5",
80
118
  "pino-pretty": "^13.1.3",
81
- "tsx": "^4.21.0",
82
- "typescript": "^5.7.2"
119
+ "react": "^19.3.0",
120
+ "tsx": "^4.23.13",
121
+ "typescript": "^5.9.3"
83
122
  },
84
123
  "files": [
85
124
  "dist",
86
- "src/db/migrations"
125
+ "src",
126
+ "!src/**/*.test.ts",
127
+ "!src/**/*.test.tsx",
128
+ "!src/**/__tests__/**",
129
+ "LICENSE",
130
+ "NOTICE",
131
+ "README.md",
132
+ "!dist/**/*.tsbuildinfo"
87
133
  ],
88
134
  "publishConfig": {
89
135
  "access": "public"
90
136
  },
137
+ "engines": {
138
+ "node": ">=22.14"
139
+ },
140
+ "sideEffects": false,
91
141
  "scripts": {
92
142
  "type-check": "tsc --noEmit",
93
143
  "lint": "eslint .",
@@ -96,6 +146,6 @@
96
146
  "db:studio": "drizzle-kit studio",
97
147
  "db:push": "drizzle-kit push",
98
148
  "db:check": "tsx scripts/check-db.ts",
99
- "build": "tsc -p tsconfig.build.json"
149
+ "build": "tsc -p tsconfig.build.json && node ../../scripts/fix-esm-extensions.mjs dist"
100
150
  }
101
151
  }
@@ -0,0 +1,18 @@
1
+ export type AttachmentServiceErrorCode =
2
+ "not_found" | "forbidden" | "invalid_input" | "database_error";
3
+
4
+ export class AttachmentServiceError extends Error {
5
+ constructor(
6
+ public readonly code: AttachmentServiceErrorCode,
7
+ message: string
8
+ ) {
9
+ super(message);
10
+ this.name = "AttachmentServiceError";
11
+ }
12
+ }
13
+
14
+ export function isAttachmentServiceError(
15
+ error: unknown
16
+ ): error is AttachmentServiceError {
17
+ return error instanceof AttachmentServiceError;
18
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Rows for the files users put into conversations; the bytes live behind
3
+ * `@intelligo-dev/core/storage`.
4
+ */
5
+
6
+ export {
7
+ attachToConversation,
8
+ createAttachment,
9
+ deleteAttachment,
10
+ getAttachment,
11
+ getAttachments,
12
+ listOrphanAttachments,
13
+ setExtractedText,
14
+ } from "./service";
15
+
16
+ export {
17
+ AttachmentServiceError,
18
+ isAttachmentServiceError,
19
+ type AttachmentServiceErrorCode,
20
+ } from "./errors";
21
+
22
+ export type { Attachment, AttachmentActor, InsertAttachment } from "./types";
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Server-only rows for the files users put into conversations. The bytes
3
+ * live behind the storage port; this table records who uploaded a file,
4
+ * its workspace, type, size and, once the turn is persisted, conversation.
5
+ *
6
+ * Every read and write is scoped to the workspace and the uploader: the ids
7
+ * arrive in the request body, and conversations are user-private, so a
8
+ * workspace-only scope would let a member trade a colleague's attachment id
9
+ * for a signed URL to it.
10
+ */
11
+
12
+ import { and, eq, inArray, isNull, lt } from "drizzle-orm";
13
+
14
+ import { db } from "../db";
15
+ import { attachments } from "../db/schema";
16
+ import { AttachmentServiceError } from "./errors";
17
+ import type { Attachment, AttachmentActor } from "./types";
18
+
19
+ export async function createAttachment(
20
+ actor: AttachmentActor,
21
+ params: {
22
+ id?: string;
23
+ storageKey: string;
24
+ filename: string;
25
+ mediaType: string;
26
+ sizeBytes: number;
27
+ conversationId?: string | null;
28
+ extractedText?: string | null;
29
+ }
30
+ ): Promise<Attachment> {
31
+ if (!params.filename.trim()) {
32
+ throw new AttachmentServiceError("invalid_input", "Filename is required");
33
+ }
34
+ if (params.sizeBytes < 0) {
35
+ throw new AttachmentServiceError(
36
+ "invalid_input",
37
+ "Size cannot be negative"
38
+ );
39
+ }
40
+ const [row] = await db
41
+ .insert(attachments)
42
+ .values({
43
+ id: params.id ?? crypto.randomUUID(),
44
+ workspaceId: actor.workspaceId,
45
+ userId: actor.userId,
46
+ conversationId: params.conversationId ?? null,
47
+ storageKey: params.storageKey,
48
+ filename: params.filename,
49
+ mediaType: params.mediaType,
50
+ sizeBytes: params.sizeBytes,
51
+ extractedText: params.extractedText ?? null,
52
+ })
53
+ .returning();
54
+ if (!row) {
55
+ throw new AttachmentServiceError(
56
+ "database_error",
57
+ "Failed to create attachment"
58
+ );
59
+ }
60
+ return row;
61
+ }
62
+
63
+ /** One attachment, if the actor uploaded it in their own workspace. */
64
+ export async function getAttachment(
65
+ actor: AttachmentActor,
66
+ id: string
67
+ ): Promise<Attachment> {
68
+ const [row] = await db
69
+ .select()
70
+ .from(attachments)
71
+ .where(
72
+ and(
73
+ eq(attachments.id, id),
74
+ eq(attachments.workspaceId, actor.workspaceId),
75
+ eq(attachments.userId, actor.userId)
76
+ )
77
+ )
78
+ .limit(1);
79
+ if (!row) {
80
+ throw new AttachmentServiceError("not_found", "Attachment not found");
81
+ }
82
+ return row;
83
+ }
84
+
85
+ /** The attachments among `ids` that the actor uploaded. */
86
+ export async function getAttachments(
87
+ actor: AttachmentActor,
88
+ ids: readonly string[]
89
+ ): Promise<Attachment[]> {
90
+ if (ids.length === 0) return [];
91
+ return db
92
+ .select()
93
+ .from(attachments)
94
+ .where(
95
+ and(
96
+ inArray(attachments.id, [...ids]),
97
+ eq(attachments.workspaceId, actor.workspaceId),
98
+ eq(attachments.userId, actor.userId)
99
+ )
100
+ );
101
+ }
102
+
103
+ /** Tie uploaded files to the conversation whose turn carried them. */
104
+ export async function attachToConversation(
105
+ actor: AttachmentActor,
106
+ params: { ids: readonly string[]; conversationId: string }
107
+ ): Promise<void> {
108
+ if (params.ids.length === 0) return;
109
+ await db
110
+ .update(attachments)
111
+ .set({ conversationId: params.conversationId })
112
+ .where(
113
+ and(
114
+ inArray(attachments.id, [...params.ids]),
115
+ eq(attachments.workspaceId, actor.workspaceId),
116
+ eq(attachments.userId, actor.userId),
117
+ isNull(attachments.conversationId)
118
+ )
119
+ );
120
+ }
121
+
122
+ export async function setExtractedText(
123
+ actor: AttachmentActor,
124
+ params: { id: string; text: string | null }
125
+ ): Promise<void> {
126
+ await db
127
+ .update(attachments)
128
+ .set({ extractedText: params.text })
129
+ .where(
130
+ and(
131
+ eq(attachments.id, params.id),
132
+ eq(attachments.workspaceId, actor.workspaceId),
133
+ eq(attachments.userId, actor.userId)
134
+ )
135
+ );
136
+ }
137
+
138
+ /** Remove the row. The caller deletes the object behind `storageKey`. */
139
+ export async function deleteAttachment(
140
+ actor: AttachmentActor,
141
+ id: string
142
+ ): Promise<Attachment> {
143
+ const [row] = await db
144
+ .delete(attachments)
145
+ .where(
146
+ and(
147
+ eq(attachments.id, id),
148
+ eq(attachments.workspaceId, actor.workspaceId),
149
+ eq(attachments.userId, actor.userId)
150
+ )
151
+ )
152
+ .returning();
153
+ if (!row) {
154
+ throw new AttachmentServiceError("not_found", "Attachment not found");
155
+ }
156
+ return row;
157
+ }
158
+
159
+ /**
160
+ * Uploads that never made it into a conversation — a turn that was
161
+ * refused, a tab closed mid-compose. A maintenance job deletes them
162
+ * and their objects.
163
+ */
164
+ export async function listOrphanAttachments(params: {
165
+ olderThan: Date;
166
+ limit?: number;
167
+ }): Promise<Attachment[]> {
168
+ return db
169
+ .select()
170
+ .from(attachments)
171
+ .where(
172
+ and(
173
+ isNull(attachments.conversationId),
174
+ lt(attachments.createdAt, params.olderThan)
175
+ )
176
+ )
177
+ .limit(params.limit ?? 100);
178
+ }
@@ -0,0 +1,6 @@
1
+ export type AttachmentActor = {
2
+ workspaceId: string;
3
+ userId: string;
4
+ };
5
+
6
+ export type { Attachment, InsertAttachment } from "../db/schema";
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Thrown by the conversations service for every failure it recognizes.
3
+ * Shaping it into a transport envelope is the caller's job.
4
+ */
5
+
6
+ /**
7
+ * - `not_found` — no conversation, or no message, exists at the given
8
+ * id within the actor's workspace/user scope.
9
+ * - `forbidden` — the target row exists but is outside the actor's
10
+ * scope (a different workspace or a different user's conversation).
11
+ * - `invalid_input` — a caller-supplied argument failed a basic
12
+ * invariant (e.g. an empty title, or a batch of messages that
13
+ * reference a conversation the actor does not own).
14
+ * - `database_error` — the underlying insert/update did not return the
15
+ * row it was expected to.
16
+ */
17
+ export type ConversationServiceErrorCode =
18
+ "not_found" | "forbidden" | "invalid_input" | "database_error";
19
+
20
+ export class ConversationServiceError extends Error {
21
+ readonly code: ConversationServiceErrorCode;
22
+ // The ES2020 target predates `Error.cause`; declared so `err.cause`
23
+ // type-checks for callers.
24
+ readonly cause?: unknown;
25
+
26
+ constructor(
27
+ code: ConversationServiceErrorCode,
28
+ message: string,
29
+ options?: { cause?: unknown }
30
+ ) {
31
+ super(message);
32
+ this.name = "ConversationServiceError";
33
+ this.code = code;
34
+ if (options?.cause !== undefined) {
35
+ (this as { cause?: unknown }).cause = options.cause;
36
+ }
37
+ Object.setPrototypeOf(this, ConversationServiceError.prototype);
38
+ }
39
+ }
40
+
41
+ export function isConversationServiceError(
42
+ error: unknown
43
+ ): error is ConversationServiceError {
44
+ return error instanceof ConversationServiceError;
45
+ }
@@ -0,0 +1,39 @@
1
+ export {
2
+ createConversation,
3
+ getConversation,
4
+ listConversations,
5
+ getConversationHistory,
6
+ renameConversation,
7
+ deleteConversation,
8
+ deleteAllConversations,
9
+ getMessages,
10
+ saveMessages,
11
+ upsertMessages,
12
+ updateMessage,
13
+ deleteTrailingMessages,
14
+ voteMessage,
15
+ getVotes,
16
+ clearVote,
17
+ updateConversationMetadata,
18
+ setConversationVisibility,
19
+ getPublicConversation,
20
+ getPublicMessages,
21
+ } from "./service";
22
+ export type { ConversationVisibility } from "./service";
23
+
24
+ export {
25
+ ConversationServiceError,
26
+ isConversationServiceError,
27
+ type ConversationServiceErrorCode,
28
+ } from "./errors";
29
+
30
+ export type {
31
+ ConversationActor,
32
+ Conversation,
33
+ InsertConversation,
34
+ Message,
35
+ InsertMessage,
36
+ Vote,
37
+ InsertVote,
38
+ ConversationMetadata,
39
+ } from "./types";