@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,212 @@
1
+ import type { AnyServerTool } from "@tanstack/ai";
2
+ import type { DatabaseAdapter } from "./adapters/database/index";
3
+ import type { StorageAdapter } from "./adapters/storage/index";
4
+ import type { DomainDef } from "@cortex/contracts/graph";
5
+ import type { RequestInterceptorOptions } from "./ai/interceptors/request-interceptor";
6
+ import type { ContextConfig } from "./ai/context/types";
7
+ import type { ChatMessage, Thread } from "./types";
8
+
9
+ /** An agent's tools, as `chat()` takes them. */
10
+ export type ToolSet = ReadonlyArray<AnyServerTool>;
11
+
12
+ type ModelConfig = {
13
+ baseURL: string;
14
+ apiKey: string;
15
+ modelName: string;
16
+ providerName?: string;
17
+ };
18
+
19
+ type EmbeddingConfig = {
20
+ baseURL: string;
21
+ apiKey: string;
22
+ modelName: string;
23
+ dimension: number;
24
+ };
25
+
26
+ type Neo4jConfig = {
27
+ url: string;
28
+ user: string;
29
+ password: string;
30
+ };
31
+
32
+ type RerankerConfig = {
33
+ url: string;
34
+ apiKey: string;
35
+ };
36
+
37
+ export type ControlCenterConfig = {
38
+ url: string;
39
+ apiKey: string;
40
+ };
41
+
42
+ export type KnowledgeConfig = {
43
+ swagger?: { url: string };
44
+ domains?: Record<string, DomainDef>;
45
+ };
46
+
47
+ export type PromptContext<
48
+ TSession extends Record<string, unknown> = Record<string, unknown>,
49
+ TRequestContext extends Record<string, unknown> = Record<string, unknown>,
50
+ > = {
51
+ session: TSession | null;
52
+ requestContext: TRequestContext;
53
+ };
54
+
55
+ /**
56
+ * Per-request context handed to a tools factory. Allows tool implementations to
57
+ * close over the active thread, user, session, and request-level context without
58
+ * reaching for globals or AsyncLocalStorage.
59
+ */
60
+ export type ToolContext<
61
+ TSession extends Record<string, unknown> = Record<string, unknown>,
62
+ TRequestContext extends Record<string, unknown> = Record<string, unknown>,
63
+ > = {
64
+ thread: Thread;
65
+ userId: string;
66
+ token: string;
67
+ session: TSession | null;
68
+ requestContext: TRequestContext;
69
+ };
70
+
71
+ export type ToolSetFactory<
72
+ TSession extends Record<string, unknown> = Record<string, unknown>,
73
+ TRequestContext extends Record<string, unknown> = Record<string, unknown>,
74
+ > = (context: ToolContext<TSession, TRequestContext>) => ToolSet;
75
+
76
+ export type DatabaseConfig = {
77
+ type: "mssql" | "postgres";
78
+ connectionString: string;
79
+ };
80
+
81
+ /**
82
+ * Optional. With Redis, live runs survive a producer restart and reach every
83
+ * instance: the chunk log, the thread→run claims, and abort fan-out all move
84
+ * there. Without it, an in-memory fallback covers a single process.
85
+ */
86
+ export type RedisConfig = {
87
+ url: string;
88
+ /** How long a finished run's stream log stays replayable. Defaults to 24 h. */
89
+ streamTtlSeconds?: number;
90
+ };
91
+
92
+ export type StorageConfig = {
93
+ endPoint: string;
94
+ port: number;
95
+ useSSL: boolean;
96
+ accessKey: string;
97
+ secretKey: string;
98
+ bucketName?: string;
99
+ };
100
+
101
+ type BackendFetchConfig = {
102
+ baseUrl: string;
103
+ apiKey: string;
104
+ headers?: Record<string, string>;
105
+ transformRequestBody?: (
106
+ body: Record<string, unknown>,
107
+ context: { token: string },
108
+ ) => Promise<Record<string, unknown>>;
109
+ interceptor?: RequestInterceptorOptions;
110
+ };
111
+
112
+ /** Model and knowledge-graph providers. Declared once at server level; an agent may override any of them. */
113
+ type ProviderConfig = {
114
+ model: ModelConfig;
115
+ fastModel?: ModelConfig;
116
+ vision?: ModelConfig;
117
+ embedding?: EmbeddingConfig;
118
+ neo4j?: Neo4jConfig;
119
+ reranker?: RerankerConfig;
120
+ };
121
+
122
+ /**
123
+ * What an agent *does*, independent of where its providers came from. Shared
124
+ * verbatim by the authored definition and its resolved form — the two differ
125
+ * only in how providers and opt-outs are expressed, so everything else lives
126
+ * here and cannot drift between them.
127
+ */
128
+ type AgentBehavior<
129
+ TSession extends Record<string, unknown>,
130
+ TRequestContext extends Record<string, unknown>,
131
+ > = {
132
+ systemPrompt?:
133
+ | string
134
+ | ((context: PromptContext<TSession, TRequestContext>) => string | Promise<string>);
135
+ tools?: ToolSet | ToolSetFactory<TSession, TRequestContext>;
136
+ backendFetch?: BackendFetchConfig;
137
+ loadSessionData?: (token: string) => Promise<TSession>;
138
+ resolveRequestContext?: (request: Request) => TRequestContext | Promise<TRequestContext>;
139
+ onToolCall?: (toolCall: {
140
+ toolName: string;
141
+ toolCallId: string;
142
+ args: Record<string, unknown>;
143
+ }) => void;
144
+ onStreamFinish?: (result: { messages: ChatMessage[]; isAborted: boolean }) => void;
145
+ };
146
+
147
+ /**
148
+ * An agent as authored. Providers are optional because an unset one inherits
149
+ * from server level; `null` on knowledge means "opt out entirely" rather than
150
+ * "inherit". The Control Center is server-level only: which agents it backs is
151
+ * decided by publishing them there, not per entry here.
152
+ */
153
+ export type CortexAgentDefinition<
154
+ TSession extends Record<string, unknown> = Record<string, unknown>,
155
+ TRequestContext extends Record<string, unknown> = Record<string, unknown>,
156
+ > = AgentBehavior<TSession, TRequestContext> &
157
+ Partial<ProviderConfig> & {
158
+ knowledge?: KnowledgeConfig | null;
159
+ context?: Partial<ContextConfig>;
160
+ };
161
+
162
+ /**
163
+ * An agent after the factory has merged it with server-level config. Every
164
+ * inherit-or-opt-out decision is already resolved, so nothing here is nullable
165
+ * and `model`/`context` are guaranteed present.
166
+ */
167
+ export type ResolvedCortexAgentConfig = AgentBehavior<
168
+ Record<string, unknown>,
169
+ Record<string, unknown>
170
+ > &
171
+ ProviderConfig & {
172
+ agentId: string;
173
+ db: DatabaseAdapter;
174
+ storage?: StorageAdapter;
175
+ controlCenter?: ControlCenterConfig;
176
+ knowledge?: KnowledgeConfig;
177
+ context: ContextConfig;
178
+ };
179
+
180
+ export type CortexConfig = ProviderConfig & {
181
+ port?: number;
182
+ database: DatabaseConfig;
183
+ storage?: StorageConfig;
184
+ redis?: RedisConfig;
185
+ auth?: {
186
+ jwksUri: string;
187
+ issuer: string;
188
+ tokenExtractor?: (req: Request) => string | null;
189
+ cookieName?: string;
190
+ };
191
+ controlCenter?: ControlCenterConfig;
192
+ context?: Partial<ContextConfig>;
193
+ knowledge?: KnowledgeConfig;
194
+ /**
195
+ * Locally-defined agents. With `controlCenter` set, agents published there
196
+ * are served automatically and need no entry here; an entry is only needed
197
+ * for local behavior (tools, backendFetch, provider overrides).
198
+ */
199
+ agents?: Record<string, CortexAgentDefinition>;
200
+ };
201
+
202
+ /**
203
+ * Helper to define an agent with full type inference for `systemPrompt` context.
204
+ * The `context.session` type is inferred from `loadSessionData`'s return type,
205
+ * and `context.requestContext` is inferred from `resolveRequestContext`'s return type.
206
+ */
207
+ export function defineAgent<
208
+ TSession extends Record<string, unknown> = Record<string, unknown>,
209
+ TRequestContext extends Record<string, unknown> = Record<string, unknown>,
210
+ >(config: CortexAgentDefinition<TSession, TRequestContext>) {
211
+ return config as CortexAgentDefinition;
212
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ // Paths are relative to the package root, which is where drizzle-kit is invoked from.
4
+ export default defineConfig({
5
+ schema: "./src/lib/db/schema.mssql.ts",
6
+ out: "./src/lib/db/migrations/mssql",
7
+ dialect: "mssql",
8
+ casing: "snake_case",
9
+ });
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ // Paths are relative to the package root, which is where drizzle-kit is invoked from.
4
+ export default defineConfig({
5
+ schema: "./src/lib/db/schema.pg.ts",
6
+ out: "./src/lib/db/migrations/pg",
7
+ dialect: "postgresql",
8
+ casing: "snake_case",
9
+ });
@@ -0,0 +1,56 @@
1
+ import { resolve } from "path";
2
+ import type { DatabaseConfig } from "@/config";
3
+
4
+ /**
5
+ * Each dialect keeps its own migration history — Postgres starts from a
6
+ * squashed initial migration rather than replaying MSSQL's. The driver imports
7
+ * are lazy so a server only loads the one it was configured for.
8
+ */
9
+ export async function runMigrations(database: DatabaseConfig) {
10
+ const migrationsFolder = resolve(import.meta.dir, "migrations", folderFor(database.type));
11
+ console.log("[cortex-server] Running migrations from:", migrationsFolder);
12
+
13
+ try {
14
+ if (database.type === "postgres") {
15
+ await migratePostgres(database.connectionString, migrationsFolder);
16
+ } else {
17
+ await migrateMssql(database.connectionString, migrationsFolder);
18
+ }
19
+ console.log("[cortex-server] Migrations complete");
20
+ } catch (e) {
21
+ console.log(e);
22
+ }
23
+ }
24
+
25
+ function folderFor(type: DatabaseConfig["type"]) {
26
+ return type === "postgres" ? "pg" : "mssql";
27
+ }
28
+
29
+ async function migrateMssql(connectionString: string, migrationsFolder: string) {
30
+ const { default: mssql } = await import("mssql");
31
+ const { drizzle } = await import("drizzle-orm/node-mssql");
32
+ const { migrate } = await import("drizzle-orm/node-mssql/migrator");
33
+
34
+ const pool = new mssql.ConnectionPool(connectionString);
35
+ await pool.connect();
36
+
37
+ try {
38
+ await migrate(drizzle({ client: pool, casing: "snake_case" }), { migrationsFolder });
39
+ } finally {
40
+ await pool.close();
41
+ }
42
+ }
43
+
44
+ async function migratePostgres(connectionString: string, migrationsFolder: string) {
45
+ const { default: pg } = await import("pg");
46
+ const { drizzle } = await import("drizzle-orm/node-postgres");
47
+ const { migrate } = await import("drizzle-orm/node-postgres/migrator");
48
+
49
+ const pool = new pg.Pool({ connectionString });
50
+
51
+ try {
52
+ await migrate(drizzle({ client: pool, casing: "snake_case" }), { migrationsFolder });
53
+ } finally {
54
+ await pool.end();
55
+ }
56
+ }
@@ -10,6 +10,16 @@ CREATE TABLE [ai].[captured_files] (
10
10
  CONSTRAINT [captured_files_pkey] PRIMARY KEY([id])
11
11
  );
12
12
  --> statement-breakpoint
13
+ CREATE TABLE [ai].[llm_requests] (
14
+ [id] UNIQUEIDENTIFIER CONSTRAINT [llm_requests_id_default] DEFAULT (NEWID()),
15
+ [message_id] nvarchar(128) NOT NULL,
16
+ [step_number] int NOT NULL,
17
+ [prompt] nvarchar(max) NOT NULL,
18
+ [output] nvarchar(max),
19
+ [token_usage] nvarchar(max),
20
+ CONSTRAINT [llm_requests_pkey] PRIMARY KEY([id])
21
+ );
22
+ --> statement-breakpoint
13
23
  CREATE TABLE [ai].[messages] (
14
24
  [id] nvarchar(128),
15
25
  [thread_id] UNIQUEIDENTIFIER NOT NULL,
@@ -27,10 +37,12 @@ CREATE TABLE [ai].[threads] (
27
37
  [agent_id] nvarchar(128) NOT NULL CONSTRAINT [threads_agent_id_default] DEFAULT ('default'),
28
38
  [title] nvarchar(256),
29
39
  [session] nvarchar(max),
40
+ [context_meta] nvarchar(max),
30
41
  [created_at] datetime2 NOT NULL,
31
42
  [updated_at] datetime2 NOT NULL,
32
43
  CONSTRAINT [threads_pkey] PRIMARY KEY([id])
33
44
  );
34
45
  --> statement-breakpoint
35
46
  ALTER TABLE [ai].[captured_files] ADD CONSTRAINT [captured_files_message_id_messages_id_fk] FOREIGN KEY ([message_id]) REFERENCES [ai].[messages]([id]) ON DELETE CASCADE;--> statement-breakpoint
47
+ ALTER TABLE [ai].[llm_requests] ADD CONSTRAINT [llm_requests_message_id_messages_id_fk] FOREIGN KEY ([message_id]) REFERENCES [ai].[messages]([id]) ON DELETE CASCADE;--> statement-breakpoint
36
48
  ALTER TABLE [ai].[messages] ADD CONSTRAINT [messages_thread_id_threads_id_fk] FOREIGN KEY ([thread_id]) REFERENCES [ai].[threads]([id]) ON DELETE CASCADE;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2",
3
3
  "dialect": "mssql",
4
- "id": "d92d3e1a-9613-4d7e-a224-de2dd01b2718",
4
+ "id": "407c2a91-87ca-412e-92c4-1c4d0d3c71b0",
5
5
  "prevIds": ["00000000-0000-0000-0000-000000000000"],
6
6
  "ddl": [
7
7
  {
@@ -13,6 +13,11 @@
13
13
  "entityType": "tables",
14
14
  "schema": "ai"
15
15
  },
16
+ {
17
+ "name": "llm_requests",
18
+ "entityType": "tables",
19
+ "schema": "ai"
20
+ },
16
21
  {
17
22
  "name": "messages",
18
23
  "entityType": "tables",
@@ -83,6 +88,66 @@
83
88
  "entityType": "columns",
84
89
  "table": "captured_files"
85
90
  },
91
+ {
92
+ "type": "UNIQUEIDENTIFIER",
93
+ "notNull": true,
94
+ "generated": null,
95
+ "identity": null,
96
+ "name": "id",
97
+ "schema": "ai",
98
+ "entityType": "columns",
99
+ "table": "llm_requests"
100
+ },
101
+ {
102
+ "type": "nvarchar(128)",
103
+ "notNull": true,
104
+ "generated": null,
105
+ "identity": null,
106
+ "name": "message_id",
107
+ "schema": "ai",
108
+ "entityType": "columns",
109
+ "table": "llm_requests"
110
+ },
111
+ {
112
+ "type": "int",
113
+ "notNull": true,
114
+ "generated": null,
115
+ "identity": null,
116
+ "name": "step_number",
117
+ "schema": "ai",
118
+ "entityType": "columns",
119
+ "table": "llm_requests"
120
+ },
121
+ {
122
+ "type": "nvarchar(max)",
123
+ "notNull": true,
124
+ "generated": null,
125
+ "identity": null,
126
+ "name": "prompt",
127
+ "schema": "ai",
128
+ "entityType": "columns",
129
+ "table": "llm_requests"
130
+ },
131
+ {
132
+ "type": "nvarchar(max)",
133
+ "notNull": false,
134
+ "generated": null,
135
+ "identity": null,
136
+ "name": "output",
137
+ "schema": "ai",
138
+ "entityType": "columns",
139
+ "table": "llm_requests"
140
+ },
141
+ {
142
+ "type": "nvarchar(max)",
143
+ "notNull": false,
144
+ "generated": null,
145
+ "identity": null,
146
+ "name": "token_usage",
147
+ "schema": "ai",
148
+ "entityType": "columns",
149
+ "table": "llm_requests"
150
+ },
86
151
  {
87
152
  "type": "nvarchar(128)",
88
153
  "notNull": true,
@@ -203,6 +268,16 @@
203
268
  "entityType": "columns",
204
269
  "table": "threads"
205
270
  },
271
+ {
272
+ "type": "nvarchar(max)",
273
+ "notNull": false,
274
+ "generated": null,
275
+ "identity": null,
276
+ "name": "context_meta",
277
+ "schema": "ai",
278
+ "entityType": "columns",
279
+ "table": "threads"
280
+ },
206
281
  {
207
282
  "type": "datetime2",
208
283
  "notNull": true,
@@ -236,6 +311,19 @@
236
311
  "table": "captured_files",
237
312
  "schema": "ai"
238
313
  },
314
+ {
315
+ "columns": ["message_id"],
316
+ "nameExplicit": false,
317
+ "schemaTo": "ai",
318
+ "tableTo": "messages",
319
+ "columnsTo": ["id"],
320
+ "onUpdate": "NO ACTION",
321
+ "onDelete": "CASCADE",
322
+ "name": "llm_requests_message_id_messages_id_fk",
323
+ "entityType": "fks",
324
+ "table": "llm_requests",
325
+ "schema": "ai"
326
+ },
239
327
  {
240
328
  "columns": ["thread_id"],
241
329
  "nameExplicit": false,
@@ -257,6 +345,14 @@
257
345
  "schema": "ai",
258
346
  "entityType": "pks"
259
347
  },
348
+ {
349
+ "nameExplicit": false,
350
+ "columns": ["id"],
351
+ "name": "llm_requests_pkey",
352
+ "table": "llm_requests",
353
+ "schema": "ai",
354
+ "entityType": "pks"
355
+ },
260
356
  {
261
357
  "nameExplicit": false,
262
358
  "columns": ["id"],
@@ -282,6 +378,15 @@
282
378
  "schema": "ai",
283
379
  "table": "captured_files"
284
380
  },
381
+ {
382
+ "column": "id",
383
+ "nameExplicit": false,
384
+ "default": "(NEWID())",
385
+ "name": "llm_requests_id_default",
386
+ "entityType": "defaults",
387
+ "schema": "ai",
388
+ "table": "llm_requests"
389
+ },
285
390
  {
286
391
  "column": "id",
287
392
  "nameExplicit": false,
@@ -0,0 +1,20 @@
1
+ CREATE TABLE [ai].[attachments] (
2
+ [id] UNIQUEIDENTIFIER CONSTRAINT [attachments_id_default] DEFAULT (NEWID()),
3
+ [thread_id] UNIQUEIDENTIFIER NOT NULL,
4
+ [user_id] UNIQUEIDENTIFIER NOT NULL,
5
+ [message_id] nvarchar(128),
6
+ [filename] nvarchar(2048) NOT NULL,
7
+ [content_type] nvarchar(256) NOT NULL,
8
+ [size_bytes] int NOT NULL,
9
+ [storage_key] nvarchar(512) NOT NULL,
10
+ [status] nvarchar(16) NOT NULL,
11
+ [description] nvarchar(max),
12
+ [created_at] datetime2 NOT NULL,
13
+ [updated_at] datetime2 NOT NULL,
14
+ CONSTRAINT [attachments_pkey] PRIMARY KEY([id])
15
+ );
16
+ --> statement-breakpoint
17
+ DROP TABLE [ai].[captured_files];--> statement-breakpoint
18
+ ALTER TABLE [ai].[attachments] ADD CONSTRAINT [attachments_thread_id_threads_id_fk] FOREIGN KEY ([thread_id]) REFERENCES [ai].[threads]([id]) ON DELETE CASCADE;--> statement-breakpoint
19
+ ALTER TABLE [ai].[attachments] ADD CONSTRAINT [attachments_message_id_messages_id_fk] FOREIGN KEY ([message_id]) REFERENCES [ai].[messages]([id]);--> statement-breakpoint
20
+ CREATE INDEX [attachments_thread_id_index] ON [ai].[attachments] ([thread_id]);