comisai 1.0.10 → 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 (251) hide show
  1. package/README.md +3 -3
  2. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
  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/dist/wizard/steps/06-channels.js +88 -11
  6. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +4 -0
  7. package/node_modules/@comis/cli/dist/wizard/types.d.ts +1 -0
  8. package/node_modules/@comis/cli/package.json +1 -1
  9. package/node_modules/@comis/core/package.json +1 -1
  10. package/node_modules/@comis/daemon/package.json +1 -1
  11. package/node_modules/@comis/gateway/package.json +1 -1
  12. package/node_modules/@comis/infra/package.json +1 -1
  13. package/node_modules/@comis/memory/package.json +1 -1
  14. package/node_modules/@comis/scheduler/package.json +1 -1
  15. package/node_modules/@comis/shared/package.json +1 -1
  16. package/node_modules/@comis/skills/package.json +1 -1
  17. package/package.json +18 -18
  18. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  19. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  20. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  21. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  22. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  24. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  26. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  28. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  30. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  32. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  34. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  36. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  38. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  40. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  42. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  44. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  46. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  48. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  50. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  52. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  54. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  56. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  58. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  60. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  62. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  64. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  66. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  68. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  70. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  72. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  74. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  76. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  78. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  80. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  82. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  84. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  86. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  88. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  90. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  92. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  94. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  96. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  98. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  100. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  102. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  104. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  106. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  108. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  110. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  112. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  114. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  116. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  118. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  120. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  122. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  124. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  126. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  128. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  130. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  132. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  134. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  136. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  138. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  140. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  142. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  144. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  146. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  148. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  150. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  152. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  154. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  156. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  158. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  160. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  162. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  164. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  166. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  168. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  170. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  172. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  173. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  174. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  176. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  177. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  178. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  180. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  181. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  182. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  183. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  184. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  186. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  187. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  188. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  189. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  190. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  191. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  192. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  193. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  194. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  196. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  198. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  199. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  200. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  202. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  203. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  204. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  206. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  207. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  208. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  210. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  212. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  213. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  214. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  215. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  216. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  217. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  218. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  220. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  222. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  223. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  224. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  226. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  227. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  228. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  230. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  232. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  233. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  234. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  236. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  237. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  238. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  240. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  241. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  242. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  243. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  244. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  245. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  246. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  248. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  250. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1,263 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import Database from "better-sqlite3";
