@m6d/cortex-server 1.7.0 → 2.0.0

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 (239) hide show
  1. package/README.md +8 -3
  2. package/contracts/README.md +23 -0
  3. package/contracts/graph/embed.ts +50 -0
  4. package/{src → contracts}/graph/helpers.ts +4 -10
  5. package/{src → contracts}/graph/neo4j.ts +14 -27
  6. package/contracts/graph/schema.ts +65 -0
  7. package/{src → contracts}/graph/types.ts +2 -29
  8. package/contracts/graph.ts +36 -0
  9. package/contracts/runtime.ts +208 -0
  10. package/contracts/wire.ts +143 -0
  11. package/dist/contracts/graph/embed.d.ts +22 -0
  12. package/dist/{src → contracts}/graph/helpers.d.ts +14 -12
  13. package/dist/{src → contracts}/graph/neo4j.d.ts +5 -5
  14. package/dist/contracts/graph/schema.d.ts +62 -0
  15. package/dist/{src → contracts}/graph/types.d.ts +1 -1
  16. package/dist/contracts/graph.d.ts +14 -0
  17. package/dist/contracts/runtime.d.ts +278 -0
  18. package/dist/contracts/wire.d.ts +120 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/src/lib/adapters/database/index.d.ts +61 -0
  21. package/dist/src/lib/adapters/database/message-content.d.ts +30 -0
  22. package/dist/src/lib/adapters/database/mssql/attachments.d.ts +100 -0
  23. package/dist/src/lib/adapters/database/mssql/client.d.ts +8 -0
  24. package/dist/src/lib/adapters/database/mssql/index.d.ts +194 -0
  25. package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +17 -0
  26. package/dist/src/lib/adapters/database/mssql/messages.d.ts +37 -0
  27. package/dist/src/lib/adapters/database/mssql/threads.d.ts +50 -0
  28. package/dist/src/lib/adapters/database/postgres/attachments.d.ts +113 -0
  29. package/dist/src/lib/adapters/database/postgres/client.d.ts +8 -0
  30. package/dist/src/lib/adapters/database/postgres/index.d.ts +207 -0
  31. package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +17 -0
  32. package/dist/src/lib/adapters/database/postgres/messages.d.ts +37 -0
  33. package/dist/src/lib/adapters/database/postgres/threads.d.ts +50 -0
  34. package/{src/adapters/storage.ts → dist/src/lib/adapters/storage/index.d.ts} +1 -1
  35. package/dist/src/{adapters → lib/adapters/storage}/minio.d.ts +1 -1
  36. package/dist/src/lib/ai/active-runs.d.ts +63 -0
  37. package/dist/src/lib/ai/attachments.d.ts +30 -0
  38. package/dist/src/lib/ai/backend-url.d.ts +16 -0
  39. package/dist/src/lib/ai/cc-runtime.d.ts +61 -0
  40. package/dist/src/lib/ai/commit-gate.d.ts +21 -0
  41. package/dist/src/{ai → lib/ai}/context/builder.d.ts +6 -7
  42. package/dist/src/lib/ai/context/compression-middleware.d.ts +15 -0
  43. package/dist/src/lib/ai/context/compressor.d.ts +7 -0
  44. package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +24 -0
  45. package/dist/src/lib/ai/context/optimize-thread-context.d.ts +9 -0
  46. package/dist/src/lib/ai/context/summarizer.d.ts +5 -0
  47. package/dist/src/{ai → lib/ai}/context/token-estimator.d.ts +5 -8
  48. package/dist/src/{ai → lib/ai}/context/types.d.ts +2 -0
  49. package/dist/src/{ai → lib/ai}/fetch.d.ts +1 -1
  50. package/dist/src/lib/ai/finish-turn.d.ts +23 -0
  51. package/dist/src/lib/ai/helpers.d.ts +38 -0
  52. package/dist/src/lib/ai/index.d.ts +7 -0
  53. package/dist/src/lib/ai/inspector.d.ts +41 -0
  54. package/dist/src/lib/ai/interceptors/request-interceptor.d.ts +13 -0
  55. package/dist/src/{ai → lib/ai}/prompt.d.ts +5 -4
  56. package/dist/src/lib/ai/redis-runs.d.ts +41 -0
  57. package/dist/src/lib/ai/redis-stream-log.d.ts +39 -0
  58. package/dist/src/lib/ai/tools/execute-code.tool.d.ts +18 -0
  59. package/dist/src/lib/ai/tools/query-graph.tool.d.ts +13 -0
  60. package/dist/src/lib/ai/tools/read-attachment.tool.d.ts +21 -0
  61. package/dist/src/lib/ai/tools/search-common.d.ts +17 -0
  62. package/dist/src/lib/ai/tools/search-knowledge.tool.d.ts +15 -0
  63. package/dist/src/lib/ai/tools/search-services.tool.d.ts +12 -0
  64. package/dist/src/lib/ai/tools/search-tools.tool.d.ts +12 -0
  65. package/dist/src/lib/ai/turn-tools.d.ts +39 -0
  66. package/dist/src/lib/ai/vision/rasterize-pdf.d.ts +26 -0
  67. package/dist/src/lib/ai/vision/rasterize-pdf.worker.d.ts +1 -0
  68. package/dist/src/lib/ai/vision/vision-reader.d.ts +45 -0
  69. package/dist/src/lib/cc/client.d.ts +183 -0
  70. package/dist/src/lib/cc/config-cache.d.ts +20 -0
  71. package/dist/src/lib/cc/format.d.ts +23 -0
  72. package/dist/src/lib/cc/registry.d.ts +34 -0
  73. package/dist/src/lib/cc/types.d.ts +27 -0
  74. package/dist/src/lib/config.d.ts +170 -0
  75. package/dist/src/lib/db/drizzle.config.mssql.d.ts +2 -0
  76. package/dist/src/lib/db/drizzle.config.pg.d.ts +2 -0
  77. package/dist/src/lib/db/migrate.d.ts +7 -0
  78. package/dist/src/{db/schema.d.ts → lib/db/schema.mssql.d.ts} +236 -24
  79. package/dist/src/lib/db/schema.pg.d.ts +546 -0
  80. package/dist/src/{factory.d.ts → lib/factory.d.ts} +2 -12
  81. package/dist/src/lib/graph/index.d.ts +10 -0
  82. package/dist/src/{graph → lib/graph}/resolver.d.ts +2 -3
  83. package/dist/src/{index.d.ts → lib/index.d.ts} +3 -4
  84. package/dist/src/lib/redis.d.ts +19 -0
  85. package/dist/src/{routes → lib/routes}/chat.d.ts +1 -1
  86. package/dist/src/{routes → lib/routes}/files.d.ts +1 -1
  87. package/dist/src/lib/routes/owned-thread.d.ts +17 -0
  88. package/dist/src/{routes → lib/routes}/threads.d.ts +1 -1
  89. package/dist/src/{routes → lib/routes}/ws.d.ts +1 -1
  90. package/dist/src/lib/types.d.ts +58 -0
  91. package/dist/src/{ws → lib/ws}/connections.d.ts +2 -1
  92. package/index.ts +1 -1
  93. package/package.json +35 -15
  94. package/src/lib/adapters/database/index.ts +78 -0
  95. package/src/lib/adapters/database/message-content.ts +39 -0
  96. package/src/lib/adapters/database/mssql/attachments.ts +90 -0
  97. package/src/lib/adapters/database/mssql/client.ts +11 -0
  98. package/src/lib/adapters/database/mssql/index.ts +23 -0
  99. package/src/lib/adapters/database/mssql/llm-requests.ts +43 -0
  100. package/src/lib/adapters/database/mssql/messages.ts +92 -0
  101. package/src/lib/adapters/database/mssql/threads.ts +83 -0
  102. package/src/lib/adapters/database/postgres/attachments.ts +88 -0
  103. package/src/lib/adapters/database/postgres/client.ts +11 -0
  104. package/src/lib/adapters/database/postgres/index.ts +23 -0
  105. package/src/lib/adapters/database/postgres/llm-requests.ts +45 -0
  106. package/src/lib/adapters/database/postgres/messages.ts +92 -0
  107. package/src/lib/adapters/database/postgres/threads.ts +84 -0
  108. package/{dist/src/adapters/storage.d.ts → src/lib/adapters/storage/index.ts} +1 -1
  109. package/src/{adapters → lib/adapters/storage}/minio.ts +7 -6
  110. package/src/lib/ai/active-runs.ts +157 -0
  111. package/src/lib/ai/attachments.ts +144 -0
  112. package/src/lib/ai/backend-url.ts +27 -0
  113. package/src/lib/ai/cc-runtime.ts +63 -0
  114. package/src/lib/ai/commit-gate.ts +116 -0
  115. package/src/{ai → lib/ai}/context/builder.ts +12 -14
  116. package/src/lib/ai/context/compression-middleware.ts +44 -0
  117. package/src/lib/ai/context/compressor.ts +267 -0
  118. package/src/lib/ai/context/intra-turn-compressor.ts +181 -0
  119. package/src/lib/ai/context/optimize-thread-context.ts +50 -0
  120. package/src/lib/ai/context/summarizer.ts +48 -0
  121. package/src/lib/ai/context/token-estimator.ts +65 -0
  122. package/src/{ai → lib/ai}/context/types.ts +4 -1
  123. package/src/{ai → lib/ai}/fetch.ts +10 -5
  124. package/src/lib/ai/finish-turn.ts +75 -0
  125. package/src/lib/ai/helpers.ts +100 -0
  126. package/src/lib/ai/index.ts +408 -0
  127. package/src/lib/ai/inspector.ts +112 -0
  128. package/src/lib/ai/interceptors/request-interceptor.ts +89 -0
  129. package/src/lib/ai/prompt.ts +355 -0
  130. package/src/lib/ai/redis-runs.ts +167 -0
  131. package/src/lib/ai/redis-stream-log.ts +219 -0
  132. package/src/lib/ai/tools/execute-code.tool.ts +267 -0
  133. package/src/{ai → lib/ai}/tools/query-graph.tool.ts +7 -8
  134. package/src/lib/ai/tools/read-attachment.tool.ts +59 -0
  135. package/src/lib/ai/tools/search-common.ts +15 -0
  136. package/src/lib/ai/tools/search-knowledge.tool.ts +33 -0
  137. package/src/lib/ai/tools/search-services.tool.ts +31 -0
  138. package/src/lib/ai/tools/search-tools.tool.ts +29 -0
  139. package/src/lib/ai/turn-tools.ts +154 -0
  140. package/src/lib/ai/vision/rasterize-pdf.ts +69 -0
  141. package/src/lib/ai/vision/rasterize-pdf.worker.ts +81 -0
  142. package/src/lib/ai/vision/vision-reader.ts +130 -0
  143. package/src/{auth → lib/auth}/middleware.ts +12 -3
  144. package/src/lib/cc/client.ts +273 -0
  145. package/src/lib/cc/config-cache.ts +32 -0
  146. package/src/lib/cc/format.ts +96 -0
  147. package/src/lib/cc/registry.ts +62 -0
  148. package/src/lib/cc/types.ts +44 -0
  149. package/src/lib/config.ts +212 -0
  150. package/src/lib/db/drizzle.config.mssql.ts +9 -0
  151. package/src/lib/db/drizzle.config.pg.ts +9 -0
  152. package/src/lib/db/migrate.ts +56 -0
  153. package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/migration.sql +12 -0
  154. package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/snapshot.json +106 -1
  155. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/migration.sql +20 -0
  156. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/snapshot.json +497 -0
  157. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/migration.sql +1 -0
  158. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/snapshot.json +516 -0
  159. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/migration.sql +2 -0
  160. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/snapshot.json +516 -0
  161. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/migration.sql +53 -0
  162. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/snapshot.json +584 -0
  163. package/src/lib/db/migrations/pg/20260812174622_user_id_text/migration.sql +2 -0
  164. package/src/lib/db/migrations/pg/20260812174622_user_id_text/snapshot.json +584 -0
  165. package/src/lib/db/schema.mssql.ts +94 -0
  166. package/src/lib/db/schema.pg.ts +95 -0
  167. package/src/lib/factory.ts +127 -0
  168. package/src/lib/graph/index.ts +19 -0
  169. package/src/lib/graph/resolver.ts +387 -0
  170. package/src/{index.ts → lib/index.ts} +13 -5
  171. package/src/lib/redis.ts +44 -0
  172. package/src/lib/routes/chat.ts +115 -0
  173. package/src/lib/routes/files.ts +129 -0
  174. package/src/lib/routes/owned-thread.ts +17 -0
  175. package/src/{routes → lib/routes}/threads.ts +22 -31
  176. package/src/{routes → lib/routes}/ws.ts +9 -3
  177. package/src/lib/types.ts +76 -0
  178. package/src/{ws → lib/ws}/connections.ts +9 -1
  179. package/tsconfig.json +48 -0
  180. package/dist/src/adapters/database.d.ts +0 -30
  181. package/dist/src/adapters/mssql.d.ts +0 -3
  182. package/dist/src/ai/active-streams.d.ts +0 -14
  183. package/dist/src/ai/context/compressor.d.ts +0 -7
  184. package/dist/src/ai/context/index.d.ts +0 -15
  185. package/dist/src/ai/context/summarizer.d.ts +0 -5
  186. package/dist/src/ai/helpers.d.ts +0 -5
  187. package/dist/src/ai/index.d.ts +0 -4
  188. package/dist/src/ai/interceptors/request-interceptor.d.ts +0 -12
  189. package/dist/src/ai/tools/call-endpoint.tool.d.ts +0 -7
  190. package/dist/src/ai/tools/capture-files.tool.d.ts +0 -6
  191. package/dist/src/ai/tools/execute-code.tool.d.ts +0 -4
  192. package/dist/src/ai/tools/query-graph.tool.d.ts +0 -5
  193. package/dist/src/cli/extract-endpoints.d.ts +0 -6
  194. package/dist/src/config.d.ts +0 -165
  195. package/dist/src/db/migrate.d.ts +0 -1
  196. package/dist/src/graph/expand-domains.d.ts +0 -2
  197. package/dist/src/graph/generate-cypher.d.ts +0 -22
  198. package/dist/src/graph/index.d.ts +0 -11
  199. package/dist/src/graph/seed.d.ts +0 -19
  200. package/dist/src/graph/validate.d.ts +0 -2
  201. package/dist/src/routes/index.d.ts +0 -4
  202. package/dist/src/types.d.ts +0 -74
  203. package/dist/src/ws/events.d.ts +0 -39
  204. package/dist/src/ws/index.d.ts +0 -3
  205. package/dist/src/ws/notify.d.ts +0 -2
  206. package/src/adapters/database.ts +0 -29
  207. package/src/adapters/mssql.ts +0 -195
  208. package/src/ai/active-streams.ts +0 -123
  209. package/src/ai/context/compressor.ts +0 -47
  210. package/src/ai/context/index.ts +0 -75
  211. package/src/ai/context/summarizer.ts +0 -50
  212. package/src/ai/context/token-estimator.ts +0 -60
  213. package/src/ai/helpers.ts +0 -32
  214. package/src/ai/index.ts +0 -277
  215. package/src/ai/interceptors/request-interceptor.ts +0 -61
  216. package/src/ai/prompt.ts +0 -126
  217. package/src/ai/tools/call-endpoint.tool.ts +0 -89
  218. package/src/ai/tools/capture-files.tool.ts +0 -20
  219. package/src/ai/tools/execute-code.tool.ts +0 -153
  220. package/src/cli/extract-endpoints.ts +0 -550
  221. package/src/config.ts +0 -182
  222. package/src/db/migrate.ts +0 -21
  223. package/src/db/migrations/20260315000000_add_context_meta/migration.sql +0 -1
  224. package/src/db/schema.ts +0 -70
  225. package/src/factory.ts +0 -171
  226. package/src/graph/expand-domains.ts +0 -276
  227. package/src/graph/generate-cypher.ts +0 -192
  228. package/src/graph/index.ts +0 -47
  229. package/src/graph/resolver.ts +0 -357
  230. package/src/graph/seed.ts +0 -162
  231. package/src/graph/validate.ts +0 -78
  232. package/src/routes/chat.ts +0 -86
  233. package/src/routes/files.ts +0 -100
  234. package/src/routes/index.ts +0 -4
  235. package/src/types.ts +0 -74
  236. package/src/ws/events.ts +0 -39
  237. package/src/ws/index.ts +0 -11
  238. package/src/ws/notify.ts +0 -9
  239. /package/dist/src/{auth → lib/auth}/middleware.d.ts +0 -0
