comisai 1.0.11 → 1.0.12

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 (247) hide show
  1. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
  2. package/node_modules/@comis/agent/package.json +1 -1
  3. package/node_modules/@comis/channels/package.json +1 -1
  4. package/node_modules/@comis/cli/package.json +1 -1
  5. package/node_modules/@comis/core/package.json +1 -1
  6. package/node_modules/@comis/daemon/package.json +1 -1
  7. package/node_modules/@comis/gateway/package.json +1 -1
  8. package/node_modules/@comis/infra/package.json +1 -1
  9. package/node_modules/@comis/memory/package.json +1 -1
  10. package/node_modules/@comis/scheduler/package.json +1 -1
  11. package/node_modules/@comis/shared/package.json +1 -1
  12. package/node_modules/@comis/skills/package.json +1 -1
  13. package/package.json +18 -18
  14. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  15. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  16. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  17. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  18. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  19. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  20. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  21. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  22. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  24. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  26. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  28. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  30. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  32. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  34. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  36. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  38. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  40. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  42. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  44. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  46. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  48. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  50. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  52. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  54. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  58. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  60. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  62. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  64. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  66. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  68. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  70. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  72. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  74. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  76. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  78. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  80. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  82. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  84. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  86. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  88. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  90. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  92. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  94. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  96. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  98. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  100. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  102. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  104. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  106. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  108. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  110. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  112. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  114. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  116. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  118. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  120. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  122. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  124. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  126. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  128. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  130. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  132. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  134. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  136. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  138. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  140. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  142. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  144. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  146. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  148. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  150. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  152. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  154. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  156. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  158. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  160. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  162. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  164. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  166. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  168. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  169. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  170. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  172. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  174. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  176. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  177. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  178. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  179. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  180. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  181. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  182. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  183. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  184. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  185. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  186. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  188. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  190. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  191. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  192. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  193. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  194. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  195. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  196. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  198. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  200. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  202. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  204. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  206. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  207. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  208. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  209. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  210. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  211. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  212. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  214. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  215. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  216. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  217. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  218. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  219. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  220. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  222. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  224. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  226. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  227. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  228. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  229. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  230. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  232. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  234. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  236. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  237. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  238. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  239. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  240. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  241. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  242. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  243. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  244. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  245. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  246. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  247. 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 {};