3
- import { initSchema } from "./schema.js";
4
- import { createSqliteDeliveryQueue } from "./delivery-queue-adapter.js";
5
- describe("SqliteDeliveryQueueAdapter", () => {
6
- let db;
7
- let queue;
8
- const now = Date.now();
9
- /** Helper to create a minimal enqueue input. */
10
- function makeEntry(overrides = {}) {
11
- return {
12
- text: "Hello, world!",
13
- channelType: "telegram",
14
- channelId: "ch-123",
15
- tenantId: "default",
16
- optionsJson: "{}",
17
- origin: "agent",
18
- formatApplied: false,
19
- chunkingApplied: false,
20
- maxAttempts: 5,
21
- createdAt: now,
22
- scheduledAt: now,
23
- expireAt: now + 3_600_000,
24
- traceId: "trace-abc",
25
- ...overrides,
26
- };
27
- }
28
- beforeEach(() => {
29
- db = new Database(":memory:");
30
- initSchema(db, 768);
31
- queue = createSqliteDeliveryQueue(db);
32
- });
33
- // -----------------------------------------------------------------------
34
- // enqueue
35
- // -----------------------------------------------------------------------
36
- describe("enqueue", () => {
37
- it("returns ok with a UUID string", async () => {
38
- const result = await queue.enqueue(makeEntry());
39
- expect(result.ok).toBe(true);
40
- if (result.ok) {
41
- expect(result.value).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
42
- }
43
- });
44
- it("increments depth to 1 after enqueue", async () => {
45
- await queue.enqueue(makeEntry());
46
- const depth = await queue.depth();
47
- expect(depth.ok).toBe(true);
48
- if (depth.ok) {
49
- expect(depth.value).toBe(1);
50
- }
51
- });
52
- it("persists all fields correctly", async () => {
53
- await queue.enqueue(makeEntry({ formatApplied: true, chunkingApplied: true }));
54
- const pending = await queue.pendingEntries();
55
- expect(pending.ok).toBe(true);
56
- if (pending.ok) {
57
- const entry = pending.value[0];
58
- expect(entry.text).toBe("Hello, world!");
59
- expect(entry.channelType).toBe("telegram");
60
- expect(entry.channelId).toBe("ch-123");
61
- expect(entry.tenantId).toBe("default");
62
- expect(entry.optionsJson).toBe("{}");
63
- expect(entry.origin).toBe("agent");
64
- expect(entry.formatApplied).toBe(true);
65
- expect(entry.chunkingApplied).toBe(true);
66
- expect(entry.status).toBe("pending");
67
- expect(entry.attemptCount).toBe(0);
68
- expect(entry.maxAttempts).toBe(5);
69
- expect(entry.traceId).toBe("trace-abc");
70
- expect(entry.markdownFallbackApplied).toBe(false);
71
- expect(entry.deliveredMessageId).toBeNull();
72
- expect(entry.lastAttemptAt).toBeNull();
73
- expect(entry.nextRetryAt).toBeNull();
74
- expect(entry.lastError).toBeNull();
75
- }
76
- });
77
- });
78
- // -----------------------------------------------------------------------
79
- // ack
80
- // -----------------------------------------------------------------------
81
- describe("ack", () => {
82
- it("marks entry as delivered and removes from depth count", async () => {
83
- const enqResult = await queue.enqueue(makeEntry());
84
- expect(enqResult.ok).toBe(true);
85
- if (!enqResult.ok)
86
- return;
87
- const ackResult = await queue.ack(enqResult.value, "msg-telegram-42");
88
- expect(ackResult.ok).toBe(true);
89
- const depth = await queue.depth();
90
- expect(depth.ok).toBe(true);
91
- if (depth.ok) {
92
- expect(depth.value).toBe(0);
93
- }
94
- });
95
- });
96
- // -----------------------------------------------------------------------
97
- // nack
98
- // -----------------------------------------------------------------------
99
- describe("nack", () => {
100
- it("increments attempt_count, sets next_retry_at and last_error", async () => {
101
- const enqResult = await queue.enqueue(makeEntry());
102
- expect(enqResult.ok).toBe(true);
103
- if (!enqResult.ok)
104
- return;
105
- const retryAt = now + 60_000;
106
- const nackResult = await queue.nack(enqResult.value, "timeout", retryAt);
107
- expect(nackResult.ok).toBe(true);
108
- // Read back the entry to verify fields
109
- const row = db
110
- .prepare("SELECT * FROM delivery_queue WHERE id = ?")
111
- .get(enqResult.value);
112
- expect(row.attempt_count).toBe(1);
113
- expect(row.next_retry_at).toBe(retryAt);
114
- expect(row.last_error).toBe("timeout");
115
- expect(row.status).toBe("pending");
116
- expect(row.last_attempt_at).toBeTypeOf("number");
117
- });
118
- it("keeps entry in pending state (still counted in depth)", async () => {
119
- const enqResult = await queue.enqueue(makeEntry());
120
- if (!enqResult.ok)
121
- return;
122
- await queue.nack(enqResult.value, "err", now + 60_000);
123
- const depth = await queue.depth();
124
- expect(depth.ok).toBe(true);
125
- if (depth.ok) {
126
- expect(depth.value).toBe(1);
127
- }
128
- });
129
- });
130
- // -----------------------------------------------------------------------
131
- // fail
132
- // -----------------------------------------------------------------------
133
- describe("fail", () => {
134
- it("marks entry as permanently failed and removes from depth count", async () => {
135
- const enqResult = await queue.enqueue(makeEntry());
136
- expect(enqResult.ok).toBe(true);
137
- if (!enqResult.ok)
138
- return;
139
- const failResult = await queue.fail(enqResult.value, "permanent: channel not found");
140
- expect(failResult.ok).toBe(true);
141
- // Verify status
142
- const row = db
143
- .prepare("SELECT status, last_error FROM delivery_queue WHERE id = ?")
144
- .get(enqResult.value);
145
- expect(row.status).toBe("failed");
146
- expect(row.last_error).toBe("permanent: channel not found");
147
- // Depth should be 0 (failed entries excluded)
148
- const depth = await queue.depth();
149
- expect(depth.ok).toBe(true);
150
- if (depth.ok) {
151
- expect(depth.value).toBe(0);
152
- }
153
- });
154
- });
155
- // -----------------------------------------------------------------------
156
- // pendingEntries
157
- // -----------------------------------------------------------------------
158
- describe("pendingEntries", () => {
159
- it("returns only entries where scheduled_at <= now, ordered by created_at ASC", async () => {
160
- // Entry 1: scheduled in the past (should appear)
161
- await queue.enqueue(makeEntry({ text: "old", createdAt: now - 3000, scheduledAt: now - 2000 }));
162
- // Entry 2: scheduled now (should appear)
163
- await queue.enqueue(makeEntry({ text: "current", createdAt: now - 2000, scheduledAt: now }));
164
- // Entry 3: scheduled in the future (should NOT appear)
165
- await queue.enqueue(makeEntry({
166
- text: "future",
167
- createdAt: now - 1000,
168
- scheduledAt: now + 60_000,
169
- }));
170
- const result = await queue.pendingEntries();
171
- expect(result.ok).toBe(true);
172
- if (result.ok) {
173
- expect(result.value).toHaveLength(2);
174
- expect(result.value[0].text).toBe("old");
175
- expect(result.value[1].text).toBe("current");
176
- }
177
- });
178
- it("excludes non-pending statuses", async () => {
179
- const enqResult = await queue.enqueue(makeEntry());
180
- if (!enqResult.ok)
181
- return;
182
- await queue.ack(enqResult.value, "msg-1");
183
- const result = await queue.pendingEntries();
184
- expect(result.ok).toBe(true);
185
- if (result.ok) {
186
- expect(result.value).toHaveLength(0);
187
- }
188
- });
189
- });
190
- // -----------------------------------------------------------------------
191
- // pruneExpired
192
- // -----------------------------------------------------------------------
193
- describe("pruneExpired", () => {
194
- it("removes expired non-delivered entries", async () => {
195
- // Entry with expire_at in the past
196
- await queue.enqueue(makeEntry({ expireAt: now - 1000 }));
197
- const result = await queue.pruneExpired();
198
- expect(result.ok).toBe(true);
199
- if (result.ok) {
200
- expect(result.value).toBe(1);
201
- }
202
- const depth = await queue.depth();
203
- expect(depth.ok).toBe(true);
204
- if (depth.ok) {
205
- expect(depth.value).toBe(0);
206
- }
207
- });
208
- it("does NOT prune delivered entries even if expired", async () => {
209
- const enqResult = await queue.enqueue(makeEntry({ expireAt: now - 1000 }));
210
- if (!enqResult.ok)
211
- return;
212
- // Ack it so status = delivered
213
- await queue.ack(enqResult.value, "msg-1");
214
- const result = await queue.pruneExpired();
215
- expect(result.ok).toBe(true);
216
- if (result.ok) {
217
- expect(result.value).toBe(0);
218
- }
219
- // Verify the row still exists
220
- const count = db
221
- .prepare("SELECT COUNT(*) as c FROM delivery_queue")
222
- .get();
223
- expect(count.c).toBe(1);
224
- });
225
- it("returns 0 when nothing to prune", async () => {
226
- const result = await queue.pruneExpired();
227
- expect(result.ok).toBe(true);
228
- if (result.ok) {
229
- expect(result.value).toBe(0);
230
- }
231
- });
232
- });
233
- // -----------------------------------------------------------------------
234
- // depth
235
- // -----------------------------------------------------------------------
236
- describe("depth", () => {
237
- it("counts pending and in_flight entries only", async () => {
238
- // 2 pending entries
239
- await queue.enqueue(makeEntry({ text: "a" }));
240
- await queue.enqueue(makeEntry({ text: "b" }));
241
- // 1 entry acked (delivered)
242
- const ackResult = await queue.enqueue(makeEntry({ text: "c" }));
243
- if (ackResult.ok)
244
- await queue.ack(ackResult.value, "msg-c");
245
- // 1 entry failed
246
- const failResult = await queue.enqueue(makeEntry({ text: "d" }));
247
- if (failResult.ok)
248
- await queue.fail(failResult.value, "permanent");
249
- const depth = await queue.depth();
250
- expect(depth.ok).toBe(true);
251
- if (depth.ok) {
252
- expect(depth.value).toBe(2); // only the 2 pending entries
253
- }
254
- });
255
- it("returns 0 on empty queue", async () => {
256
- const depth = await queue.depth();
257
- expect(depth.ok).toBe(true);
258
- if (depth.ok) {
259
- expect(depth.value).toBe(0);
260
- }
261
- });
262
- });
263
- });
@@ -1,202 +0,0 @@
1
- import { ok, err } from "@comis/shared";
2
- import Database from "better-sqlite3";
3
- import { describe, it, expect, beforeEach, vi } from "vitest";
4
- import { createBatchIndexer } from "./embedding-batch-indexer.js";
5
- import { initSchema } from "./schema.js";
6
- const DIMS = 4;
7
- /** Create a mock EmbeddingPort that returns deterministic vectors. */
8
- function createMockPort(opts) {
9
- let batchCallCount = 0;
10
- const failAfter = opts?.failAfterBatches ?? Infinity;
11
- const embedBatchFn = vi.fn(async (texts) => {
12
- batchCallCount++;
13
- if (batchCallCount > failAfter) {
14
- return err(new Error("provider unavailable"));
15
- }
16
- const vecs = texts.map((t) => {
17
- const vec = new Array(DIMS).fill(0);
18
- for (let i = 0; i < t.length && i < DIMS; i++) {
19
- vec[i] = t.charCodeAt(i) / 256;
20
- }
21
- return vec;
22
- });
23
- return ok(vecs);
24
- });
25
- const port = {
26
- provider: "test",
27
- dimensions: DIMS,
28
- modelId: "test-embed-model",
29
- embed: vi.fn().mockResolvedValue(ok(new Array(DIMS).fill(0))),
30
- embedBatch: embedBatchFn,
31
- embedBatchFn,
32
- get batchCallCount() {
33
- return batchCallCount;
34
- },
35
- };
36
- return port;
37
- }
38
- /** Insert a minimal memory row. */
39
- function insertMemory(db, id, content, hasEmbedding = 0) {
40
- db.prepare(`INSERT INTO memories (id, tenant_id, user_id, content, trust_level, memory_type, source_who, tags, created_at, has_embedding)
41
- VALUES (?, 'default', 'u1', ?, 'learned', 'semantic', 'agent', '[]', ?, ?)`).run(id, content, Date.now(), hasEmbedding);
42
- }
43
- describe("createBatchIndexer", () => {
44
- let db;
45
- beforeEach(() => {
46
- db = new Database(":memory:");
47
- initSchema(db, DIMS);
48
- });
49
- it("indexUnembedded embeds all unembedded memories", async () => {
50
- const port = createMockPort();
51
- const indexer = createBatchIndexer(db, port);
52
- insertMemory(db, "m1", "hello world");
53
- insertMemory(db, "m2", "goodbye world");
54
- insertMemory(db, "m3", "test content");
55
- const result = await indexer.indexUnembedded();
56
- expect(result.indexed).toBe(3);
57
- expect(result.failed).toBe(0);
58
- // All should now be marked as embedded
59
- const count = indexer.unembeddedCount();
60
- expect(count).toBe(0);
61
- });
62
- it("indexUnembedded with multiple batches processes all", async () => {
63
- const port = createMockPort();
64
- const indexer = createBatchIndexer(db, port, { batchSize: 2 });
65
- // Insert 5 memories, batchSize=2 -> 3 batches (2, 2, 1)
66
- for (let i = 0; i < 5; i++) {
67
- insertMemory(db, `m${i}`, `content ${i}`);
68
- }
69
- const result = await indexer.indexUnembedded();
70
- expect(result.indexed).toBe(5);
71
- expect(result.failed).toBe(0);
72
- // Should have been called 3 times (batches of 2, 2, 1)
73
- expect(port.embedBatchFn).toHaveBeenCalledTimes(3);
74
- expect(indexer.unembeddedCount()).toBe(0);
75
- });
76
- it("indexUnembedded stops on embedBatch failure", async () => {
77
- // Fail after the first batch
78
- const port = createMockPort({ failAfterBatches: 1 });
79
- const indexer = createBatchIndexer(db, port, { batchSize: 2 });
80
- // Insert 4 memories -> would need 2 batches
81
- for (let i = 0; i < 4; i++) {
82
- insertMemory(db, `m${i}`, `content ${i}`);
83
- }
84
- const result = await indexer.indexUnembedded();
85
- // First batch of 2 succeeded, second batch of 2 failed
86
- expect(result.indexed).toBe(2);
87
- expect(result.failed).toBe(2);
88
- // 2 still unembedded
89
- expect(indexer.unembeddedCount()).toBe(2);
90
- });
91
- it("reindexAll clears and re-embeds everything", async () => {
92
- const port = createMockPort();
93
- const indexer = createBatchIndexer(db, port);
94
- // Insert memories already marked as embedded
95
- insertMemory(db, "m1", "hello", 1);
96
- insertMemory(db, "m2", "world", 1);
97
- // Verify they start as embedded
98
- expect(indexer.unembeddedCount()).toBe(0);
99
- const result = await indexer.reindexAll();
100
- expect(result.indexed).toBe(2);
101
- expect(result.failed).toBe(0);
102
- // embedBatch should have been called to re-embed
103
- expect(port.embedBatchFn).toHaveBeenCalled();
104
- expect(indexer.unembeddedCount()).toBe(0);
105
- });
106
- it("unembeddedCount returns correct count", () => {
107
- const port = createMockPort();
108
- const indexer = createBatchIndexer(db, port);
109
- expect(indexer.unembeddedCount()).toBe(0);
110
- insertMemory(db, "m1", "hello");
111
- expect(indexer.unembeddedCount()).toBe(1);
112
- insertMemory(db, "m2", "world");
113
- expect(indexer.unembeddedCount()).toBe(2);
114
- // One already embedded
115
- insertMemory(db, "m3", "embedded", 1);
116
- expect(indexer.unembeddedCount()).toBe(2);
117
- });
118
- it("indexUnembedded with no unembedded entries returns zeros", async () => {
119
- const port = createMockPort();
120
- const indexer = createBatchIndexer(db, port);
121
- // No memories at all
122
- const result = await indexer.indexUnembedded();
123
- expect(result.indexed).toBe(0);
124
- expect(result.failed).toBe(0);
125
- // embedBatch should never be called
126
- expect(port.embedBatchFn).not.toHaveBeenCalled();
127
- });
128
- it("indexUnembedded skips already-embedded memories", async () => {
129
- const port = createMockPort();
130
- const indexer = createBatchIndexer(db, port);
131
- // Mix of embedded and unembedded
132
- insertMemory(db, "m1", "already done", 1);
133
- insertMemory(db, "m2", "needs embedding");
134
- const result = await indexer.indexUnembedded();
135
- expect(result.indexed).toBe(1);
136
- expect(result.failed).toBe(0);
137
- // Only 1 text sent to embedBatch
138
- expect(port.embedBatchFn).toHaveBeenCalledTimes(1);
139
- expect(port.embedBatchFn).toHaveBeenCalledWith(["needs embedding"]);
140
- });
141
- it("indexUnembedded handles per-item null failures gracefully", async () => {
142
- // Create a port that returns null for the second item
143
- const perItemFailPort = {
144
- provider: "test",
145
- dimensions: DIMS,
146
- modelId: "test-embed-model",
147
- embed: vi.fn().mockResolvedValue(ok(new Array(DIMS).fill(0))),
148
- embedBatch: vi.fn(async (texts) => {
149
- const vecs = texts.map((t, i) => {
150
- if (i === 1)
151
- return null; // Second item fails
152
- const vec = new Array(DIMS).fill(0);
153
- for (let j = 0; j < t.length && j < DIMS; j++) {
154
- vec[j] = t.charCodeAt(j) / 256;
155
- }
156
- return vec;
157
- });
158
- return ok(vecs);
159
- }),
160
- };
161
- const indexer = createBatchIndexer(db, perItemFailPort);
162
- insertMemory(db, "m1", "hello world");
163
- insertMemory(db, "m2", "this one fails");
164
- insertMemory(db, "m3", "test content");
165
- const result = await indexer.indexUnembedded();
166
- expect(result.indexed).toBe(2);
167
- expect(result.failed).toBe(1);
168
- // Successful ones should have has_embedding = 1
169
- const m1 = db.prepare("SELECT has_embedding FROM memories WHERE id = ?").get("m1");
170
- const m3 = db.prepare("SELECT has_embedding FROM memories WHERE id = ?").get("m3");
171
- expect(m1.has_embedding).toBe(1);
172
- expect(m3.has_embedding).toBe(1);
173
- // Failed one should have has_embedding = -1 (permanently failed, not retried)
174
- const m2 = db.prepare("SELECT has_embedding FROM memories WHERE id = ?").get("m2");
175
- expect(m2.has_embedding).toBe(-1);
176
- // No unembedded (0) left -- all are either 1 or -1
177
- expect(indexer.unembeddedCount()).toBe(0);
178
- });
179
- it("indexUnembedded truncates oversized text before embedding", async () => {
180
- // Track texts passed to embedBatch
181
- let capturedTexts = [];
182
- const capturingPort = {
183
- provider: "test",
184
- dimensions: DIMS,
185
- modelId: "test-embed-model",
186
- embed: vi.fn().mockResolvedValue(ok(new Array(DIMS).fill(0))),
187
- embedBatch: vi.fn(async (texts) => {
188
- capturedTexts = texts;
189
- const vecs = texts.map(() => new Array(DIMS).fill(0));
190
- return ok(vecs);
191
- }),
192
- };
193
- const indexer = createBatchIndexer(db, capturingPort);
194
- // Insert a memory with content exceeding 6144 chars (1536 tokens * 4 chars/token)
195
- const oversizedContent = "x".repeat(50_000);
196
- insertMemory(db, "m1", oversizedContent);
197
- await indexer.indexUnembedded();
198
- // The text passed to embedBatch should be truncated to 6144 chars
199
- expect(capturedTexts.length).toBe(1);
200
- expect(capturedTexts[0].length).toBe(6_144);
201
- });
202
- });