comisai 1.0.11 → 1.0.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 (255) hide show
  1. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +1 -0
  2. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +9 -9
  3. package/node_modules/@comis/agent/package.json +1 -1
  4. package/node_modules/@comis/channels/package.json +1 -1
  5. package/node_modules/@comis/cli/package.json +1 -1
  6. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +2 -0
  7. package/node_modules/@comis/core/package.json +1 -1
  8. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +12 -1
  9. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +1 -0
  10. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +1 -0
  11. package/node_modules/@comis/daemon/package.json +1 -1
  12. package/node_modules/@comis/gateway/package.json +1 -1
  13. package/node_modules/@comis/infra/package.json +1 -1
  14. package/node_modules/@comis/memory/package.json +1 -1
  15. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +6 -0
  16. package/node_modules/@comis/scheduler/dist/cron/cron-types.js +2 -0
  17. package/node_modules/@comis/scheduler/package.json +1 -1
  18. package/node_modules/@comis/shared/package.json +1 -1
  19. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  20. package/node_modules/@comis/skills/package.json +1 -1
  21. package/package.json +18 -18
  22. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  24. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  26. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  28. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  30. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  32. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  34. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  36. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  38. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  40. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  42. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  44. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  46. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  48. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  50. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  52. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  54. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  58. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  60. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  62. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  64. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  66. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  68. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  70. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  72. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  74. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  76. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  78. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  80. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  82. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  84. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  86. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  88. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  90. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  92. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  94. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  96. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  98. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  100. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  102. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  104. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  106. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  108. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  110. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  112. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  114. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  116. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  118. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  120. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  122. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  124. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  126. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  128. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  130. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  132. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  134. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  136. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  138. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  140. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  142. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  144. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  146. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  148. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  150. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  152. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  154. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  156. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  158. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  160. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  162. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  164. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  166. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  168. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  170. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  172. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  174. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  176. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  177. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  178. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  180. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  181. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  182. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  183. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  184. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  186. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  188. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  190. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  191. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  192. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  193. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  194. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  196. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  198. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  200. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  202. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  204. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  206. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  207. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  208. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  210. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  212. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  214. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  215. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  216. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  217. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  218. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  220. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  222. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  224. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  226. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  227. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  228. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  230. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  232. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  234. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  236. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  237. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  238. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  240. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  241. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  242. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  243. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  244. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  245. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  246. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  248. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  250. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  252. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  253. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  254. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  255. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1 +0,0 @@