@@ -0,0 +1,113 @@
1
+ import type { PostgresDb } from "./client";
2
+ export declare function createAttachmentsRepository(db: PostgresDb): {
3
+ createPending(row: {
4
+ userId: string;
5
+ threadId: string;
6
+ filename: string;
7
+ contentType: string;
8
+ sizeBytes: number;
9
+ storageKey: string;
10
+ status: "pending" | "described" | "failed" | "skipped";
11
+ id?: string | undefined;
12
+ createdAt?: Date | undefined;
13
+ updatedAt?: Date | undefined;
14
+ messageId?: string | null | undefined;
15
+ description?: string | null | undefined;
16
+ }, limit: number): Promise<{
17
+ id: string;
18
+ userId: string;
19
+ createdAt: Date;
20
+ updatedAt: Date;
21
+ threadId: string;
22
+ messageId: string | null;
23
+ filename: string;
24
+ contentType: string;
25
+ sizeBytes: number;
26
+ storageKey: string;
27
+ status: "pending" | "described" | "failed" | "skipped";
28
+ description: string | null;
29
+ } | undefined>;
30
+ getById(id: string, userId: string): Promise<{
31
+ id: string;
32
+ userId: string;
33
+ createdAt: Date;
34
+ updatedAt: Date;
35
+ threadId: string;
36
+ messageId: string | null;
37
+ filename: string;
38
+ contentType: string;
39
+ sizeBytes: number;
40
+ storageKey: string;
41
+ status: "pending" | "described" | "failed" | "skipped";
42
+ description: string | null;
43
+ } | {
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ id: string;
47
+ threadId: string;
48
+ userId: string;
49
+ messageId: string | null;
50
+ filename: string;
51
+ contentType: string;
52
+ sizeBytes: number;
53
+ storageKey: string;
54
+ status: "pending" | "described" | "failed" | "skipped";
55
+ description: string | null;
56
+ } | undefined>;
57
+ listByThread(threadId: string, userId: string): Promise<{
58
+ createdAt: Date;
59
+ updatedAt: Date;
60
+ id: string;
61
+ threadId: string;
62
+ userId: string;
63
+ messageId: string | null;
64
+ filename: string;
65
+ contentType: string;
66
+ sizeBytes: number;
67
+ storageKey: string;
68
+ status: "pending" | "described" | "failed" | "skipped";
69
+ description: string | null;
70
+ }[]>;
71
+ claimForMessage(threadId: string, userId: string, messageId: string): Promise<{
72
+ createdAt: Date;
73
+ updatedAt: Date;
74
+ id: string;
75
+ threadId: string;
76
+ userId: string;
77
+ messageId: string | null;
78
+ filename: string;
79
+ contentType: string;
80
+ sizeBytes: number;
81
+ storageKey: string;
82
+ status: "pending" | "described" | "failed" | "skipped";
83
+ description: string | null;
84
+ }[]>;
85
+ setDescription(id: string, userId: string, status: "pending" | "described" | "failed" | "skipped", description: string | undefined): Promise<void>;
86
+ remove(id: string, userId: string): Promise<{
87
+ id: string;
88
+ userId: string;
89
+ createdAt: Date;
90
+ updatedAt: Date;
91
+ threadId: string;
92
+ messageId: string | null;
93
+ filename: string;
94
+ contentType: string;
95
+ sizeBytes: number;
96
+ storageKey: string;
97
+ status: "pending" | "described" | "failed" | "skipped";
98
+ description: string | null;
99
+ } | {
100
+ id: string;
101
+ userId: string;
102
+ createdAt: Date;
103
+ updatedAt: Date;
104
+ threadId: string;
105
+ messageId: string | null;
106
+ filename: string;
107
+ contentType: string;
108
+ sizeBytes: number;
109
+ storageKey: string;
110
+ status: "pending" | "described" | "failed" | "skipped";
111
+ description: string | null;
112
+ } | undefined>;
113
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Global snake_case mapping means schema columns are never spelled out twice —
3
+ * the TypeScript name is the source of truth and Drizzle derives the column.
4
+ */
5
+ export declare function createPostgresDb(connectionString: string): import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, never>, import("drizzle-orm").EmptyRelations> & {
6
+ $client: import("pg").Pool;
7
+ };
8
+ export type PostgresDb = ReturnType<typeof createPostgresDb>;
@@ -0,0 +1,207 @@
1
+ import type { StorageAdapter } from "../../../adapters/storage/index";
2
+ /**
3
+ * The Postgres implementation of the database contract. One repository per
4
+ * table; only threads takes storage, because deleting a thread is the one
5
+ * operation that also has to reach into object storage.
6
+ */
7
+ export declare function createPostgresAdapter(connectionString: string, storage?: StorageAdapter): {
8
+ threads: {
9
+ list(userId: string, agentId: string): Promise<{
10
+ createdAt: Date;
11
+ updatedAt: Date;
12
+ id: string;
13
+ userId: string;
14
+ agentId: string;
15
+ title: string | null;
16
+ session: Record<string, unknown> | null;
17
+ contextMeta: import("../../..").ThreadContextMeta | null;
18
+ }[]>;
19
+ getById(userId: string, threadId: string): Promise<{
20
+ id: string;
21
+ userId: string;
22
+ agentId: string;
23
+ title: string | null;
24
+ session: Record<string, unknown> | null;
25
+ contextMeta: import("../../..").ThreadContextMeta | null;
26
+ createdAt: Date;
27
+ updatedAt: Date;
28
+ } | null>;
29
+ create(userId: string, agentId: string): Promise<{
30
+ id: string;
31
+ userId: string;
32
+ agentId: string;
33
+ title: string | null;
34
+ session: Record<string, unknown> | null;
35
+ contextMeta: import("../../..").ThreadContextMeta | null;
36
+ createdAt: Date;
37
+ updatedAt: Date;
38
+ }>;
39
+ delete(userId: string, threadId: string): Promise<void>;
40
+ touch(threadId: string): Promise<{
41
+ id: string;
42
+ userId: string;
43
+ agentId: string;
44
+ title: string | null;
45
+ session: Record<string, unknown> | null;
46
+ contextMeta: import("../../..").ThreadContextMeta | null;
47
+ createdAt: Date;
48
+ updatedAt: Date;
49
+ }>;
50
+ updateTitle(threadId: string, title: string): Promise<void>;
51
+ updateSession(threadId: string, session: Record<string, unknown>): Promise<void>;
52
+ updateContextMeta(threadId: string, meta: import("../../..").ThreadContextMeta): Promise<void>;
53
+ };
54
+ messages: {
55
+ list(userId: string, threadId: string, opts: {
56
+ limit?: number;
57
+ } | undefined): Promise<{
58
+ id: string;
59
+ text: string | null;
60
+ createdAt: Date;
61
+ updatedAt: Date;
62
+ threadId: string;
63
+ content: import("../../../types").ChatMessage;
64
+ ordinal: number;
65
+ role: "system" | "user" | "assistant" | "tool";
66
+ }[] | {
67
+ createdAt: Date;
68
+ updatedAt: Date;
69
+ id: string;
70
+ threadId: string;
71
+ text: string | null;
72
+ content: import("../../../types").ChatMessage;
73
+ ordinal: number;
74
+ role: "system" | "user" | "assistant" | "tool";
75
+ }[]>;
76
+ upsert(threadId: string, messagesToUpsert: import("../../../types").ChatMessage[], options?: {
77
+ replaceAttachments?: boolean;
78
+ }): Promise<void>;
79
+ };
80
+ llmRequests: {
81
+ insert(requests: {
82
+ messageId: string;
83
+ stepNumber: number;
84
+ prompt: string;
85
+ output: string | null;
86
+ tokenUsage: import("../../..").TokenUsage | null;
87
+ }[]): Promise<void>;
88
+ listByMessageId(messageId: string): Promise<{
89
+ id: string;
90
+ prompt: string;
91
+ output: string | null;
92
+ tokenUsage: import("../../..").TokenUsage | null;
93
+ }[]>;
94
+ };
95
+ attachments: {
96
+ createPending(row: {
97
+ userId: string;
98
+ threadId: string;
99
+ filename: string;
100
+ contentType: string;
101
+ sizeBytes: number;
102
+ storageKey: string;
103
+ status: "pending" | "described" | "failed" | "skipped";
104
+ id?: string | undefined;
105
+ createdAt?: Date | undefined;
106
+ updatedAt?: Date | undefined;
107
+ messageId?: string | null | undefined;
108
+ description?: string | null | undefined;
109
+ }, limit: number): Promise<{
110
+ id: string;
111
+ userId: string;
112
+ createdAt: Date;
113
+ updatedAt: Date;
114
+ threadId: string;
115
+ messageId: string | null;
116
+ filename: string;
117
+ contentType: string;
118
+ sizeBytes: number;
119
+ storageKey: string;
120
+ status: "pending" | "described" | "failed" | "skipped";
121
+ description: string | null;
122
+ } | undefined>;
123
+ getById(id: string, userId: string): Promise<{
124
+ id: string;
125
+ userId: string;
126
+ createdAt: Date;
127
+ updatedAt: Date;
128
+ threadId: string;
129
+ messageId: string | null;
130
+ filename: string;
131
+ contentType: string;
132
+ sizeBytes: number;
133
+ storageKey: string;
134
+ status: "pending" | "described" | "failed" | "skipped";
135
+ description: string | null;
136
+ } | {
137
+ createdAt: Date;
138
+ updatedAt: Date;
139
+ id: string;
140
+ threadId: string;
141
+ userId: string;
142
+ messageId: string | null;
143
+ filename: string;
144
+ contentType: string;
145
+ sizeBytes: number;
146
+ storageKey: string;
147
+ status: "pending" | "described" | "failed" | "skipped";
148
+ description: string | null;
149
+ } | undefined>;
150
+ listByThread(threadId: string, userId: string): Promise<{
151
+ createdAt: Date;
152
+ updatedAt: Date;
153
+ id: string;
154
+ threadId: string;
155
+ userId: string;
156
+ messageId: string | null;
157
+ filename: string;
158
+ contentType: string;
159
+ sizeBytes: number;
160
+ storageKey: string;
161
+ status: "pending" | "described" | "failed" | "skipped";
162
+ description: string | null;
163
+ }[]>;
164
+ claimForMessage(threadId: string, userId: string, messageId: string): Promise<{
165
+ createdAt: Date;
166
+ updatedAt: Date;
167
+ id: string;
168
+ threadId: string;
169
+ userId: string;
170
+ messageId: string | null;
171
+ filename: string;
172
+ contentType: string;
173
+ sizeBytes: number;
174
+ storageKey: string;
175
+ status: "pending" | "described" | "failed" | "skipped";
176
+ description: string | null;
177
+ }[]>;
178
+ setDescription(id: string, userId: string, status: "pending" | "described" | "failed" | "skipped", description: string | undefined): Promise<void>;
179
+ remove(id: string, userId: string): Promise<{
180
+ id: string;
181
+ userId: string;
182
+ createdAt: Date;
183
+ updatedAt: Date;
184
+ threadId: string;
185
+ messageId: string | null;
186
+ filename: string;
187
+ contentType: string;
188
+ sizeBytes: number;
189
+ storageKey: string;
190
+ status: "pending" | "described" | "failed" | "skipped";
191
+ description: string | null;
192
+ } | {
193
+ id: string;
194
+ userId: string;
195
+ createdAt: Date;
196
+ updatedAt: Date;
197
+ threadId: string;
198
+ messageId: string | null;
199
+ filename: string;
200
+ contentType: string;
201
+ sizeBytes: number;
202
+ storageKey: string;
203
+ status: "pending" | "described" | "failed" | "skipped";
204
+ description: string | null;
205
+ } | undefined>;
206
+ };
207
+ };
@@ -0,0 +1,17 @@
1
+ import type { PostgresDb } from "./client";
2
+ export declare function createLlmRequestsRepository(db: PostgresDb): {
3
+ insert(requests: {
4
+ messageId: string;
5
+ stepNumber: number;
6
+ prompt: string;
7
+ output: string | null;
8
+ tokenUsage: import("../../..").TokenUsage | null;
9
+ }[]): Promise<void>;
10
+ /** Ordered by step so the inspector replays a turn in the order it ran. */
11
+ listByMessageId(messageId: string): Promise<{
12
+ id: string;
13
+ prompt: string;
14
+ output: string | null;
15
+ tokenUsage: import("../../..").TokenUsage | null;
16
+ }[]>;
17
+ };
@@ -0,0 +1,37 @@
1
+ import type { ChatMessage } from "../../../types";
2
+ import type { PostgresDb } from "./client";
3
+ export declare function createMessagesRepository(db: PostgresDb): {
4
+ /**
5
+ * Fetches the newest N and reverses, so a limit keeps the most recent
6
+ * messages while callers still receive them oldest-first.
7
+ */
8
+ list(userId: string, threadId: string, opts: {
9
+ limit?: number;
10
+ } | undefined): Promise<{
11
+ id: string;
12
+ text: string | null;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ threadId: string;
16
+ content: ChatMessage;
17
+ ordinal: number;
18
+ role: "system" | "user" | "assistant" | "tool";
19
+ }[] | {
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ id: string;
23
+ threadId: string;
24
+ text: string | null;
25
+ content: ChatMessage;
26
+ ordinal: number;
27
+ role: "system" | "user" | "assistant" | "tool";
28
+ }[]>;
29
+ /**
30
+ * Ids are client-generated, so a turn mixes new messages with edits to
31
+ * ones already stored. Splitting on existence lets the new ones go in as
32
+ * a single insert; the rest are updated individually.
33
+ */
34
+ upsert(threadId: string, messagesToUpsert: ChatMessage[], options?: {
35
+ replaceAttachments?: boolean;
36
+ }): Promise<void>;
37
+ };
@@ -0,0 +1,50 @@
1
+ import type { ThreadContextMeta } from "../../../ai/context/types";
2
+ import type { PostgresDb } from "./client";
3
+ import type { StorageAdapter } from "../../../adapters/storage/index";
4
+ export declare function createThreadsRepository(db: PostgresDb, storage?: StorageAdapter): {
5
+ list(userId: string, agentId: string): Promise<{
6
+ createdAt: Date;
7
+ updatedAt: Date;
8
+ id: string;
9
+ userId: string;
10
+ agentId: string;
11
+ title: string | null;
12
+ session: Record<string, unknown> | null;
13
+ contextMeta: ThreadContextMeta | null;
14
+ }[]>;
15
+ getById(userId: string, threadId: string): Promise<{
16
+ id: string;
17
+ userId: string;
18
+ agentId: string;
19
+ title: string | null;
20
+ session: Record<string, unknown> | null;
21
+ contextMeta: ThreadContextMeta | null;
22
+ createdAt: Date;
23
+ updatedAt: Date;
24
+ } | null>;
25
+ create(userId: string, agentId: string): Promise<{
26
+ id: string;
27
+ userId: string;
28
+ agentId: string;
29
+ title: string | null;
30
+ session: Record<string, unknown> | null;
31
+ contextMeta: ThreadContextMeta | null;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }>;
35
+ /** Object storage has no foreign keys, so attachment paths must be swept before row cascade. */
36
+ delete(userId: string, threadId: string): Promise<void>;
37
+ touch(threadId: string): Promise<{
38
+ id: string;
39
+ userId: string;
40
+ agentId: string;
41
+ title: string | null;
42
+ session: Record<string, unknown> | null;
43
+ contextMeta: ThreadContextMeta | null;
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ }>;
47
+ updateTitle(threadId: string, title: string): Promise<void>;
48
+ updateSession(threadId: string, session: Record<string, unknown>): Promise<void>;
49
+ updateContextMeta(threadId: string, meta: ThreadContextMeta): Promise<void>;
50
+ };
@@ -2,5 +2,5 @@ export type StorageAdapter = {
2
2
  put(path: string, data: string): Promise<boolean>;
3
3
  get(path: string): Promise<string | false>;
4
4
  delete(paths: string[]): Promise<boolean>;
5
- stream(path: string): Promise<ReadableStream>;
5
+ stream(path: string): Promise<ReadableStream<Uint8Array>>;
6
6
  };
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from "./storage";
1
+ import type { StorageAdapter } from "./index";
2
2
  export type MinioConfig = {
3
3
  endPoint: string;
4
4
  port: number;
@@ -0,0 +1,63 @@
1
+ import { type StreamDurability } from "@tanstack/ai";
2
+ /**
3
+ * The live turn on a thread. Generation runs detached from the HTTP request that
4
+ * started it, so this registry — not the request — owns the run's lifetime: it is
5
+ * how abort reaches a producer and how a reconnecting client finds the run to
6
+ * rejoin.
7
+ */
8
+ export type ActiveRun = {
9
+ runId: string;
10
+ abortController: AbortController;
11
+ };
12
+ /**
13
+ * One backend owns both halves of a live run: the thread→run claim registry and
14
+ * the durability log the run streams through. In-memory is the single-process
15
+ * default; `createCortex({ redis })` swaps in the Redis coordinator so claims,
16
+ * aborts, and logs survive a producer restart and reach every instance.
17
+ */
18
+ export type RunCoordinator = {
19
+ /** Claims the thread for a new run, aborting whatever was running on it. */
20
+ startRun: (threadId: string) => Promise<ActiveRun>;
21
+ getRunId: (threadId: string) => Promise<string | undefined>;
22
+ /** Which of `threadIds` have a live run — one round trip, for list views. */
23
+ runningThreadIds: (threadIds: string[]) => Promise<Set<string>>;
24
+ /** Aborts the thread's live run. False when there was none to abort — the
25
+ * caller must not report an abort that never happened. */
26
+ abortRun: (threadId: string) => Promise<boolean>;
27
+ /** Releases the thread, but only for the run that still holds it — a
28
+ * superseded run finishing late must not evict its replacement. */
29
+ endRun: (threadId: string, runId: string) => Promise<void>;
30
+ /** The producer's sink: `resumeFrom()` is null, so appends flow into the log. */
31
+ producerLog: (runId: string) => StreamDurability;
32
+ /** A reader on the run's log, replaying from `offset` and tailing until close.
33
+ * Takes the thread too: the thread's claim is how a reader can tell a live
34
+ * producer from a dead one. */
35
+ joinLog: (threadId: string, runId: string, offset?: string) => StreamDurability;
36
+ /**
37
+ * Whether a client-supplied resume offset belongs to `runId`. The offset is
38
+ * the adapter's own opaque token and names the log it replays — so an offset
39
+ * naming another run would replay that run's log to whoever presents it.
40
+ */
41
+ offsetBelongsToRun: (offset: string, runId: string) => boolean;
42
+ };
43
+ /**
44
+ * How long a joiner waits for a run's first chunk. The adapter arms this on any
45
+ * empty log, and it cannot tell "the producer died" from "the producer has not
46
+ * reached the model yet" — so it has to clear the worst case: a compression
47
+ * middleware's extra summarization call plus the model's time to first token.
48
+ * It is generous because it is only a backstop: a producer that fails writes its
49
+ * own terminal event into the log, and a run that ended is gone from the
50
+ * registry, so neither ever reaches this timer.
51
+ */
52
+ export declare const JOIN_FIRST_CHUNK_TIMEOUT_MS: number;
53
+ /** `createCortex` swaps the backend in once at startup; everything below delegates. */
54
+ export declare function configureRunCoordination(backend: RunCoordinator): void;
55
+ export declare function startRun(threadId: string): Promise<ActiveRun>;
56
+ export declare function getRunId(threadId: string): Promise<string | undefined>;
57
+ export declare function isRunning(threadId: string): Promise<boolean>;
58
+ export declare function runningThreadIds(threadIds: string[]): Promise<Set<string>>;
59
+ export declare function abortRun(threadId: string): Promise<boolean>;
60
+ export declare function endRun(threadId: string, runId: string): Promise<void>;
61
+ export declare function producerLog(runId: string): StreamDurability<string>;
62
+ export declare function joinLog(threadId: string, runId: string, offset?: string): StreamDurability<string>;
63
+ export declare function offsetBelongsToRun(offset: string, runId: string): boolean;
@@ -0,0 +1,30 @@
1
+ import type { ResolvedCortexAgentConfig } from "../config";
2
+ import type { Attachment, ChatMessage } from "../types";
3
+ type PrepareAttachmentsOptions = {
4
+ config: ResolvedCortexAgentConfig;
5
+ threadId: string;
6
+ userId: string;
7
+ message: ChatMessage;
8
+ abortSignal?: AbortSignal;
9
+ };
10
+ type AttachmentCapabilities = {
11
+ readAttachment: boolean;
12
+ attachmentSentinels: boolean;
13
+ };
14
+ export declare function prepareAttachmentsForTurn(options: PrepareAttachmentsOptions): Promise<{
15
+ id: string;
16
+ userId: string;
17
+ createdAt: Date;
18
+ updatedAt: Date;
19
+ threadId: string;
20
+ messageId: string | null;
21
+ filename: string;
22
+ contentType: string;
23
+ sizeBytes: number;
24
+ storageKey: string;
25
+ status: "pending" | "described" | "failed" | "skipped";
26
+ description: string | null;
27
+ }[]>;
28
+ export declare function buildAttachmentListing(attachmentRows: Attachment[], currentMessageId: string | undefined, capabilities: AttachmentCapabilities): string | undefined;
29
+ export declare function sanitizeAttachmentText(value: string, maxLength?: number): string;
30
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Resolves a backend call target, refusing anything that leaves the configured
3
+ * origin or escapes its base path.
4
+ *
5
+ * `path` arrives from code the model wrote inside the sandbox, so it is untrusted.
6
+ * Concatenating it onto `baseUrl` was unsafe: when `baseUrl` carries no trailing
7
+ * slash — the form the docs show — a path of `@evil.test/x` produces
8
+ * `https://api.example.com@evil.test/x`, where everything before the `@` is read
9
+ * as userinfo and the host becomes `evil.test`. The request carries the service
10
+ * API key and the caller's token, so that is a credential leak, not just an SSRF.
11
+ *
12
+ * Resolving against an explicitly slash-terminated base also neutralizes
13
+ * protocol-relative (`//host`) and absolute (`https://host`) paths, which the
14
+ * origin check below then rejects outright.
15
+ */
16
+ export declare function resolveBackendUrl(baseUrl: string, path: string): URL;
@@ -0,0 +1,61 @@
1
+ import type { ResolvedCortexAgentConfig } from "../config";
2
+ import type { Thread } from "../types";
3
+ import type { ControlCenterClient } from "../cc/client";
4
+ import type { CcToolRegistry } from "../cc/registry";
5
+ import type { ResolveResponse, RuntimeAgentConfig } from "../cc/types";
6
+ type CcRuntimeOptions = {
7
+ ccClient: ControlCenterClient | null;
8
+ ccConfig: RuntimeAgentConfig | null;
9
+ ccResolved: ResolveResponse | null;
10
+ config: ResolvedCortexAgentConfig;
11
+ thread: Thread;
12
+ userId: string;
13
+ token: string;
14
+ turnKey: string;
15
+ abortSignal: AbortSignal;
16
+ getStepIndex: () => number;
17
+ /** Reports Control Center tools invoked from inside the sandbox, which the
18
+ * outer tool instrumentation never sees — it only observes `executeCode`. */
19
+ onToolProgress: (toolName: string, toolCallId: string, status: "started" | "finished") => void;
20
+ };
21
+ /**
22
+ * Builds the per-turn Control Center runtime, or undefined when the agent has no
23
+ * Control Center configured — every consumer treats that as "skip CC entirely".
24
+ *
25
+ * Owns the call-index counter, which must restart at zero on each new step so
26
+ * idempotency keys stay stable when a step is retried.
27
+ */
28
+ export declare function createCcRuntime(options: CcRuntimeOptions): {
29
+ client: ControlCenterClient;
30
+ agentId: string;
31
+ config: {
32
+ agentId: string;
33
+ systemPrompt: string;
34
+ promptVariables: ("userName" | "channel" | "locale")[];
35
+ catalogBlurb: string;
36
+ defaultLocale: "en" | "ar";
37
+ metaTools: {
38
+ searchKnowledge: boolean;
39
+ searchTools: boolean;
40
+ searchServices: boolean;
41
+ };
42
+ limits: {
43
+ resolveTokenBudget: number;
44
+ executeTimeoutMs: number;
45
+ maxResponseBytes: number;
46
+ };
47
+ catalogVersion: string;
48
+ publishedAt: string;
49
+ };
50
+ registry: CcToolRegistry;
51
+ threadId: string;
52
+ turnKey: string;
53
+ userId: string;
54
+ locale: "en" | "ar";
55
+ endUserToken: string;
56
+ abortSignal: AbortSignal;
57
+ getStepIndex: () => number;
58
+ nextCallIndex(stepIndex: number): number;
59
+ onToolProgress: (toolName: string, toolCallId: string, status: "started" | "finished") => void;
60
+ } | undefined;
61
+ export {};
@@ -0,0 +1,21 @@
1
+ import { EventType, type StreamChunk, type UIMessage } from "@tanstack/ai";
2
+ type CommitGateOptions = {
3
+ /** Persists the run's messages. Its rejection is reported to the client. */
4
+ commit: (messages: UIMessage[]) => Promise<void>;
5
+ isAborted: () => boolean;
6
+ };
7
+ /**
8
+ * Rebuilds the run's messages from its own chunks and holds the run's terminal
9
+ * event back until they are committed, so a client that refetches when the
10
+ * stream ends can never race the database.
11
+ *
12
+ * Only the terminal event ever waits, and it has to be the *last* one rather
13
+ * than the first: the agent loop emits a terminal event per iteration, and which
14
+ * one ends the run is only knowable once the stream is exhausted.
15
+ */
16
+ export declare function commitBeforeTerminal(stream: AsyncIterable<StreamChunk>, options: CommitGateOptions): AsyncGenerator<import("@tanstack/ai").AGUIEvent | {
17
+ type: EventType.RUN_ERROR;
18
+ timestamp: number;
19
+ message: string;
20
+ }, void, unknown>;
21
+ export {};
@@ -1,7 +1,6 @@
1
- import type { UIMessage } from "ai";
2
- import type { DatabaseAdapter } from "../../adapters/database.ts";
3
- import type { MessageMetadata, Thread } from "../../types.ts";
4
- import type { ContextConfig } from "./types.ts";
1
+ import type { DatabaseAdapter } from "../../adapters/database/index";
2
+ import type { ChatMessage, Thread } from "../../types";
3
+ import type { ContextConfig } from "./types";
5
4
  /**
6
5
  * Builds a token-aware context window from stored messages.
7
6
  *
@@ -13,12 +12,12 @@ import type { ContextConfig } from "./types.ts";
13
12
  * 6. Prepends summary as synthetic message if older messages were trimmed
14
13
  */
15
14
  export declare function buildContextMessages(userId: string, thread: Thread, db: DatabaseAdapter, contextConfig: ContextConfig): Promise<{
16
- messages: UIMessage<MessageMetadata, import("ai").UIDataTypes, import("ai").UITools>[];
17
- allMessages: UIMessage<MessageMetadata, import("ai").UIDataTypes, import("ai").UITools>[];
15
+ messages: ChatMessage[];
16
+ allMessages: ChatMessage[];
18
17
  summary: string | null;
19
18
  }>;
20
19
  /**
21
20
  * Drops the oldest messages until the total estimated tokens fit within `budget`.
22
21
  * Always keeps at least the most recent message.
23
22
  */
24
- export declare function trimMessagesToFit(messages: UIMessage<MessageMetadata>[], budget: number): UIMessage<MessageMetadata, import("ai").UIDataTypes, import("ai").UITools>[];
23
+ export declare function trimMessagesToFit(messages: ChatMessage[], budget: number): ChatMessage[];