akanjs 3.0.0-beta.18 → 3.0.0-beta.19

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 (254) hide show
  1. package/base/baseEnv.ts +12 -3
  2. package/base/databaseModes.ts +76 -0
  3. package/base/index.ts +1 -0
  4. package/base/primitiveRegistry.ts +27 -7
  5. package/common/CodeTranscript.ts +13 -2
  6. package/common/codeAgentWire.ts +17 -3
  7. package/constant/getDefault.ts +21 -2
  8. package/constant/mask.ts +35 -3
  9. package/dictionary/agent.dictionary.ts +9 -0
  10. package/dictionary/base.dictionary.ts +5 -0
  11. package/document/database.ts +39 -3
  12. package/document/queryEvaluator.ts +10 -1
  13. package/index.ts +10 -1
  14. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0001.log +44 -0
  15. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0002.log +42 -0
  16. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0003.log +43 -0
  17. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0004.log +44 -0
  18. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0005.log +50 -0
  19. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0006.log +46 -0
  20. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0007.log +46 -0
  21. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0008.log +47 -0
  22. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0009.log +47 -0
  23. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0010.log +6 -0
  24. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0011.log +14 -0
  25. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0012.log +6 -0
  26. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0013.log +35 -0
  27. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0014.log +46 -0
  28. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0015.log +46 -0
  29. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0016.log +47 -0
  30. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0017.log +47 -0
  31. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0018.log +46 -0
  32. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0019.log +46 -0
  33. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0020.log +47 -0
  34. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0021.log +47 -0
  35. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0022.log +46 -0
  36. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0023.log +46 -0
  37. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0024.log +46 -0
  38. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0025.log +46 -0
  39. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0026.log +46 -0
  40. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0027.log +46 -0
  41. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0028.log +46 -0
  42. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0029.log +46 -0
  43. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0030.log +46 -0
  44. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0031.log +46 -0
  45. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0032.log +46 -0
  46. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0033.log +46 -0
  47. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0034.log +46 -0
  48. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0035.log +46 -0
  49. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0036.log +46 -0
  50. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0037.log +46 -0
  51. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0038.log +46 -0
  52. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0039.log +46 -0
  53. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0040.log +46 -0
  54. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0041.log +46 -0
  55. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0042.log +46 -0
  56. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0043.log +46 -0
  57. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0044.log +46 -0
  58. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0045.log +46 -0
  59. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0046.log +46 -0
  60. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0047.log +46 -0
  61. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0048.log +46 -0
  62. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0049.log +46 -0
  63. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0050.log +46 -0
  64. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0051.log +46 -0
  65. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0052.log +46 -0
  66. package/local/apps/crossTest/runtime/logs/crossTest-testing-local-2026-09-25-all-0053.log +46 -0
  67. package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
  68. package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
  69. package/package.json +2 -1
  70. package/server/akanApp.ts +28 -1
  71. package/server/akanOption.ts +22 -1
  72. package/server/akanServer.ts +36 -4
  73. package/server/artifact/builderRpc.ts +7 -2
  74. package/server/artifact/ipcTypes.ts +1 -0
  75. package/server/artifact/routeClientCache.ts +5 -1
  76. package/server/di/diLifecycle.ts +31 -3
  77. package/server/di/predefinedAdaptor.ts +13 -3
  78. package/server/hmr/devHmrController.ts +8 -1
  79. package/server/mcp/McpDispatcher.ts +7 -5
  80. package/server/mcp/McpRateLimiter.ts +67 -21
  81. package/server/mcp/McpRouter.ts +14 -8
  82. package/server/mcp/PagePromptComposer.ts +6 -2
  83. package/server/ops/ageEncryption.ts +322 -0
  84. package/server/ops/appInfo.ts +92 -0
  85. package/server/ops/opsCommand.ts +120 -0
  86. package/server/ops/opsRoute.ts +155 -0
  87. package/server/ops/opsToken.ts +97 -0
  88. package/server/ops/snapshotJobs.ts +137 -0
  89. package/server/ops/snapshotRestore.ts +127 -0
  90. package/server/ops/snapshotTypes.ts +54 -0
  91. package/server/ops/sqliteFiles.ts +43 -0
  92. package/server/ops/sqliteSnapshot.ts +153 -0
  93. package/server/resolver/signal.resolver.ts +49 -10
  94. package/server/routing/soloAppRoutes.ts +5 -0
  95. package/server/rscWorkerHost.ts +9 -1
  96. package/server/webRouter.ts +11 -3
  97. package/service/agent.service.ts +8 -1
  98. package/service/injectInfo.ts +31 -13
  99. package/service/ipcTypes.ts +3 -0
  100. package/service/predefinedAdaptor/anthropicLlm.ts +36 -10
  101. package/service/predefinedAdaptor/cache.adaptor.ts +246 -94
  102. package/service/predefinedAdaptor/database.adaptor.ts +357 -74
  103. package/service/predefinedAdaptor/documentTransfer.ts +91 -0
  104. package/service/predefinedAdaptor/index.ts +2 -0
  105. package/service/predefinedAdaptor/insightQuery.ts +113 -43
  106. package/service/predefinedAdaptor/llm.adaptor.ts +33 -0
  107. package/service/predefinedAdaptor/llmOverflow.ts +73 -0
  108. package/service/predefinedAdaptor/openaiDialect.ts +23 -2
  109. package/service/predefinedAdaptor/openaiLlm.ts +11 -17
  110. package/service/predefinedAdaptor/queue.adaptor.ts +40 -21
  111. package/service/predefinedAdaptor/schedule.adaptor.ts +69 -8
  112. package/service/predefinedAdaptor/searchIndex.ts +63 -288
  113. package/service/predefinedAdaptor/solidCache.adaptor.ts +135 -12
  114. package/service/predefinedAdaptor/solidPubsub.adaptor.ts +27 -12
  115. package/service/predefinedAdaptor/solidQueue.adaptor.ts +66 -10
  116. package/service/predefinedAdaptor/solidSqlite.ts +8 -2
  117. package/service/predefinedAdaptor/sql/PostgresInsightSession.ts +116 -0
  118. package/service/predefinedAdaptor/sql/QueryCompiler.ts +47 -19
  119. package/service/predefinedAdaptor/sql/SqlDocumentStore.ts +256 -60
  120. package/service/predefinedAdaptor/sql/SqliteInsightSession.ts +89 -0
  121. package/service/predefinedAdaptor/sql/dialect/postgres.ts +139 -51
  122. package/service/predefinedAdaptor/sql/dialect/sqlite.ts +17 -13
  123. package/service/predefinedAdaptor/sql/driver/bunSqlite.ts +29 -4
  124. package/service/predefinedAdaptor/sql/driver/libsql.ts +26 -12
  125. package/service/predefinedAdaptor/sql/driver/postgres.ts +13 -7
  126. package/service/predefinedAdaptor/sql/search/fts5.ts +260 -0
  127. package/service/predefinedAdaptor/sql/search/mirror.ts +76 -0
  128. package/service/predefinedAdaptor/sql/search/postgres.ts +455 -0
  129. package/service/predefinedAdaptor/sql/search/types.ts +54 -0
  130. package/service/predefinedAdaptor/sql/types.ts +79 -16
  131. package/service/predefinedAdaptor/sql/values.ts +14 -1
  132. package/service/predefinedAdaptor/storage.adaptor.ts +16 -0
  133. package/service/predefinedAdaptor/websocket.adaptor.ts +157 -168
  134. package/signal/agent.signal.ts +8 -4
  135. package/signal/agentMeter.ts +49 -0
  136. package/signal/agentTurnStream.ts +18 -7
  137. package/signal/index.ts +1 -0
  138. package/signal/internal.ts +2 -2
  139. package/signal/internalArg.ts +7 -0
  140. package/signal/mcp/McpDocument.ts +1 -1
  141. package/signal/schema/JsonSchemaBuilder.ts +27 -4
  142. package/signal/signalContext.ts +13 -2
  143. package/signal/types.ts +6 -0
  144. package/store/agent/index.ts +1 -1
  145. package/store/agentic/AgentValue.ts +9 -6
  146. package/store/agentic/formFields.ts +3 -0
  147. package/test/conformance.ts +313 -0
  148. package/test/index.ts +1 -0
  149. package/test/sampleOf.ts +19 -2
  150. package/test/signalTestRuntime.ts +2 -2
  151. package/test/testServer.ts +64 -12
  152. package/types/base/baseEnv.d.ts +2 -2
  153. package/types/base/databaseModes.d.ts +29 -0
  154. package/types/base/index.d.ts +1 -0
  155. package/types/base/primitiveRegistry.d.ts +21 -4
  156. package/types/common/codeAgentWire.d.ts +11 -1
  157. package/types/constant/getDefault.d.ts +10 -1
  158. package/types/constant/mask.d.ts +10 -1
  159. package/types/dictionary/agent.dictionary.d.ts +1 -1
  160. package/types/dictionary/base.dictionary.d.ts +1 -1
  161. package/types/dictionary/dictionary.d.ts +9 -9
  162. package/types/document/database.d.ts +15 -3
  163. package/types/index.d.ts +9 -1
  164. package/types/server/akanOption.d.ts +10 -1
  165. package/types/server/artifact/builderRpc.d.ts +2 -1
  166. package/types/server/artifact/ipcTypes.d.ts +1 -0
  167. package/types/server/di/predefinedAdaptor.d.ts +5 -0
  168. package/types/server/mcp/McpRateLimiter.d.ts +15 -5
  169. package/types/server/mcp/McpRouter.d.ts +1 -1
  170. package/types/server/ops/ageEncryption.d.ts +24 -0
  171. package/types/server/ops/appInfo.d.ts +36 -0
  172. package/types/server/ops/opsCommand.d.ts +9 -0
  173. package/types/server/ops/opsRoute.d.ts +28 -0
  174. package/types/server/ops/opsToken.d.ts +30 -0
  175. package/types/server/ops/snapshotJobs.d.ts +25 -0
  176. package/types/server/ops/snapshotRestore.d.ts +24 -0
  177. package/types/server/ops/snapshotTypes.d.ts +46 -0
  178. package/types/server/ops/sqliteFiles.d.ts +10 -0
  179. package/types/server/ops/sqliteSnapshot.d.ts +31 -0
  180. package/types/server/resolver/signal.resolver.d.ts +5 -0
  181. package/types/server/routing/soloAppRoutes.d.ts +2 -1
  182. package/types/server/rscWorkerHost.d.ts +3 -1
  183. package/types/service/agent.service.d.ts +3 -0
  184. package/types/service/injectInfo.d.ts +9 -0
  185. package/types/service/ipcTypes.d.ts +6 -0
  186. package/types/service/predefinedAdaptor/anthropicLlm.d.ts +10 -1
  187. package/types/service/predefinedAdaptor/cache.adaptor.d.ts +45 -12
  188. package/types/service/predefinedAdaptor/database.adaptor.d.ts +20 -3
  189. package/types/service/predefinedAdaptor/documentTransfer.d.ts +17 -0
  190. package/types/service/predefinedAdaptor/index.d.ts +2 -0
  191. package/types/service/predefinedAdaptor/insightQuery.d.ts +14 -12
  192. package/types/service/predefinedAdaptor/llm.adaptor.d.ts +31 -0
  193. package/types/service/predefinedAdaptor/llmOverflow.d.ts +26 -0
  194. package/types/service/predefinedAdaptor/openaiDialect.d.ts +14 -1
  195. package/types/service/predefinedAdaptor/openaiLlm.d.ts +3 -1
  196. package/types/service/predefinedAdaptor/queue.adaptor.d.ts +12 -7
  197. package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +7 -2
  198. package/types/service/predefinedAdaptor/searchIndex.d.ts +12 -25
  199. package/types/service/predefinedAdaptor/solidCache.adaptor.d.ts +15 -6
  200. package/types/service/predefinedAdaptor/solidPubsub.adaptor.d.ts +6 -4
  201. package/types/service/predefinedAdaptor/solidSqlite.d.ts +1 -0
  202. package/types/service/predefinedAdaptor/sql/PostgresInsightSession.d.ts +23 -0
  203. package/types/service/predefinedAdaptor/sql/QueryCompiler.d.ts +7 -3
  204. package/types/service/predefinedAdaptor/sql/SqlDocumentStore.d.ts +11 -2
  205. package/types/service/predefinedAdaptor/sql/SqliteInsightSession.d.ts +19 -0
  206. package/types/service/predefinedAdaptor/sql/dialect/postgres.d.ts +20 -10
  207. package/types/service/predefinedAdaptor/sql/dialect/sqlite.d.ts +5 -2
  208. package/types/service/predefinedAdaptor/sql/driver/bunSqlite.d.ts +9 -3
  209. package/types/service/predefinedAdaptor/sql/driver/libsql.d.ts +9 -5
  210. package/types/service/predefinedAdaptor/sql/driver/postgres.d.ts +4 -4
  211. package/types/service/predefinedAdaptor/sql/search/fts5.d.ts +33 -0
  212. package/types/service/predefinedAdaptor/sql/search/mirror.d.ts +20 -0
  213. package/types/service/predefinedAdaptor/sql/search/postgres.d.ts +54 -0
  214. package/types/service/predefinedAdaptor/sql/search/types.d.ts +49 -0
  215. package/types/service/predefinedAdaptor/sql/types.d.ts +73 -15
  216. package/types/service/predefinedAdaptor/sql/values.d.ts +3 -0
  217. package/types/service/predefinedAdaptor/storage.adaptor.d.ts +6 -0
  218. package/types/service/predefinedAdaptor/websocket.adaptor.d.ts +29 -13
  219. package/types/signal/agent.signal.d.ts +4 -1
  220. package/types/signal/agentMeter.d.ts +28 -0
  221. package/types/signal/agentTurnStream.d.ts +6 -1
  222. package/types/signal/index.d.ts +1 -0
  223. package/types/signal/internalArg.d.ts +4 -0
  224. package/types/signal/schema/JsonSchemaBuilder.d.ts +11 -2
  225. package/types/signal/types.d.ts +6 -0
  226. package/types/store/agent/index.d.ts +1 -1
  227. package/types/store/agentic/AgentValue.d.ts +3 -3
  228. package/types/test/conformance.d.ts +87 -0
  229. package/types/test/index.d.ts +1 -0
  230. package/types/test/sampleOf.d.ts +1 -1
  231. package/types/test/signalTestRuntime.d.ts +1 -1
  232. package/types/test/testServer.d.ts +4 -3
  233. package/types/ui/Agent/Chat.d.ts +4 -2
  234. package/types/vendor/use-agentic/AgentProgress.d.ts +12 -0
  235. package/types/vendor/use-agentic/AgentSession.d.ts +11 -1
  236. package/types/vendor/use-agentic/Compaction.d.ts +42 -5
  237. package/types/vendor/use-agentic/Transcript.d.ts +2 -0
  238. package/types/vendor/use-agentic/types.d.ts +29 -0
  239. package/ui/Agent/Bubble.tsx +47 -1
  240. package/ui/Agent/Chat.tsx +15 -6
  241. package/ui/Agent/fetchRunner.ts +2 -1
  242. package/ui/CsrImage.tsx +6 -3
  243. package/ui/Image.tsx +8 -10
  244. package/ui/Portal.tsx +2 -3
  245. package/ui/Refresh.tsx +1 -3
  246. package/ui/ScreenNavigator.tsx +6 -4
  247. package/ui/System/SSR.tsx +8 -5
  248. package/vendor/use-agentic/AgentProgress.ts +13 -1
  249. package/vendor/use-agentic/AgentSession.ts +119 -27
  250. package/vendor/use-agentic/Compaction.ts +82 -8
  251. package/vendor/use-agentic/Transcript.ts +6 -1
  252. package/vendor/use-agentic/WIRE.md +16 -2
  253. package/vendor/use-agentic/httpRunner.ts +19 -4
  254. package/vendor/use-agentic/types.ts +33 -2