1
- export {};
@@ -1,409 +0,0 @@
1
- import Database from "better-sqlite3";
2
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
3
- import { rowToEntry, insertMemoryRow, storeEmbedding, buildFilterClause, countRows, groupCountRows, ALLOWED_TABLES, ALLOWED_GROUP_COLUMNS, } from "./row-mapper.js";
4
- import { initSchema, isVecAvailable } from "./schema.js";
5
- const DIMS = 4;
6
- // ── Test Fixtures ────────────────────────────────────────────────────
7
- /** Create a complete MemoryRow with all fields populated. */
8
- function makeRow(overrides) {
9
- const defaults = {
10
- id: "row-1",
11
- tenant_id: "default",
12
- agent_id: "default",
13
- user_id: "user-1",
14
- content: "test content",
15
- trust_level: "learned",
16
- memory_type: "semantic",
17
- source_who: "agent",
18
- source_channel: "telegram",
19
- source_session_key: "sess-123",
20
- tags: '["tag1","tag2"]',
21
- created_at: 1700000000000,
22
- updated_at: 1700001000000,
23
- expires_at: 1700090000000,
24
- has_embedding: 0,
25
- };
26
- return { ...defaults, ...overrides };
27
- }
28
- /** Create a minimal valid MemoryEntry. */
29
- function makeEntry(overrides) {
30
- return {
31
- id: overrides?.id ?? crypto.randomUUID(),
32
- tenantId: overrides?.tenantId ?? "default",
33
- agentId: overrides?.agentId ?? "default",
34
- userId: overrides?.userId ?? "user-1",
35
- content: overrides?.content ?? "test memory content",
36
- trustLevel: overrides?.trustLevel ?? "learned",
37
- source: overrides?.source ?? { who: "agent", channel: "telegram" },
38
- tags: overrides?.tags ?? [],
39
- createdAt: overrides?.createdAt ?? Date.now(),
40
- ...(overrides?.updatedAt !== undefined ? { updatedAt: overrides.updatedAt } : {}),
41
- ...(overrides?.expiresAt !== undefined ? { expiresAt: overrides.expiresAt } : {}),
42
- ...(overrides?.embedding ? { embedding: overrides.embedding } : {}),
43
- };
44
- }
45
- // ── rowToEntry ───────────────────────────────────────────────────────
46
- describe("rowToEntry", () => {
47
- it("converts a complete MemoryRow with all fields populated", () => {
48
- const row = makeRow();
49
- const entry = rowToEntry(row);
50
- expect(entry.id).toBe("row-1");
51
- expect(entry.tenantId).toBe("default");
52
- expect(entry.agentId).toBe("default");
53
- expect(entry.userId).toBe("user-1");
54
- expect(entry.content).toBe("test content");
55
- expect(entry.trustLevel).toBe("learned");
56
- expect(entry.source.who).toBe("agent");
57
- expect(entry.source.channel).toBe("telegram");
58
- expect(entry.source.sessionKey).toBe("sess-123");
59
- expect(entry.tags).toEqual(["tag1", "tag2"]);
60
- expect(entry.createdAt).toBe(1700000000000);
61
- expect(entry.updatedAt).toBe(1700001000000);
62
- expect(entry.expiresAt).toBe(1700090000000);
63
- });
64
- it("converts a MemoryRow with null optional fields", () => {
65
- const row = makeRow({
66
- source_channel: null,
67
- source_session_key: null,
68
- updated_at: null,
69
- expires_at: null,
70
- });
71
- const entry = rowToEntry(row);
72
- expect(entry.source.channel).toBeUndefined();
73
- expect(entry.source.sessionKey).toBeUndefined();
74
- expect(entry.updatedAt).toBeUndefined();
75
- expect(entry.expiresAt).toBeUndefined();
76
- });
77
- it("includes embedding when provided", () => {
78
- const row = makeRow();
79
- const embedding = [0.1, 0.2, 0.3, 0.4];
80
- const entry = rowToEntry(row, embedding);
81
- expect(entry.embedding).toEqual([0.1, 0.2, 0.3, 0.4]);
82
- });
83
- it("omits embedding when not provided", () => {
84
- const row = makeRow();
85
- const entry = rowToEntry(row);
86
- expect(entry.embedding).toBeUndefined();
87
- });
88
- it("correctly parses JSON tags", () => {
89
- const row = makeRow({ tags: '["important","project-x","review"]' });
90
- const entry = rowToEntry(row);
91
- expect(entry.tags).toEqual(["important", "project-x", "review"]);
92
- });
93
- it("parses empty JSON tags array", () => {
94
- const row = makeRow({ tags: "[]" });
95
- const entry = rowToEntry(row);
96
- expect(entry.tags).toEqual([]);
97
- });
98
- });
99
- // ── insertMemoryRow ──────────────────────────────────────────────────
100
- describe("insertMemoryRow", () => {
101
- let db;
102
- beforeEach(() => {
103
- db = new Database(":memory:");
104
- initSchema(db, DIMS);
105
- });
106
- afterEach(() => {
107
- db.close();
108
- });
109
- it("inserts a row with all fields", () => {
110
- const entry = makeEntry({
111
- id: "mem-1",
112
- tenantId: "tenant-a",
113
- agentId: "coder",
114
- userId: "user-42",
115
- content: "important fact",
116
- trustLevel: "system",
117
- source: { who: "admin", channel: "cli", sessionKey: "sk-1" },
118
- tags: ["critical"],
119
- createdAt: 1700000000000,
120
- updatedAt: 1700001000000,
121
- expiresAt: 1700090000000,
122
- });
123
- insertMemoryRow(db, entry, "semantic");
124
- const row = db.prepare("SELECT * FROM memories WHERE id = ?").get("mem-1");
125
- expect(row.id).toBe("mem-1");
126
- expect(row.tenant_id).toBe("tenant-a");
127
- expect(row.agent_id).toBe("coder");
128
- expect(row.user_id).toBe("user-42");
129
- expect(row.content).toBe("important fact");
130
- expect(row.trust_level).toBe("system");
131
- expect(row.memory_type).toBe("semantic");
132
- expect(row.source_who).toBe("admin");
133
- expect(row.source_channel).toBe("cli");
134
- expect(row.source_session_key).toBe("sk-1");
135
- expect(JSON.parse(row.tags)).toEqual(["critical"]);
136
- expect(row.created_at).toBe(1700000000000);
137
- expect(row.updated_at).toBe(1700001000000);
138
- expect(row.expires_at).toBe(1700090000000);
139
- expect(row.has_embedding).toBe(0);
140
- });
141
- it("defaults agentId to 'default' when undefined", () => {
142
- const entry = makeEntry({ id: "mem-2" });
143
- // Force agentId to undefined to test default path
144
- entry.agentId = undefined;
145
- insertMemoryRow(db, entry, "working");
146
- const row = db.prepare("SELECT agent_id FROM memories WHERE id = ?").get("mem-2");
147
- expect(row.agent_id).toBe("default");
148
- });
149
- it("handles null optional fields (source_channel, source_session_key, expires_at)", () => {
150
- const entry = makeEntry({
151
- id: "mem-3",
152
- source: { who: "agent" },
153
- });
154
- insertMemoryRow(db, entry, "episodic");
155
- const row = db.prepare("SELECT * FROM memories WHERE id = ?").get("mem-3");
156
- expect(row.source_channel).toBeNull();
157
- expect(row.source_session_key).toBeNull();
158
- expect(row.expires_at).toBeNull();
159
- });
160
- it("stores correct memory_type", () => {
161
- const entry = makeEntry({ id: "mem-4" });
162
- insertMemoryRow(db, entry, "procedural");
163
- const row = db.prepare("SELECT memory_type FROM memories WHERE id = ?").get("mem-4");
164
- expect(row.memory_type).toBe("procedural");
165
- });
166
- });
167
- // ── storeEmbedding ───────────────────────────────────────────────────
168
- describe("storeEmbedding", () => {
169
- let db;
170
- beforeEach(() => {
171
- db = new Database(":memory:");
172
- initSchema(db, DIMS);
173
- });
174
- afterEach(() => {
175
- db.close();
176
- });
177
- it("inserts embedding and sets has_embedding=1", () => {
178
- if (!isVecAvailable())
179
- return;
180
- // First insert a memory row
181
- const entry = makeEntry({ id: "mem-embed-1" });
182
- insertMemoryRow(db, entry, "semantic");
183
- // Store embedding
184
- storeEmbedding(db, "mem-embed-1", [0.1, 0.2, 0.3, 0.4]);
185
- // Verify has_embedding flag
186
- const row = db.prepare("SELECT has_embedding FROM memories WHERE id = ?").get("mem-embed-1");
187
- expect(row.has_embedding).toBe(1);
188
- // Verify vec_memories entry exists
189
- const vecRow = db
190
- .prepare("SELECT memory_id FROM vec_memories WHERE memory_id = ?")
191
- .get("mem-embed-1");
192
- expect(vecRow).toBeDefined();
193
- expect(vecRow.memory_id).toBe("mem-embed-1");
194
- });
195
- it("stores correct float values in vec_memories", () => {
196
- if (!isVecAvailable())
197
- return;
198
- const entry = makeEntry({ id: "mem-embed-2" });
199
- insertMemoryRow(db, entry, "semantic");
200
- storeEmbedding(db, "mem-embed-2", [0.5, 0.25, 0.75, 1.0]);
201
- const vecRow = db
202
- .prepare("SELECT embedding FROM vec_memories WHERE memory_id = ?")
203
- .get("mem-embed-2");
204
- expect(vecRow).toBeDefined();
205
- const float32 = new Float32Array(vecRow.embedding.buffer, vecRow.embedding.byteOffset, vecRow.embedding.byteLength / Float32Array.BYTES_PER_ELEMENT);
206
- expect(float32[0]).toBeCloseTo(0.5, 4);
207
- expect(float32[1]).toBeCloseTo(0.25, 4);
208
- expect(float32[2]).toBeCloseTo(0.75, 4);
209
- expect(float32[3]).toBeCloseTo(1.0, 4);
210
- });
211
- it("no-ops when sqlite-vec is unavailable", () => {
212
- // This test verifies the function doesn't throw when vec is unavailable.
213
- // We can't easily mock isVecAvailable, but we verify it's called
214
- // by passing through without error. If vec IS available, this test
215
- // exercises the normal path instead.
216
- const entry = makeEntry({ id: "mem-embed-3" });
217
- insertMemoryRow(db, entry, "semantic");
218
- // Should not throw regardless of vec availability
219
- expect(() => storeEmbedding(db, "mem-embed-3", [0.1, 0.2, 0.3, 0.4])).not.toThrow();
220
- });
221
- });
222
- // ── buildFilterClause ────────────────────────────────────────────────
223
- describe("buildFilterClause", () => {
224
- it("empty filters produce empty clause", () => {
225
- const result = buildFilterClause({});
226
- expect(result.clause).toBe("");
227
- expect(result.params).toEqual([]);
228
- });
229
- it("single filter produces correct WHERE clause", () => {
230
- const result = buildFilterClause({ tenantId: "t1" });
231
- expect(result.clause).toBe("WHERE tenant_id = ?");
232
- expect(result.params).toEqual(["t1"]);
233
- });
234
- it("multiple filters combine with AND", () => {
235
- const result = buildFilterClause({
236
- memoryType: "semantic",
237
- trustLevel: "learned",
238
- tenantId: "t1",
239
- });
240
- expect(result.clause).toBe("WHERE memory_type = ? AND trust_level = ? AND tenant_id = ?");
241
- expect(result.params).toEqual(["semantic", "learned", "t1"]);
242
- });
243
- it("params array matches clause placeholders", () => {
244
- const result = buildFilterClause({
245
- agentId: "coder",
246
- createdAfter: 1000,
247
- createdBefore: 2000,
248
- });
249
- const placeholderCount = (result.clause.match(/\?/g) ?? []).length;
250
- expect(placeholderCount).toBe(result.params.length);
251
- expect(result.params).toEqual(["coder", 1000, 2000]);
252
- });
253
- it("handles all filter types together", () => {
254
- const result = buildFilterClause({
255
- memoryType: "episodic",
256
- trustLevel: "system",
257
- tenantId: "t1",
258
- agentId: "bot",
259
- createdAfter: 100,
260
- createdBefore: 900,
261
- olderThan: 800,
262
- });
263
- expect(result.clause).toContain("WHERE");
264
- expect(result.clause).toContain("memory_type = ?");
265
- expect(result.clause).toContain("trust_level = ?");
266
- expect(result.clause).toContain("tenant_id = ?");
267
- expect(result.clause).toContain("agent_id = ?");
268
- expect(result.clause).toContain("created_at > ?");
269
- // createdBefore and olderThan both produce "created_at < ?"
270
- expect((result.clause.match(/created_at < \?/g) ?? []).length).toBe(2);
271
- expect(result.params).toHaveLength(7);
272
- });
273
- it("undefined values are skipped", () => {
274
- const result = buildFilterClause({
275
- memoryType: undefined,
276
- trustLevel: "external",
277
- tenantId: undefined,
278
- });
279
- expect(result.clause).toBe("WHERE trust_level = ?");
280
- expect(result.params).toEqual(["external"]);
281
- });
282
- });
283
- // ── countRows ───────────────────────────────────────────────────────
284
- describe("countRows", () => {
285
- let db;
286
- beforeEach(() => {
287
- db = new Database(":memory:");
288
- initSchema(db, DIMS);
289
- });
290
- afterEach(() => {
291
- db.close();
292
- });
293
- it("returns 0 for an empty table", () => {
294
- const count = countRows(db, "memories", "", []);
295
- expect(count).toBe(0);
296
- });
297
- it("returns correct count with entries", () => {
298
- insertMemoryRow(db, makeEntry({ id: "cr-1" }), "semantic");
299
- insertMemoryRow(db, makeEntry({ id: "cr-2" }), "episodic");
300
- insertMemoryRow(db, makeEntry({ id: "cr-3" }), "semantic");
301
- const count = countRows(db, "memories", "", []);
302
- expect(count).toBe(3);
303
- });
304
- it("filters correctly with WHERE clause", () => {
305
- insertMemoryRow(db, makeEntry({ id: "cr-4", tenantId: "t1" }), "semantic");
306
- insertMemoryRow(db, makeEntry({ id: "cr-5", tenantId: "t1" }), "episodic");
307
- insertMemoryRow(db, makeEntry({ id: "cr-6", tenantId: "t2" }), "semantic");
308
- const count = countRows(db, "memories", "WHERE tenant_id = ?", ["t1"]);
309
- expect(count).toBe(2);
310
- });
311
- });
312
- // ── groupCountRows ──────────────────────────────────────────────────
313
- describe("groupCountRows", () => {
314
- let db;
315
- beforeEach(() => {
316
- db = new Database(":memory:");
317
- initSchema(db, DIMS);
318
- });
319
- afterEach(() => {
320
- db.close();
321
- });
322
- it("returns empty object for an empty table", () => {
323
- const result = groupCountRows(db, "memories", "memory_type", "", []);
324
- expect(result).toEqual({});
325
- });
326
- it("groups by memory_type correctly", () => {
327
- insertMemoryRow(db, makeEntry({ id: "gc-1" }), "semantic");
328
- insertMemoryRow(db, makeEntry({ id: "gc-2" }), "semantic");
329
- insertMemoryRow(db, makeEntry({ id: "gc-3" }), "episodic");
330
- insertMemoryRow(db, makeEntry({ id: "gc-4" }), "working");
331
- const result = groupCountRows(db, "memories", "memory_type", "", []);
332
- expect(result).toEqual({
333
- semantic: 2,
334
- episodic: 1,
335
- working: 1,
336
- });
337
- });
338
- it("filters groups with WHERE clause", () => {
339
- insertMemoryRow(db, makeEntry({ id: "gc-5", tenantId: "t1" }), "semantic");
340
- insertMemoryRow(db, makeEntry({ id: "gc-6", tenantId: "t1" }), "episodic");
341
- insertMemoryRow(db, makeEntry({ id: "gc-7", tenantId: "t2" }), "semantic");
342
- const result = groupCountRows(db, "memories", "memory_type", "WHERE tenant_id = ?", ["t1"]);
343
- expect(result).toEqual({
344
- semantic: 1,
345
- episodic: 1,
346
- });
347
- });
348
- });
349
- // ── DATA-03: Whitelist validation for table/column names ───────────
350
- describe("countRows whitelist validation", () => {
351
- let db;
352
- beforeEach(() => {
353
- db = new Database(":memory:");
354
- initSchema(db, DIMS);
355
- });
356
- afterEach(() => {
357
- db.close();
358
- });
359
- it("accepts 'memories' table", () => {
360
- expect(() => countRows(db, "memories", "", [])).not.toThrow();
361
- });
362
- it("accepts 'sessions' table", () => {
363
- expect(() => countRows(db, "sessions", "", [])).not.toThrow();
364
- });
365
- it("rejects invalid table name", () => {
366
- expect(() => countRows(db, "evil_table", "", [])).toThrow('countRows: invalid table "evil_table"');
367
- });
368
- it("rejects SQL injection in table name", () => {
369
- expect(() => countRows(db, "memories; DROP TABLE memories;--", "", [])).toThrow("countRows: invalid table");
370
- });
371
- });
372
- describe("groupCountRows whitelist validation", () => {
373
- let db;
374
- beforeEach(() => {
375
- db = new Database(":memory:");
376
- initSchema(db, DIMS);
377
- });
378
- afterEach(() => {
379
- db.close();
380
- });
381
- it("accepts 'memory_type' column", () => {
382
- expect(() => groupCountRows(db, "memories", "memory_type", "", [])).not.toThrow();
383
- });
384
- it("accepts 'trust_level' column", () => {
385
- expect(() => groupCountRows(db, "memories", "trust_level", "", [])).not.toThrow();
386
- });
387
- it("accepts 'agent_id' column", () => {
388
- expect(() => groupCountRows(db, "memories", "agent_id", "", [])).not.toThrow();
389
- });
390
- it("rejects invalid column name", () => {
391
- expect(() => groupCountRows(db, "memories", "evil_column", "", [])).toThrow('groupCountRows: invalid column "evil_column"');
392
- });
393
- it("rejects invalid table name", () => {
394
- expect(() => groupCountRows(db, "evil_table", "memory_type", "", [])).toThrow('groupCountRows: invalid table "evil_table"');
395
- });
396
- });
397
- describe("whitelist exports", () => {
398
- it("ALLOWED_TABLES contains expected values", () => {
399
- expect(ALLOWED_TABLES.has("memories")).toBe(true);
400
- expect(ALLOWED_TABLES.has("sessions")).toBe(true);
401
- expect(ALLOWED_TABLES.size).toBe(2);
402
- });
403
- it("ALLOWED_GROUP_COLUMNS contains expected values", () => {
404
- expect(ALLOWED_GROUP_COLUMNS.has("memory_type")).toBe(true);
405
- expect(ALLOWED_GROUP_COLUMNS.has("trust_level")).toBe(true);
406
- expect(ALLOWED_GROUP_COLUMNS.has("agent_id")).toBe(true);
407
- expect(ALLOWED_GROUP_COLUMNS.size).toBe(3);
408
- });
409
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,240 +0,0 @@
1
- import Database from "better-sqlite3";
2
- import { describe, it, expect, beforeEach } from "vitest";
3
- import { initSchema, isVecAvailable } from "./schema.js";
4
- describe("initSchema", () => {
5
- let db;
6
- beforeEach(() => {
7
- db = new Database(":memory:");
8
- });
9
- it("creates the memories table with correct columns", () => {
10
- initSchema(db, 1536);
11
- const columns = db.prepare("PRAGMA table_info(memories)").all();
12
- const colNames = columns.map((c) => c.name);
13
- expect(colNames).toContain("id");
14
- expect(colNames).toContain("tenant_id");
15
- expect(colNames).toContain("user_id");
16
- expect(colNames).toContain("content");
17
- expect(colNames).toContain("trust_level");
18
- expect(colNames).toContain("memory_type");
19
- expect(colNames).toContain("source_who");
20
- expect(colNames).toContain("source_channel");
21
- expect(colNames).toContain("source_session_key");
22
- expect(colNames).toContain("tags");
23
- expect(colNames).toContain("created_at");
24
- expect(colNames).toContain("updated_at");
25
- expect(colNames).toContain("expires_at");
26
- expect(colNames).toContain("has_embedding");
27
- });
28
- it("creates the sessions table", () => {
29
- initSchema(db, 1536);
30
- const columns = db.prepare("PRAGMA table_info(sessions)").all();
31
- const colNames = columns.map((c) => c.name);
32
- expect(colNames).toContain("session_key");
33
- expect(colNames).toContain("tenant_id");
34
- expect(colNames).toContain("user_id");
35
- expect(colNames).toContain("channel_id");
36
- expect(colNames).toContain("messages");
37
- expect(colNames).toContain("created_at");
38
- expect(colNames).toContain("updated_at");
39
- expect(colNames).toContain("metadata");
40
- });
41
- it("creates the memory_fts virtual table", () => {
42
- initSchema(db, 1536);
43
- const tables = db
44
- .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='memory_fts'")
45
- .all();
46
- expect(tables).toHaveLength(1);
47
- expect(tables[0].name).toBe("memory_fts");
48
- });
49
- it("creates the vec_memories virtual table when vec is available", () => {
50
- initSchema(db, 1536);
51
- if (!isVecAvailable()) {
52
- // Skip on platforms where sqlite-vec cannot load
53
- return;
54
- }
55
- const tables = db
56
- .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='vec_memories'")
57
- .all();
58
- expect(tables).toHaveLength(1);
59
- expect(tables[0].name).toBe("vec_memories");
60
- });
61
- it("creates all memory indexes", () => {
62
- initSchema(db, 1536);
63
- const indexes = db
64
- .prepare("SELECT name FROM sqlite_master WHERE type='index' AND name LIKE 'idx_memories_%'")
65
- .all();
66
- const indexNames = indexes.map((i) => i.name);
67
- expect(indexNames).toContain("idx_memories_tenant");
68
- expect(indexNames).toContain("idx_memories_trust");
69
- expect(indexNames).toContain("idx_memories_type");
70
- expect(indexNames).toContain("idx_memories_created");
71
- expect(indexNames).toContain("idx_memories_expires");
72
- });
73
- it("creates all session indexes", () => {
74
- initSchema(db, 1536);
75
- const indexes = db
76
- .prepare("SELECT name FROM sqlite_master WHERE type='index' AND name LIKE 'idx_sessions_%'")
77
- .all();
78
- const indexNames = indexes.map((i) => i.name);
79
- expect(indexNames).toContain("idx_sessions_tenant");
80
- expect(indexNames).toContain("idx_sessions_updated");
81
- });
82
- it("FTS5 trigger fires on INSERT", () => {
83
- initSchema(db, 1536);
84
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
85
- VALUES ('m1', 'default', 'u1', 'the quick brown fox', 'learned', 'semantic', 'agent', '[]', 1000)`).run();
86
- const ftsRows = db
87
- .prepare("SELECT * FROM memory_fts WHERE memory_fts MATCH 'fox'")
88
- .all();
89
- expect(ftsRows).toHaveLength(1);
90
- expect(ftsRows[0].content).toBe("the quick brown fox");
91
- });
92
- it("FTS5 trigger fires on DELETE", () => {
93
- initSchema(db, 1536);
94
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
95
- VALUES ('m1', 'default', 'u1', 'the quick brown fox', 'learned', 'semantic', 'agent', '[]', 1000)`).run();
96
- // Verify it's in FTS
97
- let ftsRows = db.prepare("SELECT * FROM memory_fts WHERE memory_fts MATCH 'fox'").all();
98
- expect(ftsRows).toHaveLength(1);
99
- // Delete from base table
100
- db.prepare("DELETE FROM memories WHERE id = 'm1'").run();
101
- // Verify removed from FTS
102
- ftsRows = db.prepare("SELECT * FROM memory_fts WHERE memory_fts MATCH 'fox'").all();
103
- expect(ftsRows).toHaveLength(0);
104
- });
105
- it("FTS5 trigger fires on UPDATE of content", () => {
106
- initSchema(db, 1536);
107
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
108
- VALUES ('m1', 'default', 'u1', 'the quick brown fox', 'learned', 'semantic', 'agent', '[]', 1000)`).run();
109
- // Update content
110
- db.prepare("UPDATE memories SET content = 'lazy dog sleeps' WHERE id = 'm1'").run();
111
- // Old content should not match
112
- const oldRows = db.prepare("SELECT * FROM memory_fts WHERE memory_fts MATCH 'fox'").all();
113
- expect(oldRows).toHaveLength(0);
114
- // New content should match
115
- const newRows = db
116
- .prepare("SELECT * FROM memory_fts WHERE memory_fts MATCH 'dog'")
117
- .all();
118
- expect(newRows).toHaveLength(1);
119
- expect(newRows[0].content).toBe("lazy dog sleeps");
120
- });
121
- it("trust_level CHECK constraint rejects invalid values", () => {
122
- initSchema(db, 1536);
123
- expect(() => {
124
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
125
- VALUES ('m1', 'default', 'u1', 'test', 'invalid', 'semantic', 'agent', '[]', 1000)`).run();
126
- }).toThrow();
127
- });
128
- it("memory_type CHECK constraint rejects invalid values", () => {
129
- initSchema(db, 1536);
130
- expect(() => {
131
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
132
- VALUES ('m1', 'default', 'u1', 'test', 'learned', 'invalid_type', 'agent', '[]', 1000)`).run();
133
- }).toThrow();
134
- });
135
- it("isVecAvailable() returns true after successful init", () => {
136
- initSchema(db, 1536);
137
- // On platforms with sqlite-vec support, this should be true
138
- // This test validates the flag is set correctly
139
- const available = isVecAvailable();
140
- expect(typeof available).toBe("boolean");
141
- // On this platform, sqlite-vec should load
142
- expect(available).toBe(true);
143
- });
144
- it("initSchema is idempotent -- calling twice does not error", () => {
145
- initSchema(db, 1536);
146
- expect(() => initSchema(db, 1536)).not.toThrow();
147
- // Tables still exist after second call
148
- const tables = db
149
- .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('memories', 'sessions')")
150
- .all();
151
- expect(tables).toHaveLength(2);
152
- });
153
- it("vec_memories dimension matches config", () => {
154
- initSchema(db, 384);
155
- if (!isVecAvailable())
156
- return;
157
- // Insert a vector with correct dimensions (384)
158
- const float32 = new Float32Array(384);
159
- float32[0] = 1.0;
160
- expect(() => {
161
- db.prepare("INSERT INTO vec_memories(memory_id, embedding) VALUES (?, ?)").run("test-id", float32);
162
- }).not.toThrow();
163
- // Verify the entry exists
164
- const row = db
165
- .prepare("SELECT memory_id FROM vec_memories WHERE memory_id = ?")
166
- .get("test-id");
167
- expect(row).toBeDefined();
168
- expect(row.memory_id).toBe("test-id");
169
- });
170
- it("vec_memories rejects vectors with wrong dimensions", () => {
171
- initSchema(db, 384);
172
- if (!isVecAvailable())
173
- return;
174
- // Try to insert a vector with wrong dimensions (1536 instead of 384)
175
- const wrongFloat32 = new Float32Array(1536);
176
- wrongFloat32[0] = 1.0;
177
- expect(() => {
178
- db.prepare("INSERT INTO vec_memories(memory_id, embedding) VALUES (?, ?)").run("test-wrong", wrongFloat32);
179
- }).toThrow();
180
- });
181
- it("accepts all valid trust_level values", () => {
182
- initSchema(db, 1536);
183
- const levels = ["system", "learned", "external"];
184
- for (const level of levels) {
185
- expect(() => {
186
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
187
- VALUES (?, 'default', 'u1', 'test', ?, 'semantic', 'agent', '[]', 1000)`).run(`m-${level}`, level);
188
- }).not.toThrow();
189
- }
190
- });
191
- it("accepts all valid memory_type values", () => {
192
- initSchema(db, 1536);
193
- const types = ["working", "episodic", "semantic", "procedural"];
194
- for (const type of types) {
195
- expect(() => {
196
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at)
197
- VALUES (?, 'default', 'u1', 'test', 'learned', ?, 'agent', '[]', 1000)`).run(`m-${type}`, type);
198
- }).not.toThrow();
199
- }
200
- });
201
- // ── DATA-05: initSchema returns per-instance vecAvailable ──────
202
- describe("initSchema return value", () => {
203
- it("returns { vecAvailable: boolean }", () => {
204
- const result = initSchema(db, 1536);
205
- expect(result).toBeDefined();
206
- expect(typeof result.vecAvailable).toBe("boolean");
207
- });
208
- it("returns vecAvailable: true when sqlite-vec loads", () => {
209
- const result = initSchema(db, 1536);
210
- // On this platform, sqlite-vec should load
211
- expect(result.vecAvailable).toBe(true);
212
- });
213
- it("returns consistent value across multiple calls on same db", () => {
214
- const result1 = initSchema(db, 1536);
215
- const result2 = initSchema(db, 1536);
216
- expect(result1.vecAvailable).toBe(result2.vecAvailable);
217
- });
218
- });
219
- // ── DATA-02: embeddingDimensions runtime assertion ──────────────
220
- describe("embeddingDimensions validation", () => {
221
- it("throws on embeddingDimensions = 0", () => {
222
- expect(() => initSchema(db, 0)).toThrow("Invalid embeddingDimensions");
223
- });
224
- it("throws on embeddingDimensions = -1", () => {
225
- expect(() => initSchema(db, -1)).toThrow("Invalid embeddingDimensions");
226
- });
227
- it("throws on embeddingDimensions = 1.5", () => {
228
- expect(() => initSchema(db, 1.5)).toThrow("Invalid embeddingDimensions");
229
- });
230
- it("throws on embeddingDimensions = NaN", () => {
231
- expect(() => initSchema(db, NaN)).toThrow("Invalid embeddingDimensions");
232
- });
233
- it("does not throw on valid embeddingDimensions = 1536", () => {
234
- expect(() => initSchema(db, 1536)).not.toThrow();
235
- });
236
- it("throws on embeddingDimensions = Infinity", () => {
237
- expect(() => initSchema(db, Infinity)).toThrow("Invalid embeddingDimensions");
238
- });
239
- });
240
- });
@@ -1,7 +0,0 @@
1
- /**
2
- * Tests for secret store schema DDL and canary validation.
3
- *
4
- * Uses in-memory SQLite databases and real crypto from @comis/core
5
- * to validate schema creation and master key mismatch detection.
6
- */
7
- export {};