package/base/baseEnv.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { DatabaseModes } from "./databaseModes";
2
+
1
3
  type ProcessEnvLike = { env?: Record<string, string | undefined> };
2
4
 
3
5
  const globalWithProcess = globalThis as unknown as { process?: ProcessEnvLike };
@@ -19,8 +21,6 @@ export type BackendEnv = {
19
21
  hostname?: string | null;
20
22
  port?: number;
21
23
  database?: {
22
- mode?: DatabaseMode;
23
- driver?: "sqlite" | "libsql" | "postgres";
24
24
  sqlite?: {
25
25
  filePath?: string;
26
26
  journalMode?: string;
@@ -41,6 +41,7 @@ export type BackendEnv = {
41
41
  database?: string;
42
42
  user?: string;
43
43
  password?: string;
44
+ insightUrl?: string;
44
45
  };
45
46
  };
46
47
  solid?: {
@@ -51,6 +52,7 @@ export type BackendEnv = {
51
52
  cleanupIntervalMs?: number;
52
53
  queuePollIntervalMs?: number;
53
54
  queueLeaseMs?: number;
55
+ queueFailedRetentionMs?: number;
54
56
  };
55
57
  onCleanup?: () => Promise<void>;
56
58
  };
@@ -133,7 +135,14 @@ export const getEnv = (): ClientEnv => {
133
135
  appName,
134
136
  environment,
135
137
  operationMode,
136
- databaseMode: process.env.AKAN_DATABASE_MODE as DatabaseMode | undefined,
138
+ databaseMode:
139
+ typeof window === "undefined"
140
+ ? DatabaseModes.settle({
141
+ requested: process.env.AKAN_DATABASE_MODE,
142
+ declared: process.env.AKAN_DATABASE_MODES,
143
+ local: environment === "local" || operationMode === "local",
144
+ })
145
+ : undefined,
137
146
  } as const;
138
147
  const side = typeof window === "undefined" ? "server" : "client";
139
148
  const renderMode = (process.env.AKAN_PUBLIC_RENDER_ENV ?? "csr") as ClientEnv["renderMode"];
@@ -0,0 +1,76 @@
1
+ import type { DatabaseMode } from "./baseEnv";
2
+
3
+ export interface DatabaseModeRequest {
4
+ /** `AKAN_DATABASE_MODE`: the mode a deployment names. */
5
+ requested: string | undefined;
6
+ /** `AKAN_DATABASE_MODES`: what the build carries drivers for, first one the default. Unset allows any. */
7
+ declared: string | undefined;
8
+ /** A developer machine, which may leave the mode unnamed when the build carries several. */
9
+ local: boolean;
10
+ }
11
+
12
+ /** The database modes, what each runs on, and how a process settles on one. The CLI and the server share it. */
13
+ export class DatabaseModes {
14
+ static readonly all = ["single", "multiple", "cluster"] as const satisfies readonly DatabaseMode[];
15
+ /** Packages a mode imports at runtime. A build carries them for every mode the app declares. */
16
+ static readonly drivers: { [mode in DatabaseMode]: readonly string[] } = {
17
+ single: [],
18
+ multiple: ["bullmq", "ioredis"],
19
+ cluster: ["bullmq", "ioredis", "postgres"],
20
+ };
21
+ static readonly #stores: { [mode in DatabaseMode]: string } = {
22
+ single: "sqlite · solid",
23
+ multiple: "sqlite · redis",
24
+ cluster: "postgres · redis",
25
+ };
26
+
27
+ static describe(mode: DatabaseMode) {
28
+ return `${mode} (${DatabaseModes.#stores[mode]})`;
29
+ }
30
+
31
+ static parse(value: string, source: string): DatabaseMode {
32
+ const mode = value.trim();
33
+ if ((DatabaseModes.all as readonly string[]).includes(mode)) return mode as DatabaseMode;
34
+ throw new Error(`${source} must be one of ${DatabaseModes.all.join(", ")}, not "${value}"`);
35
+ }
36
+
37
+ static parseList(value: string, source: string): DatabaseMode[] {
38
+ const modes = value
39
+ .split(",")
40
+ .filter((mode) => mode.trim())
41
+ .map((mode) => DatabaseModes.parse(mode, source));
42
+ if (!modes.length) throw new Error(`${source} names no database mode`);
43
+ return [...new Set(modes)];
44
+ }
45
+
46
+ /**
47
+ * The mode this process runs in, or the reason it cannot pick one. A deployment that names no mode when the build
48
+ * carries several fails rather than falling back: the fallback would be a SQLite file inside each container, which a
49
+ * cluster deployment would find out about only once its instances disagreed.
50
+ */
51
+ static resolve({ requested, declared, local }: DatabaseModeRequest): DatabaseMode {
52
+ const modes = declared?.trim() ? DatabaseModes.parseList(declared, "AKAN_DATABASE_MODES") : null;
53
+ if (requested?.trim()) {
54
+ const mode = DatabaseModes.parse(requested, "AKAN_DATABASE_MODE");
55
+ if (modes && !modes.includes(mode))
56
+ throw new Error(
57
+ `AKAN_DATABASE_MODE is ${mode}, but this build carries only ${modes.join(", ")}. Add "${mode}" to database.modes in akan.config.ts and rebuild.`,
58
+ );
59
+ return mode;
60
+ }
61
+ if (!modes) return "single";
62
+ if (modes.length === 1 || local) return modes[0] as DatabaseMode;
63
+ throw new Error(
64
+ `This build runs in ${modes.join(" or ")} mode, and AKAN_DATABASE_MODE names neither. Set it to say which this deployment is.`,
65
+ );
66
+ }
67
+
68
+ /** `resolve` for readers that cannot fail a boot; the boot itself resolves again and reports the reason. */
69
+ static settle(request: DatabaseModeRequest): DatabaseMode | undefined {
70
+ try {
71
+ return DatabaseModes.resolve(request);
72
+ } catch {
73
+ return undefined;
74
+ }
75
+ }
76
+ }
package/base/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./base";
2
2
  export * from "./baseEnv";
3
+ export * from "./databaseModes";
3
4
  export * from "./primitiveRegistry";
4
5
  export * from "./symbols";
5
6
  export * from "./types";
@@ -11,12 +11,8 @@ export const dayjs = dayjsLib;
11
11
  export class PrimitiveRegistry {
12
12
  static readonly #namePrimitiveMap = new Map<string, typeof PrimitiveScalar>();
13
13
  static readonly #primitiveNameMap = new Map<typeof PrimitiveScalar, string>();
14
- static register(scalar: typeof PrimitiveScalar, { overwrite = false } = {}) {
15
- if (
16
- !overwrite &&
17
- (PrimitiveRegistry.#namePrimitiveMap.has(scalar.refName) || PrimitiveRegistry.#primitiveNameMap.has(scalar))
18
- )
19
- throw new Error(`Scalar ${scalar.refName} already registered`);
14
+
15
+ static register(scalar: typeof PrimitiveScalar) {
20
16
  PrimitiveRegistry.#namePrimitiveMap.set(scalar.refName, scalar);
21
17
  PrimitiveRegistry.#primitiveNameMap.set(scalar, scalar.refName);
22
18
  }
@@ -42,9 +38,29 @@ export class PrimitiveRegistry {
42
38
  static getAll(): (typeof PrimitiveScalar)[] {
43
39
  return [...PrimitiveRegistry.#namePrimitiveMap.values()];
44
40
  }
41
+ /** The agent face `modelRef` declares, or null for anything that is not a registered primitive declaring one. */
42
+ static agentOf(modelRef: unknown): PrimitiveAgentFace | null {
43
+ if (!PrimitiveRegistry.#primitiveNameMap.has(modelRef as typeof PrimitiveScalar)) return null;
44
+ return (modelRef as typeof PrimitiveScalar).agent ?? null;
45
+ }
46
+ }
47
+
48
+ export interface PrimitiveJsonSchema {
49
+ [key: string]: unknown;
50
+ }
51
+
52
+ /**
53
+ * How an agent — an MCP client or the in-page one — sees a primitive whose stored shape is not the one a model
54
+ * should read or write: `schema` is what it is published as on both sides of a call, and `read` turns a stored or
55
+ * wire value into that shape. There is no `write`, because every argument and every input field already runs
56
+ * through `parseValue`; a primitive that accepts the agent's shape there has taken the write.
57
+ */
58
+ export interface PrimitiveAgentFace<Value = unknown> {
59
+ schema: PrimitiveJsonSchema;
60
+ read(value: Value): unknown;
45
61
  }
46
62
 
47
- export type PrimitiveValue = string | number | boolean | Dayjs | Date | Uint8Array | null | undefined;
63
+ export type PrimitiveValue = string | number | boolean | Dayjs | Date | Uint8Array | object | null | undefined;
48
64
  export class PrimitiveScalar {
49
65
  static refName: string;
50
66
  static [SERVER_VALUE]: unknown;
@@ -52,6 +68,10 @@ export class PrimitiveScalar {
52
68
  static [DEFAULT_VALUE]: unknown = null;
53
69
  static [PURIFIED_VALUE]: unknown = null;
54
70
  static [EXAMPLE_VALUE]: unknown = null;
71
+ /** The wire shape, for a primitive the built-in schema table cannot know. Absent, it is published as a string. */
72
+ static jsonSchema?: PrimitiveJsonSchema;
73
+ /** Absent, an agent sees the wire shape. See `PrimitiveAgentFace`. */
74
+ static agent?: PrimitiveAgentFace;
55
75
 
56
76
  static validate(value: PrimitiveValue): boolean {
57
77
  return true;
@@ -179,6 +179,13 @@ export class CodeTranscript {
179
179
  case "question":
180
180
  this.#question = event.question;
181
181
  return this.#push({ kind: "question", id: event.question.questionId, question: event.question });
182
+ case "question_skipped":
183
+ return this.#push({
184
+ kind: "question",
185
+ id: event.question.questionId,
186
+ question: event.question,
187
+ rendered: `(${event.reason})`,
188
+ });
182
189
  case "question_resolved":
183
190
  if (this.#question?.questionId === event.questionId) this.#question = undefined;
184
191
  return this.#patch(event.questionId, (part) => {
@@ -197,8 +204,12 @@ export class CodeTranscript {
197
204
  return;
198
205
  case "compaction":
199
206
  this.#compacting = event.phase === "start";
200
- if (event.phase === "end") this.#notice("info", `Compacted the conversation (${event.reason}).`);
201
- return;
207
+ if (event.phase === "start") return;
208
+
209
+ if ((event.error || event.aborted) && event.reason === "manual") return;
210
+ if (event.error) return this.#notice("warning", event.error);
211
+ if (event.aborted) return this.#notice("info", "Compaction cancelled.");
212
+ return this.#notice("info", `Compacted the conversation (${event.reason}).`);
202
213
  case "retry":
203
214
  return this.#notice(
204
215
  "warning",
@@ -190,10 +190,19 @@ export type CodeAgentEventBody =
190
190
  }
191
191
  | { type: "question"; question: CodeAgentQuestion }
192
192
  | { type: "question_resolved"; questionId: string; answer: CodeAgentAnswer; rendered: string }
193
+ /** A question nobody could be asked — no host attached — answered with nothing; the model continued on its own. */
194
+ | { type: "question_skipped"; question: CodeAgentQuestion; reason: "no-host" }
193
195
  | { type: "approval"; request: CodeAgentApprovalRequest }
194
196
  | { type: "approval_resolved"; approvalId: string; approved: boolean }
195
197
  | { type: "context"; used: number; max: number | undefined }
196
- | { type: "compaction"; phase: "start" | "end"; reason: "manual" | "threshold" | "overflow" }
198
+ /** An `end` carrying neither `error` nor `aborted` is the only one that compacted anything. */
199
+ | {
200
+ type: "compaction";
201
+ phase: "start" | "end";
202
+ reason: "manual" | "threshold" | "overflow";
203
+ error?: string;
204
+ aborted?: boolean;
205
+ }
197
206
  | { type: "retry"; attempt: number; maxAttempts: number; delayMs: number; message: string }
198
207
  | { type: "queue"; steering: string[]; followUp: string[] }
199
208
  | { type: "notice"; level: "info" | "warning" | "error"; message: string }
@@ -255,6 +264,7 @@ export const codeAgentEventPersistence: { [key in CodeAgentEventType]: "live" |
255
264
  tool_end: "persist",
256
265
  question: "persist",
257
266
  question_resolved: "persist",
267
+ question_skipped: "persist",
258
268
  approval: "live",
259
269
  approval_resolved: "live",
260
270
  context: "live",
@@ -393,14 +403,18 @@ export const codeAgentEventLabel = (event: CodeAgentEventBody): string => {
393
403
  return `? ${event.question.prompt}`;
394
404
  case "question_resolved":
395
405
  return `= ${event.rendered}`;
406
+ case "question_skipped":
407
+ return `? ${event.question.prompt} (skipped: ${event.reason})`;
396
408
  case "approval":
397
409
  return `approve? ${event.request.summary}`;
398
410
  case "approval_resolved":
399
411
  return event.approved ? "approved" : "denied";
400
412
  case "context":
401
413
  return `context ${event.used}${event.max ? `/${event.max}` : ""}`;
402
- case "compaction":
403
- return `compaction ${event.phase} (${event.reason})`;
414
+ case "compaction": {
415
+ const outcome = event.error ? ` — ${event.error}` : event.aborted ? " — cancelled" : "";
416
+ return `compaction ${event.phase} (${event.reason})${outcome}`;
417
+ }
404
418
  case "retry":
405
419
  return `retry ${event.attempt}/${event.maxAttempts} in ${event.delayMs}ms — ${event.message}`;
406
420
  case "queue":
@@ -5,7 +5,10 @@ import type { DefaultOf } from "./types";
5
5
  export interface DefaultPlan {
6
6
  /** Fields whose default is a value that can be shared: a primitive, `null`, or the field's own literal. */
7
7
  shared: Record<string, unknown>;
8
- /** Fields that have to be produced per call — a thunk, a fresh array, or a nested scalar record. */
8
+ /**
9
+ * Fields that have to be produced per call — a thunk, a fresh array, a nested scalar record, or a primitive's
10
+ * structured default.
11
+ */
9
12
  perCall: Map<string, () => unknown>;
10
13
  }
11
14
 
@@ -49,7 +52,23 @@ const buildPlan = (fieldObj: FieldObject): DefaultPlan => {
49
52
  else if (field.isClass) {
50
53
  if (field.isScalar) perCall.set(key, () => getDefault(field.modelRef[FIELD_META]));
51
54
  else shared[key] = null;
52
- } else shared[key] = (field.modelRef as unknown as typeof PrimitiveScalar)[DEFAULT_VALUE];
55
+ } else {
56
+ const primitiveDefault = (field.modelRef as unknown as typeof PrimitiveScalar)[DEFAULT_VALUE];
57
+ if (isStructured(primitiveDefault)) perCall.set(key, () => structuredClone(primitiveDefault));
58
+ else shared[key] = primitiveDefault;
59
+ }
53
60
  }
54
61
  return { shared, perCall };
55
62
  };
63
+
64
+ const isStructured = (value: unknown): value is object =>
65
+ typeof value === "object" &&
66
+ value !== null &&
67
+ (Array.isArray(value) || Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
68
+
69
+ /**
70
+ * A primitive's value is never an identity, so a plain object or array — an empty editor document as a primitive's
71
+ * `DEFAULT_VALUE` — is copied for each use, for the reason an array field default is. An instance (a `Dayjs`, a
72
+ * `Uint8Array`) is handed back as is: its own API is how it changes, and a structured copy would drop its prototype.
73
+ */
74
+ export const freshPrimitiveValue = <T>(value: T): T => (isStructured(value) ? structuredClone(value) : value);
package/constant/mask.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FIELD_META } from "akanjs/base";
1
+ import { type Cls, FIELD_META, getNonArrayModel, type PrimitiveAgentFace, PrimitiveRegistry } from "akanjs/base";
2
2
 
3
3
  /**
4
4
  * A model as masking reads it — the constructor, for the field metadata it carries at runtime.
@@ -14,7 +14,10 @@ export interface MaskModel {
14
14
  interface MaskField {
15
15
  fieldType?: string;
16
16
  isClass?: boolean;
17
+ isMap?: boolean;
17
18
  modelRef?: MaskModel;
19
+ of?: unknown;
20
+ arrDepth?: number;
18
21
  visual?: boolean;
19
22
  }
20
23
 
@@ -40,7 +43,8 @@ export const leakingFieldsOf = (model: MaskModel, value: Record<string, unknown>
40
43
  /**
41
44
  * Strips what a model marks `hidden`, `secret`, or `visual`, by the model the caller names rather than by the one
42
45
  * the value happens to still carry. The first two are secrecy and the third is cost, but the answer is the same
43
- * one — leave the field out — and this is the only place every AI-facing read already passes through.
46
+ * one — leave the field out — and this is the only place every AI-facing read already passes through. For the same
47
+ * reason it is where a primitive declaring an agent face is read into that face (`agentRead`).
44
48
  *
45
49
  * That distinction is the whole point. A check that reads the class off the value can only mask what arrives as an
46
50
  * instance, so a `{ ...doc }` spread, a `toJSON()`, an `immerify()`, or a round-trip through `JSON.stringify` reaches
@@ -61,11 +65,39 @@ export const mask = (model: MaskModel, value: unknown): unknown => {
61
65
  const masked: Record<string, unknown> = {};
62
66
  for (const [key, field] of Object.entries(fields)) {
63
67
  if (field.fieldType === "hidden" || field.fieldType === "secret" || field.visual || !(key in source)) continue;
64
- masked[key] = field.isClass && field.modelRef ? mask(field.modelRef, source[key]) : source[key];
68
+ masked[key] = maskField(field, source[key]);
65
69
  }
66
70
  return masked;
67
71
  };
68
72
 
73
+ /**
74
+ * What an agent reads of a primitive value: the primitive's `agent.read` when it declares an agent face, the value
75
+ * untouched otherwise. The read is applied through `arrDepth` levels of array, the way a field declares them.
76
+ */
77
+ export const agentRead = (modelRef: unknown, value: unknown, arrDepth = 0): unknown => {
78
+ const face = PrimitiveRegistry.agentOf(modelRef);
79
+ return face ? readThrough(face, value, arrDepth) : value;
80
+ };
81
+
82
+ const readThrough = (face: PrimitiveAgentFace, value: unknown, arrDepth: number): unknown => {
83
+ if (value === null || value === undefined) return value;
84
+ if (arrDepth > 0 && Array.isArray(value)) return value.map((item) => readThrough(face, item, arrDepth - 1));
85
+ return face.read(value);
86
+ };
87
+
88
+ const maskField = (field: MaskField, value: unknown): unknown => {
89
+ if (field.isClass && field.modelRef) return mask(field.modelRef, value);
90
+ if (field.isMap) return maskMapValues(field.of, value);
91
+ return agentRead(field.modelRef, value, field.arrDepth ?? 0);
92
+ };
93
+
94
+ const maskMapValues = (of: unknown, value: unknown): unknown => {
95
+ const [valueRef, arrDepth] = getNonArrayModel(of as Cls);
96
+ if (!PrimitiveRegistry.agentOf(valueRef) || value === null || typeof value !== "object") return value;
97
+ const entries = value instanceof Map ? [...value.entries()] : Object.entries(value);
98
+ return Object.fromEntries(entries.map(([key, item]) => [key, agentRead(valueRef, item, arrDepth)]));
99
+ };
100
+
69
101
  /**
70
102
  * Drops what a model marks `hidden` or `secret`, and nothing else.
71
103
  *
@@ -29,4 +29,13 @@ export const agentDictionary = serviceDictionary(["en", "ko"])
29
29
  "{provider} refused this turn with status {status}. Reason: {reason}",
30
30
  "{provider}가 이번 턴을 거절했습니다 (status {status}). 사유: {reason}",
31
31
  ],
32
+
33
+ contextOverflow: [
34
+ "This conversation no longer fits the model's context window at {provider}. Use /compact to summarize it, or /new to start over",
35
+ "대화가 {provider} 모델의 컨텍스트 창을 넘었습니다. /compact로 요약하거나 /new로 새로 시작할 수 있습니다.",
36
+ ],
37
+ quotaExceeded: [
38
+ "The agent's usage limit for this account has been reached",
39
+ "이 계정의 에이전트 사용 한도에 도달했습니다.",
40
+ ],
32
41
  });
@@ -109,6 +109,11 @@ export const baseDictionary = serviceDictionary(["en", "ko"])
109
109
  agentToolRunning: ["Running", "실행 중"],
110
110
  agentToolResult: ["Show what this tool returned", "이 툴이 반환한 값 보기"],
111
111
  agentTokens: ["~{count} tokens", "약 {count} 토큰"],
112
+ agentTokensOf: ["~{count} / {limit} tokens", "약 {count} / {limit} 토큰"],
113
+ agentCompactsAt: [
114
+ "The conversation summarizes itself past {limit} tokens",
115
+ "{limit} 토큰을 넘으면 대화를 스스로 요약합니다",
116
+ ],
112
117
  agentSummarizing: ["Summarizing the conversation…", "대화를 요약하는 중…"],
113
118
  agentContinue: ["This is taking a while. Keep going?", "시간이 걸리고 있습니다. 계속할까요?"],
114
119
  agentKeepGoing: ["Keep going", "계속하기"],
@@ -1,7 +1,7 @@
1
1
  import type { MergedValues, PromiseOrObject } from "akanjs/base";
2
2
  import { Logger } from "akanjs/common";
3
3
  import type { DocumentModel, QueryOf } from "akanjs/constant";
4
- import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
4
+ import type { CacheAdaptor, CacheSetOptions, CacheValue } from "akanjs/service";
5
5
  import type { DataLoader } from "./dataLoader";
6
6
  import type { DocumentUpdateInput } from "./documentQuery";
7
7
  import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta";
@@ -16,15 +16,51 @@ export class CacheDatabase<T = unknown> {
16
16
  ) {
17
17
  this.logger = new Logger(`${refName}Cache`);
18
18
  }
19
- async set(topic: string, key: string, value: string | number | Buffer, option: CacheSetOptions = {}) {
19
+ async set(topic: string, key: string, value: CacheValue, option: CacheSetOptions = {}) {
20
20
  await this.cache.set(this.refName, `${topic}:${key}`, value, option);
21
21
  }
22
- async get<T extends string | number | Buffer>(topic: string, key: string): Promise<T | undefined> {
22
+ async get<T extends CacheValue = CacheValue>(topic: string, key: string): Promise<T | undefined> {
23
23
  return await this.cache.get<T>(this.refName, `${topic}:${key}`);
24
24
  }
25
25
  async delete(topic: string, key: string) {
26
26
  await this.cache.delete(this.refName, `${topic}:${key}`);
27
27
  }
28
+ async getDel<T extends CacheValue = CacheValue>(topic: string, key: string): Promise<T | undefined> {
29
+ return await this.cache.getDel<T>(this.refName, `${topic}:${key}`);
30
+ }
31
+ async setIfAbsent(topic: string, key: string, value: CacheValue, option: CacheSetOptions = {}) {
32
+ return await this.cache.setIfAbsent(this.refName, `${topic}:${key}`, value, option);
33
+ }
34
+ async incr(topic: string, key: string, by = 1, option: CacheSetOptions = {}) {
35
+ return await this.cache.incr(this.refName, `${topic}:${key}`, by, option);
36
+ }
37
+ async hset(topic: string, key: string, subKey: string, value: CacheValue, option: CacheSetOptions = {}) {
38
+ await this.cache.hset(this.refName, `${topic}:${key}`, subKey, value, option);
39
+ }
40
+ async hget<T extends CacheValue = CacheValue>(topic: string, key: string, subKey: string): Promise<T | undefined> {
41
+ return await this.cache.hget<T>(this.refName, `${topic}:${key}`, subKey);
42
+ }
43
+ async hdelete(topic: string, key: string, subKey: string) {
44
+ await this.cache.hdelete(this.refName, `${topic}:${key}`, subKey);
45
+ }
46
+ async hkeys(topic: string, key: string) {
47
+ return await this.cache.hkeys(this.refName, `${topic}:${key}`);
48
+ }
49
+ async hentries<T extends CacheValue = CacheValue>(topic: string, key: string): Promise<[string, T][]> {
50
+ return await this.cache.hentries<T>(this.refName, `${topic}:${key}`);
51
+ }
52
+ async hclear(topic: string, key: string) {
53
+ await this.cache.hclear(this.refName, `${topic}:${key}`);
54
+ }
55
+ async hgetDel<T extends CacheValue = CacheValue>(topic: string, key: string, subKey: string): Promise<T | undefined> {
56
+ return await this.cache.hgetDel<T>(this.refName, `${topic}:${key}`, subKey);
57
+ }
58
+ async hsetIfAbsent(topic: string, key: string, subKey: string, value: CacheValue, option: CacheSetOptions = {}) {
59
+ return await this.cache.hsetIfAbsent(this.refName, `${topic}:${key}`, subKey, value, option);
60
+ }
61
+ async hincr(topic: string, key: string, subKey: string, by = 1, option: CacheSetOptions = {}) {
62
+ return await this.cache.hincr(this.refName, `${topic}:${key}`, subKey, by, option);
63
+ }
28
64
  }
29
65
  /**
30
66
  * What `update<Filter>` returns. The patch cannot be a trailing parameter — a filter's own args may be optional,
@@ -217,7 +217,12 @@ export class DocumentQueryEvaluator {
217
217
  return this.#has(read, operand);
218
218
  case "contains":
219
219
 
220
- return read.value !== null && String(read.value).toLowerCase().includes(String(operand).toLowerCase());
220
+ return (
221
+ read.value !== null &&
222
+ DocumentQueryEvaluator.#foldAscii(String(read.value)).includes(
223
+ DocumentQueryEvaluator.#foldAscii(String(operand)),
224
+ )
225
+ );
221
226
  }
222
227
  }
223
228
 
@@ -313,6 +318,10 @@ export class DocumentQueryEvaluator {
313
318
  return leftPoints.length === rightPoints.length ? 0 : leftPoints.length < rightPoints.length ? -1 : 1;
314
319
  }
315
320
 
321
+ static #foldAscii(text: string) {
322
+ return text.replace(/[A-Z]/g, (char) => char.toLowerCase());
323
+ }
324
+
316
325
  static #isNode(value: unknown): value is DocumentQueryNode {
317
326
  return !!value && typeof value === "object" && "kind" in value;
318
327
  }
package/index.ts CHANGED
@@ -229,9 +229,18 @@ export interface AkanApiConfig {
229
229
  websocketPrefix: string;
230
230
  }
231
231
 
232
+ export interface AkanDatabaseConfig {
233
+ /**
234
+ * The modes this app's build can run in. `akan build` bundles the drivers of each, the image lets a deployment
235
+ * pick one of them with `AKAN_DATABASE_MODE` and no other, and `akan start` runs the first unless the shell names
236
+ * another. A deployment of a build carrying several has to name one.
237
+ */
238
+ modes: DatabaseMode[];
239
+ }
240
+
232
241
  export interface AppConfigResult {
233
242
  docker: DockerConfig;
234
- defaultDatabaseMode: DatabaseMode;
243
+ database: AkanDatabaseConfig;
235
244
  /**
236
245
  * Where this app mounts its endpoints. Declared here rather than only in `main.ts` because the value is baked
237
246
  * into every client bundle: a prebuilt CSR shell or a mobile bundle never reaches the server that would tell
@@ -0,0 +1,44 @@
1
+ [crossTest] 58035 - 09/25/2026, 16:51:41 PM VERBOSE crossTest is serving on port 47811 +114ms
2
+ [crossTest] 58035 - 09/25/2026, 16:51:41 PM VERBOSE 🚀 crossTest is running on port 47811 +117ms
3
+ [scheduler] 58035 - 09/25/2026, 16:52:41 PM DEBUG Schedule interval searchIndexRetry finished 2ms +60110ms
4
+ [scheduler] 58035 - 09/25/2026, 16:53:41 PM DEBUG Schedule interval searchIndexRetry finished 1ms +120110ms
5
+ [crossTest] 58035 - 09/25/2026, 16:53:57 PM DEBUG Received SIGTERM, starting graceful shutdown... +135947ms
6
+ [crossTest] 58035 - 09/25/2026, 16:53:57 PM INFO Shutting down gracefully... +135947ms
7
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Running destroy internals... +135947ms
8
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroy internals in 1ms +135948ms
9
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroying services... +135948ms
10
+ [BaseService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE base service destroying... +135948ms
11
+ [AgentService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE agent service destroying... +135948ms
12
+ [CrossItemService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE crossItem service destroying... +135948ms
13
+ [BaseService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE base service destroyed in 0ms +135948ms
14
+ [AgentService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE agent service destroyed in 0ms +135948ms
15
+ [CrossItemService] 58035 - 09/25/2026, 16:53:57 PM VERBOSE crossItem service destroyed in 0ms +135948ms
16
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroy services in 0ms +135948ms
17
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroying adaptors... +135948ms
18
+ [crossItemModel] 58035 - 09/25/2026, 16:53:57 PM VERBOSE crossItemModel adaptor destroying... +135948ms
19
+ [crossItemModel] 58035 - 09/25/2026, 16:53:57 PM VERBOSE crossItemModel adaptor destroyed in 0ms +135948ms
20
+ [sqliteDatabase] 58035 - 09/25/2026, 16:53:57 PM VERBOSE sqliteDatabase adaptor destroying... +135948ms
21
+ [sqliteDatabase] 58035 - 09/25/2026, 16:53:57 PM VERBOSE sqliteDatabase adaptor destroyed in 5ms +135953ms
22
+ [bullQueue] 58035 - 09/25/2026, 16:53:57 PM VERBOSE bullQueue adaptor destroying... +135953ms
23
+ [scheduler] 58035 - 09/25/2026, 16:53:57 PM VERBOSE scheduler adaptor destroying... +135953ms
24
+ [wsRedis] 58035 - 09/25/2026, 16:53:57 PM VERBOSE wsRedis adaptor destroying... +135953ms
25
+ [scheduler] 58035 - 09/25/2026, 16:53:57 PM VERBOSE scheduler adaptor destroyed in 0ms +135953ms
26
+ [bullQueue] 58035 - 09/25/2026, 16:53:57 PM VERBOSE bullQueue adaptor destroyed in 0ms +135953ms
27
+ [wsRedis] 58035 - 09/25/2026, 16:53:57 PM VERBOSE WebSocket Redis adaptor destroyed +135957ms
28
+ [wsRedis] 58035 - 09/25/2026, 16:53:57 PM VERBOSE wsRedis adaptor destroyed in 4ms +135957ms
29
+ [redisCache] 58035 - 09/25/2026, 16:53:57 PM VERBOSE redisCache adaptor destroying... +135957ms
30
+ [blobStorage] 58035 - 09/25/2026, 16:53:57 PM VERBOSE blobStorage adaptor destroying... +135957ms
31
+ [consoleLogger] 58035 - 09/25/2026, 16:53:57 PM VERBOSE consoleLogger adaptor destroying... +135957ms
32
+ [jsonCompressor] 58035 - 09/25/2026, 16:53:57 PM VERBOSE jsonCompressor adaptor destroying... +135957ms
33
+ [openaiLlm] 58035 - 09/25/2026, 16:53:57 PM VERBOSE openaiLlm adaptor destroying... +135957ms
34
+ [llmAdaptorRole] 58035 - 09/25/2026, 16:53:57 PM VERBOSE llmAdaptorRole adaptor destroying... +135957ms
35
+ [redisCache] 58035 - 09/25/2026, 16:53:57 PM VERBOSE redisCache adaptor destroyed in 0ms +135957ms
36
+ [blobStorage] 58035 - 09/25/2026, 16:53:57 PM VERBOSE blobStorage adaptor destroyed in 0ms +135957ms
37
+ [consoleLogger] 58035 - 09/25/2026, 16:53:57 PM VERBOSE consoleLogger adaptor destroyed in 0ms +135957ms
38
+ [jsonCompressor] 58035 - 09/25/2026, 16:53:57 PM VERBOSE jsonCompressor adaptor destroyed in 0ms +135957ms
39
+ [openaiLlm] 58035 - 09/25/2026, 16:53:57 PM VERBOSE openaiLlm adaptor destroyed in 0ms +135957ms
40
+ [llmAdaptorRole] 58035 - 09/25/2026, 16:53:57 PM VERBOSE llmAdaptorRole adaptor destroyed in 0ms +135957ms
41
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroy adaptors in 9ms +135957ms
42
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroying uses... +135957ms
43
+ [DiLifecycle] 58035 - 09/25/2026, 16:53:57 PM VERBOSE Destroy uses in 0ms +135957ms
44
+ [crossTest] 58035 - 09/25/2026, 16:53:57 PM INFO Shutdown completed successfully in 10ms +135957ms
@@ -0,0 +1,42 @@
1
+ [crossTest] 59872 - 09/25/2026, 16:53:58 PM VERBOSE crossTest is serving on port 47811 +109ms
2
+ [crossTest] 59872 - 09/25/2026, 16:53:58 PM VERBOSE 🚀 crossTest is running on port 47811 +112ms
3
+ [crossTest] 59872 - 09/25/2026, 16:54:10 PM DEBUG Received SIGTERM, starting graceful shutdown... +11999ms
4
+ [crossTest] 59872 - 09/25/2026, 16:54:10 PM INFO Shutting down gracefully... +11999ms
5
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Running destroy internals... +12000ms
6
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroy internals in 0ms +12000ms
7
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroying services... +12000ms
8
+ [BaseService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE base service destroying... +12000ms
9
+ [AgentService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE agent service destroying... +12000ms
10
+ [CrossItemService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE crossItem service destroying... +12000ms
11
+ [BaseService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE base service destroyed in 0ms +12000ms
12
+ [AgentService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE agent service destroyed in 0ms +12000ms
13
+ [CrossItemService] 59872 - 09/25/2026, 16:54:10 PM VERBOSE crossItem service destroyed in 0ms +12000ms
14
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroy services in 0ms +12000ms
15
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroying adaptors... +12000ms
16
+ [crossItemModel] 59872 - 09/25/2026, 16:54:10 PM VERBOSE crossItemModel adaptor destroying... +12000ms
17
+ [crossItemModel] 59872 - 09/25/2026, 16:54:10 PM VERBOSE crossItemModel adaptor destroyed in 0ms +12000ms
18
+ [sqliteDatabase] 59872 - 09/25/2026, 16:54:10 PM VERBOSE sqliteDatabase adaptor destroying... +12000ms
19
+ [sqliteDatabase] 59872 - 09/25/2026, 16:54:10 PM VERBOSE sqliteDatabase adaptor destroyed in 5ms +12005ms
20
+ [bullQueue] 59872 - 09/25/2026, 16:54:10 PM VERBOSE bullQueue adaptor destroying... +12005ms
21
+ [scheduler] 59872 - 09/25/2026, 16:54:10 PM VERBOSE scheduler adaptor destroying... +12005ms
22
+ [wsRedis] 59872 - 09/25/2026, 16:54:10 PM VERBOSE wsRedis adaptor destroying... +12005ms
23
+ [scheduler] 59872 - 09/25/2026, 16:54:10 PM VERBOSE scheduler adaptor destroyed in 1ms +12006ms
24
+ [bullQueue] 59872 - 09/25/2026, 16:54:10 PM VERBOSE bullQueue adaptor destroyed in 1ms +12006ms
25
+ [wsRedis] 59872 - 09/25/2026, 16:54:10 PM VERBOSE WebSocket Redis adaptor destroyed +12010ms
26
+ [wsRedis] 59872 - 09/25/2026, 16:54:10 PM VERBOSE wsRedis adaptor destroyed in 5ms +12010ms
27
+ [redisCache] 59872 - 09/25/2026, 16:54:10 PM VERBOSE redisCache adaptor destroying... +12010ms
28
+ [blobStorage] 59872 - 09/25/2026, 16:54:10 PM VERBOSE blobStorage adaptor destroying... +12010ms
29
+ [consoleLogger] 59872 - 09/25/2026, 16:54:10 PM VERBOSE consoleLogger adaptor destroying... +12010ms
30
+ [jsonCompressor] 59872 - 09/25/2026, 16:54:10 PM VERBOSE jsonCompressor adaptor destroying... +12010ms
31
+ [openaiLlm] 59872 - 09/25/2026, 16:54:10 PM VERBOSE openaiLlm adaptor destroying... +12010ms
32
+ [llmAdaptorRole] 59872 - 09/25/2026, 16:54:10 PM VERBOSE llmAdaptorRole adaptor destroying... +12010ms
33
+ [redisCache] 59872 - 09/25/2026, 16:54:10 PM VERBOSE redisCache adaptor destroyed in 0ms +12010ms
34
+ [blobStorage] 59872 - 09/25/2026, 16:54:10 PM VERBOSE blobStorage adaptor destroyed in 0ms +12010ms
35
+ [consoleLogger] 59872 - 09/25/2026, 16:54:10 PM VERBOSE consoleLogger adaptor destroyed in 0ms +12010ms
36
+ [jsonCompressor] 59872 - 09/25/2026, 16:54:10 PM VERBOSE jsonCompressor adaptor destroyed in 0ms +12010ms
37
+ [openaiLlm] 59872 - 09/25/2026, 16:54:10 PM VERBOSE openaiLlm adaptor destroyed in 0ms +12010ms
38
+ [llmAdaptorRole] 59872 - 09/25/2026, 16:54:10 PM VERBOSE llmAdaptorRole adaptor destroyed in 0ms +12010ms
39
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroy adaptors in 10ms +12010ms
40
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroying uses... +12010ms
41
+ [DiLifecycle] 59872 - 09/25/2026, 16:54:10 PM VERBOSE Destroy uses in 0ms +12010ms
42
+ [crossTest] 59872 - 09/25/2026, 16:54:10 PM INFO Shutdown completed successfully in 11ms +12010ms
@@ -0,0 +1,43 @@
1
+ [crossTest] 60280 - 09/25/2026, 16:54:26 PM VERBOSE crossTest is serving on port 47811 +111ms
2
+ [crossTest] 60280 - 09/25/2026, 16:54:26 PM VERBOSE 🚀 crossTest is running on port 47811 +114ms
3
+ [scheduler] 60280 - 09/25/2026, 16:55:26 PM DEBUG Schedule interval searchIndexRetry finished 3ms +60108ms
4
+ [crossTest] 60280 - 09/25/2026, 16:56:12 PM DEBUG Received SIGTERM, starting graceful shutdown... +105905ms
5
+ [crossTest] 60280 - 09/25/2026, 16:56:12 PM INFO Shutting down gracefully... +105905ms
6
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Running destroy internals... +105905ms
7
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroy internals in 0ms +105905ms
8
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroying services... +105905ms
9
+ [BaseService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE base service destroying... +105906ms
10
+ [AgentService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE agent service destroying... +105906ms
11
+ [CrossItemService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE crossItem service destroying... +105906ms
12
+ [BaseService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE base service destroyed in 0ms +105906ms
13
+ [AgentService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE agent service destroyed in 0ms +105906ms
14
+ [CrossItemService] 60280 - 09/25/2026, 16:56:12 PM VERBOSE crossItem service destroyed in 0ms +105906ms
15
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroy services in 1ms +105906ms
16
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroying adaptors... +105906ms
17
+ [crossItemModel] 60280 - 09/25/2026, 16:56:12 PM VERBOSE crossItemModel adaptor destroying... +105906ms
18
+ [crossItemModel] 60280 - 09/25/2026, 16:56:12 PM VERBOSE crossItemModel adaptor destroyed in 0ms +105906ms
19
+ [sqliteDatabase] 60280 - 09/25/2026, 16:56:12 PM VERBOSE sqliteDatabase adaptor destroying... +105906ms
20
+ [sqliteDatabase] 60280 - 09/25/2026, 16:56:12 PM VERBOSE sqliteDatabase adaptor destroyed in 4ms +105910ms
21
+ [bullQueue] 60280 - 09/25/2026, 16:56:12 PM VERBOSE bullQueue adaptor destroying... +105910ms
22
+ [scheduler] 60280 - 09/25/2026, 16:56:12 PM VERBOSE scheduler adaptor destroying... +105910ms
23
+ [wsRedis] 60280 - 09/25/2026, 16:56:12 PM VERBOSE wsRedis adaptor destroying... +105910ms
24
+ [scheduler] 60280 - 09/25/2026, 16:56:12 PM VERBOSE scheduler adaptor destroyed in 1ms +105911ms
25
+ [bullQueue] 60280 - 09/25/2026, 16:56:12 PM VERBOSE bullQueue adaptor destroyed in 1ms +105911ms
26
+ [wsRedis] 60280 - 09/25/2026, 16:56:12 PM VERBOSE WebSocket Redis adaptor destroyed +105912ms
27
+ [wsRedis] 60280 - 09/25/2026, 16:56:12 PM VERBOSE wsRedis adaptor destroyed in 2ms +105912ms
28
+ [redisCache] 60280 - 09/25/2026, 16:56:12 PM VERBOSE redisCache adaptor destroying... +105912ms
29
+ [blobStorage] 60280 - 09/25/2026, 16:56:12 PM VERBOSE blobStorage adaptor destroying... +105912ms
30
+ [consoleLogger] 60280 - 09/25/2026, 16:56:12 PM VERBOSE consoleLogger adaptor destroying... +105912ms
31
+ [jsonCompressor] 60280 - 09/25/2026, 16:56:12 PM VERBOSE jsonCompressor adaptor destroying... +105912ms
32
+ [openaiLlm] 60280 - 09/25/2026, 16:56:12 PM VERBOSE openaiLlm adaptor destroying... +105912ms
33
+ [llmAdaptorRole] 60280 - 09/25/2026, 16:56:12 PM VERBOSE llmAdaptorRole adaptor destroying... +105912ms
34
+ [redisCache] 60280 - 09/25/2026, 16:56:12 PM VERBOSE redisCache adaptor destroyed in 0ms +105912ms
35
+ [blobStorage] 60280 - 09/25/2026, 16:56:12 PM VERBOSE blobStorage adaptor destroyed in 0ms +105912ms
36
+ [consoleLogger] 60280 - 09/25/2026, 16:56:12 PM VERBOSE consoleLogger adaptor destroyed in 0ms +105912ms
37
+ [jsonCompressor] 60280 - 09/25/2026, 16:56:12 PM VERBOSE jsonCompressor adaptor destroyed in 0ms +105912ms
38
+ [openaiLlm] 60280 - 09/25/2026, 16:56:12 PM VERBOSE openaiLlm adaptor destroyed in 1ms +105913ms
39
+ [llmAdaptorRole] 60280 - 09/25/2026, 16:56:12 PM VERBOSE llmAdaptorRole adaptor destroyed in 1ms +105913ms
40
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroy adaptors in 7ms +105913ms
41
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroying uses... +105913ms
42
+ [DiLifecycle] 60280 - 09/25/2026, 16:56:12 PM VERBOSE Destroy uses in 0ms +105913ms
43
+ [crossTest] 60280 - 09/25/2026, 16:56:12 PM INFO Shutdown completed successfully in 8ms +105913ms