@m6d/cortex-server 1.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 (82) hide show
  1. package/README.md +64 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/src/adapters/database.d.ts +27 -0
  4. package/dist/src/adapters/minio.d.ts +10 -0
  5. package/dist/src/adapters/mssql.d.ts +3 -0
  6. package/dist/src/adapters/storage.d.ts +6 -0
  7. package/dist/src/ai/fetch.d.ts +2 -0
  8. package/dist/src/ai/helpers.d.ts +5 -0
  9. package/dist/src/ai/index.d.ts +4 -0
  10. package/dist/src/ai/interceptors/resolve-captured-files.d.ts +11 -0
  11. package/dist/src/ai/prompt.d.ts +4 -0
  12. package/dist/src/ai/tools/call-endpoint.tool.d.ts +7 -0
  13. package/dist/src/ai/tools/capture-files.tool.d.ts +6 -0
  14. package/dist/src/ai/tools/execute-code.tool.d.ts +4 -0
  15. package/dist/src/ai/tools/query-graph.tool.d.ts +5 -0
  16. package/dist/src/auth/middleware.d.ts +4 -0
  17. package/dist/src/cli/extract-endpoints.d.ts +6 -0
  18. package/dist/src/config.d.ts +145 -0
  19. package/dist/src/db/migrate.d.ts +1 -0
  20. package/dist/src/db/schema.d.ts +345 -0
  21. package/dist/src/factory.d.ts +17 -0
  22. package/dist/src/graph/generate-cypher.d.ts +22 -0
  23. package/dist/src/graph/helpers.d.ts +60 -0
  24. package/dist/src/graph/index.d.ts +11 -0
  25. package/dist/src/graph/neo4j.d.ts +18 -0
  26. package/dist/src/graph/resolver.d.ts +51 -0
  27. package/dist/src/graph/seed.d.ts +19 -0
  28. package/dist/src/graph/types.d.ts +104 -0
  29. package/dist/src/graph/validate.d.ts +2 -0
  30. package/dist/src/index.d.ts +10 -0
  31. package/dist/src/routes/chat.d.ts +3 -0
  32. package/dist/src/routes/files.d.ts +3 -0
  33. package/dist/src/routes/index.d.ts +4 -0
  34. package/dist/src/routes/threads.d.ts +3 -0
  35. package/dist/src/routes/ws.d.ts +3 -0
  36. package/dist/src/types.d.ts +56 -0
  37. package/dist/src/ws/connections.d.ts +4 -0
  38. package/dist/src/ws/events.d.ts +8 -0
  39. package/dist/src/ws/index.d.ts +3 -0
  40. package/dist/src/ws/notify.d.ts +2 -0
  41. package/index.ts +1 -0
  42. package/package.json +57 -0
  43. package/src/adapters/database.ts +33 -0
  44. package/src/adapters/minio.ts +89 -0
  45. package/src/adapters/mssql.ts +203 -0
  46. package/src/adapters/storage.ts +6 -0
  47. package/src/ai/fetch.ts +39 -0
  48. package/src/ai/helpers.ts +36 -0
  49. package/src/ai/index.ts +145 -0
  50. package/src/ai/interceptors/resolve-captured-files.ts +64 -0
  51. package/src/ai/prompt.ts +120 -0
  52. package/src/ai/tools/call-endpoint.tool.ts +96 -0
  53. package/src/ai/tools/capture-files.tool.ts +22 -0
  54. package/src/ai/tools/execute-code.tool.ts +108 -0
  55. package/src/ai/tools/query-graph.tool.ts +35 -0
  56. package/src/auth/middleware.ts +63 -0
  57. package/src/cli/extract-endpoints.ts +588 -0
  58. package/src/config.ts +155 -0
  59. package/src/db/migrate.ts +21 -0
  60. package/src/db/migrations/20260309012148_cloudy_maria_hill/migration.sql +36 -0
  61. package/src/db/migrations/20260309012148_cloudy_maria_hill/snapshot.json +305 -0
  62. package/src/db/schema.ts +77 -0
  63. package/src/factory.ts +159 -0
  64. package/src/graph/generate-cypher.ts +179 -0
  65. package/src/graph/helpers.ts +68 -0
  66. package/src/graph/index.ts +47 -0
  67. package/src/graph/neo4j.ts +117 -0
  68. package/src/graph/resolver.ts +357 -0
  69. package/src/graph/seed.ts +172 -0
  70. package/src/graph/types.ts +152 -0
  71. package/src/graph/validate.ts +80 -0
  72. package/src/index.ts +27 -0
  73. package/src/routes/chat.ts +38 -0
  74. package/src/routes/files.ts +105 -0
  75. package/src/routes/index.ts +4 -0
  76. package/src/routes/threads.ts +69 -0
  77. package/src/routes/ws.ts +33 -0
  78. package/src/types.ts +50 -0
  79. package/src/ws/connections.ts +23 -0
  80. package/src/ws/events.ts +6 -0
  81. package/src/ws/index.ts +7 -0
  82. package/src/ws/notify.ts +9 -0
package/src/config.ts ADDED
@@ -0,0 +1,155 @@
1
+ import type { UIMessage } from "ai";
2
+ import type { DatabaseAdapter } from "./adapters/database";
3
+ import type { StorageAdapter } from "./adapters/storage";
4
+ import type { DomainDef } from "./graph/types.ts";
5
+
6
+ export type KnowledgeConfig = {
7
+ swagger?: { url: string };
8
+ domains?: Record<string, DomainDef>;
9
+ };
10
+
11
+ export type DatabaseConfig = {
12
+ type: "mssql";
13
+ connectionString: string;
14
+ };
15
+
16
+ export type StorageConfig = {
17
+ endPoint: string;
18
+ port: number;
19
+ useSSL: boolean;
20
+ accessKey: string;
21
+ secretKey: string;
22
+ bucketName?: string;
23
+ };
24
+
25
+ export type CortexAgentDefinition = {
26
+ systemPrompt:
27
+ | string
28
+ | ((session: Record<string, unknown> | null) => string | Promise<string>);
29
+ tools?: Record<string, unknown>;
30
+ backendFetch?: {
31
+ baseUrl: string;
32
+ apiKey: string;
33
+ headers?: Record<string, string>;
34
+ transformRequestBody?: (
35
+ body: Record<string, unknown>,
36
+ context: { token: string },
37
+ ) => Promise<Record<string, unknown>>;
38
+ };
39
+ loadSessionData?: (token: string) => Promise<Record<string, unknown>>;
40
+ onToolCall?: (toolCall: {
41
+ toolName: string;
42
+ toolCallId: string;
43
+ args: Record<string, unknown>;
44
+ }) => void;
45
+ onStreamFinish?: (result: {
46
+ messages: UIMessage[];
47
+ isAborted: boolean;
48
+ }) => void;
49
+ model?: {
50
+ baseURL: string;
51
+ apiKey: string;
52
+ modelName: string;
53
+ providerName?: string;
54
+ };
55
+ embedding?: {
56
+ baseURL: string;
57
+ apiKey: string;
58
+ modelName: string;
59
+ dimension: number;
60
+ };
61
+ neo4j?: {
62
+ url: string;
63
+ user: string;
64
+ password: string;
65
+ };
66
+ reranker?: {
67
+ url: string;
68
+ apiKey: string;
69
+ };
70
+ knowledge?: KnowledgeConfig | null;
71
+ };
72
+
73
+ export type ResolvedCortexAgentConfig = {
74
+ db: DatabaseAdapter;
75
+ storage: StorageAdapter;
76
+ model: {
77
+ baseURL: string;
78
+ apiKey: string;
79
+ modelName: string;
80
+ providerName?: string;
81
+ };
82
+ embedding: {
83
+ baseURL: string;
84
+ apiKey: string;
85
+ modelName: string;
86
+ dimension: number;
87
+ };
88
+ neo4j: {
89
+ url: string;
90
+ user: string;
91
+ password: string;
92
+ };
93
+ reranker?: {
94
+ url: string;
95
+ apiKey: string;
96
+ };
97
+ systemPrompt:
98
+ | string
99
+ | ((session: Record<string, unknown> | null) => string | Promise<string>);
100
+ tools?: Record<string, unknown>;
101
+ backendFetch?: {
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
+ };
110
+ loadSessionData?: (token: string) => Promise<Record<string, unknown>>;
111
+ onToolCall?: (toolCall: {
112
+ toolName: string;
113
+ toolCallId: string;
114
+ args: Record<string, unknown>;
115
+ }) => void;
116
+ onStreamFinish?: (result: {
117
+ messages: UIMessage[];
118
+ isAborted: boolean;
119
+ }) => void;
120
+ knowledge?: KnowledgeConfig;
121
+ };
122
+
123
+ export type CortexConfig = {
124
+ database: DatabaseConfig;
125
+ storage: StorageConfig;
126
+ auth: {
127
+ jwksUri: string;
128
+ issuer: string;
129
+ tokenExtractor?: (req: Request) => string | null;
130
+ cookieName?: string;
131
+ };
132
+ model: {
133
+ baseURL: string;
134
+ apiKey: string;
135
+ modelName: string;
136
+ providerName?: string;
137
+ };
138
+ embedding: {
139
+ baseURL: string;
140
+ apiKey: string;
141
+ modelName: string;
142
+ dimension: number;
143
+ };
144
+ neo4j: {
145
+ url: string;
146
+ user: string;
147
+ password: string;
148
+ };
149
+ reranker?: {
150
+ url: string;
151
+ apiKey: string;
152
+ };
153
+ knowledge?: KnowledgeConfig;
154
+ agents: Record<string, CortexAgentDefinition>;
155
+ };
@@ -0,0 +1,21 @@
1
+ import mssql from "mssql";
2
+ import { drizzle } from "drizzle-orm/node-mssql";
3
+ import { migrate } from "drizzle-orm/node-mssql/migrator";
4
+ import { resolve } from "path";
5
+
6
+ export async function runMigrations(connectionString: string) {
7
+ const pool = new mssql.ConnectionPool(connectionString);
8
+ await pool.connect();
9
+
10
+ try {
11
+ const db = drizzle({ client: pool, casing: "snake_case" });
12
+ const migrationsFolder = resolve(import.meta.dir, "migrations");
13
+ console.log("[cortex-server] Running migrations from:", migrationsFolder);
14
+ await migrate(db, { migrationsFolder });
15
+ console.log("[cortex-server] Migrations complete");
16
+ } catch (e) {
17
+ console.log(e);
18
+ } finally {
19
+ await pool.close();
20
+ }
21
+ }
@@ -0,0 +1,36 @@
1
+ CREATE SCHEMA [ai];
2
+ --> statement-breakpoint
3
+ CREATE TABLE [ai].[captured_files] (
4
+ [id] UNIQUEIDENTIFIER CONSTRAINT [captured_files_id_default] DEFAULT (NEWID()),
5
+ [name] nvarchar(2048) NOT NULL,
6
+ [user_id] UNIQUEIDENTIFIER NOT NULL,
7
+ [agent_generated_id] nvarchar(1024) NOT NULL,
8
+ [message_id] nvarchar(128) NOT NULL,
9
+ [tool_part] nvarchar(max) NOT NULL,
10
+ CONSTRAINT [captured_files_pkey] PRIMARY KEY([id])
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE TABLE [ai].[messages] (
14
+ [id] nvarchar(128),
15
+ [thread_id] UNIQUEIDENTIFIER NOT NULL,
16
+ [text] nvarchar(max),
17
+ [content] nvarchar(max) NOT NULL,
18
+ [role] nvarchar(16) NOT NULL,
19
+ [created_at] datetime2 NOT NULL,
20
+ [updated_at] datetime2 NOT NULL,
21
+ CONSTRAINT [messages_pkey] PRIMARY KEY([id])
22
+ );
23
+ --> statement-breakpoint
24
+ CREATE TABLE [ai].[threads] (
25
+ [id] UNIQUEIDENTIFIER CONSTRAINT [threads_id_default] DEFAULT (NEWID()),
26
+ [user_id] UNIQUEIDENTIFIER NOT NULL,
27
+ [agent_id] nvarchar(128) NOT NULL CONSTRAINT [threads_agent_id_default] DEFAULT ('default'),
28
+ [title] nvarchar(256),
29
+ [session] nvarchar(max),
30
+ [created_at] datetime2 NOT NULL,
31
+ [updated_at] datetime2 NOT NULL,
32
+ CONSTRAINT [threads_pkey] PRIMARY KEY([id])
33
+ );
34
+ --> statement-breakpoint
35
+ 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
36
+ ALTER TABLE [ai].[messages] ADD CONSTRAINT [messages_thread_id_threads_id_fk] FOREIGN KEY ([thread_id]) REFERENCES [ai].[threads]([id]) ON DELETE CASCADE;
@@ -0,0 +1,305 @@
1
+ {
2
+ "version": "2",
3
+ "dialect": "mssql",
4
+ "id": "d92d3e1a-9613-4d7e-a224-de2dd01b2718",
5
+ "prevIds": ["00000000-0000-0000-0000-000000000000"],
6
+ "ddl": [
7
+ {
8
+ "name": "ai",
9
+ "entityType": "schemas"
10
+ },
11
+ {
12
+ "name": "captured_files",
13
+ "entityType": "tables",
14
+ "schema": "ai"
15
+ },
16
+ {
17
+ "name": "messages",
18
+ "entityType": "tables",
19
+ "schema": "ai"
20
+ },
21
+ {
22
+ "name": "threads",
23
+ "entityType": "tables",
24
+ "schema": "ai"
25
+ },
26
+ {
27
+ "type": "UNIQUEIDENTIFIER",
28
+ "notNull": true,
29
+ "generated": null,
30
+ "identity": null,
31
+ "name": "id",
32
+ "schema": "ai",
33
+ "entityType": "columns",
34
+ "table": "captured_files"
35
+ },
36
+ {
37
+ "type": "nvarchar(2048)",
38
+ "notNull": true,
39
+ "generated": null,
40
+ "identity": null,
41
+ "name": "name",
42
+ "schema": "ai",
43
+ "entityType": "columns",
44
+ "table": "captured_files"
45
+ },
46
+ {
47
+ "type": "UNIQUEIDENTIFIER",
48
+ "notNull": true,
49
+ "generated": null,
50
+ "identity": null,
51
+ "name": "user_id",
52
+ "schema": "ai",
53
+ "entityType": "columns",
54
+ "table": "captured_files"
55
+ },
56
+ {
57
+ "type": "nvarchar(1024)",
58
+ "notNull": true,
59
+ "generated": null,
60
+ "identity": null,
61
+ "name": "agent_generated_id",
62
+ "schema": "ai",
63
+ "entityType": "columns",
64
+ "table": "captured_files"
65
+ },
66
+ {
67
+ "type": "nvarchar(128)",
68
+ "notNull": true,
69
+ "generated": null,
70
+ "identity": null,
71
+ "name": "message_id",
72
+ "schema": "ai",
73
+ "entityType": "columns",
74
+ "table": "captured_files"
75
+ },
76
+ {
77
+ "type": "nvarchar(max)",
78
+ "notNull": true,
79
+ "generated": null,
80
+ "identity": null,
81
+ "name": "tool_part",
82
+ "schema": "ai",
83
+ "entityType": "columns",
84
+ "table": "captured_files"
85
+ },
86
+ {
87
+ "type": "nvarchar(128)",
88
+ "notNull": true,
89
+ "generated": null,
90
+ "identity": null,
91
+ "name": "id",
92
+ "schema": "ai",
93
+ "entityType": "columns",
94
+ "table": "messages"
95
+ },
96
+ {
97
+ "type": "UNIQUEIDENTIFIER",
98
+ "notNull": true,
99
+ "generated": null,
100
+ "identity": null,
101
+ "name": "thread_id",
102
+ "schema": "ai",
103
+ "entityType": "columns",
104
+ "table": "messages"
105
+ },
106
+ {
107
+ "type": "nvarchar(max)",
108
+ "notNull": false,
109
+ "generated": null,
110
+ "identity": null,
111
+ "name": "text",
112
+ "schema": "ai",
113
+ "entityType": "columns",
114
+ "table": "messages"
115
+ },
116
+ {
117
+ "type": "nvarchar(max)",
118
+ "notNull": true,
119
+ "generated": null,
120
+ "identity": null,
121
+ "name": "content",
122
+ "schema": "ai",
123
+ "entityType": "columns",
124
+ "table": "messages"
125
+ },
126
+ {
127
+ "type": "nvarchar(16)",
128
+ "notNull": true,
129
+ "generated": null,
130
+ "identity": null,
131
+ "name": "role",
132
+ "schema": "ai",
133
+ "entityType": "columns",
134
+ "table": "messages"
135
+ },
136
+ {
137
+ "type": "datetime2",
138
+ "notNull": true,
139
+ "generated": null,
140
+ "identity": null,
141
+ "name": "created_at",
142
+ "schema": "ai",
143
+ "entityType": "columns",
144
+ "table": "messages"
145
+ },
146
+ {
147
+ "type": "datetime2",
148
+ "notNull": true,
149
+ "generated": null,
150
+ "identity": null,
151
+ "name": "updated_at",
152
+ "schema": "ai",
153
+ "entityType": "columns",
154
+ "table": "messages"
155
+ },
156
+ {
157
+ "type": "UNIQUEIDENTIFIER",
158
+ "notNull": true,
159
+ "generated": null,
160
+ "identity": null,
161
+ "name": "id",
162
+ "schema": "ai",
163
+ "entityType": "columns",
164
+ "table": "threads"
165
+ },
166
+ {
167
+ "type": "UNIQUEIDENTIFIER",
168
+ "notNull": true,
169
+ "generated": null,
170
+ "identity": null,
171
+ "name": "user_id",
172
+ "schema": "ai",
173
+ "entityType": "columns",
174
+ "table": "threads"
175
+ },
176
+ {
177
+ "type": "nvarchar(128)",
178
+ "notNull": true,
179
+ "generated": null,
180
+ "identity": null,
181
+ "name": "agent_id",
182
+ "schema": "ai",
183
+ "entityType": "columns",
184
+ "table": "threads"
185
+ },
186
+ {
187
+ "type": "nvarchar(256)",
188
+ "notNull": false,
189
+ "generated": null,
190
+ "identity": null,
191
+ "name": "title",
192
+ "schema": "ai",
193
+ "entityType": "columns",
194
+ "table": "threads"
195
+ },
196
+ {
197
+ "type": "nvarchar(max)",
198
+ "notNull": false,
199
+ "generated": null,
200
+ "identity": null,
201
+ "name": "session",
202
+ "schema": "ai",
203
+ "entityType": "columns",
204
+ "table": "threads"
205
+ },
206
+ {
207
+ "type": "datetime2",
208
+ "notNull": true,
209
+ "generated": null,
210
+ "identity": null,
211
+ "name": "created_at",
212
+ "schema": "ai",
213
+ "entityType": "columns",
214
+ "table": "threads"
215
+ },
216
+ {
217
+ "type": "datetime2",
218
+ "notNull": true,
219
+ "generated": null,
220
+ "identity": null,
221
+ "name": "updated_at",
222
+ "schema": "ai",
223
+ "entityType": "columns",
224
+ "table": "threads"
225
+ },
226
+ {
227
+ "columns": ["message_id"],
228
+ "nameExplicit": false,
229
+ "schemaTo": "ai",
230
+ "tableTo": "messages",
231
+ "columnsTo": ["id"],
232
+ "onUpdate": "NO ACTION",
233
+ "onDelete": "CASCADE",
234
+ "name": "captured_files_message_id_messages_id_fk",
235
+ "entityType": "fks",
236
+ "table": "captured_files",
237
+ "schema": "ai"
238
+ },
239
+ {
240
+ "columns": ["thread_id"],
241
+ "nameExplicit": false,
242
+ "schemaTo": "ai",
243
+ "tableTo": "threads",
244
+ "columnsTo": ["id"],
245
+ "onUpdate": "NO ACTION",
246
+ "onDelete": "CASCADE",
247
+ "name": "messages_thread_id_threads_id_fk",
248
+ "entityType": "fks",
249
+ "table": "messages",
250
+ "schema": "ai"
251
+ },
252
+ {
253
+ "nameExplicit": false,
254
+ "columns": ["id"],
255
+ "name": "captured_files_pkey",
256
+ "table": "captured_files",
257
+ "schema": "ai",
258
+ "entityType": "pks"
259
+ },
260
+ {
261
+ "nameExplicit": false,
262
+ "columns": ["id"],
263
+ "name": "messages_pkey",
264
+ "table": "messages",
265
+ "schema": "ai",
266
+ "entityType": "pks"
267
+ },
268
+ {
269
+ "nameExplicit": false,
270
+ "columns": ["id"],
271
+ "name": "threads_pkey",
272
+ "table": "threads",
273
+ "schema": "ai",
274
+ "entityType": "pks"
275
+ },
276
+ {
277
+ "column": "id",
278
+ "nameExplicit": false,
279
+ "default": "(NEWID())",
280
+ "name": "captured_files_id_default",
281
+ "entityType": "defaults",
282
+ "schema": "ai",
283
+ "table": "captured_files"
284
+ },
285
+ {
286
+ "column": "id",
287
+ "nameExplicit": false,
288
+ "default": "(NEWID())",
289
+ "name": "threads_id_default",
290
+ "entityType": "defaults",
291
+ "schema": "ai",
292
+ "table": "threads"
293
+ },
294
+ {
295
+ "column": "agent_id",
296
+ "nameExplicit": false,
297
+ "default": "('default')",
298
+ "name": "threads_agent_id_default",
299
+ "entityType": "defaults",
300
+ "schema": "ai",
301
+ "table": "threads"
302
+ }
303
+ ],
304
+ "renames": []
305
+ }
@@ -0,0 +1,77 @@
1
+ import type { ToolUIPart, UIMessage } from "ai";
2
+ import { sql } from "drizzle-orm";
3
+ import {
4
+ customType,
5
+ datetime2,
6
+ index,
7
+ mssqlSchema,
8
+ nvarchar,
9
+ } from "drizzle-orm/mssql-core";
10
+
11
+ const uniqueIdentifier = customType<{ data: string }>({
12
+ dataType() {
13
+ return "UNIQUEIDENTIFIER";
14
+ },
15
+ });
16
+
17
+ export const aiSchema = mssqlSchema("ai");
18
+
19
+ const auditColumns = {
20
+ createdAt: datetime2({ mode: "date" })
21
+ .$default(() => new Date())
22
+ .notNull(),
23
+ updatedAt: datetime2({ mode: "date" })
24
+ .$default(() => new Date())
25
+ .$onUpdate(() => new Date())
26
+ .notNull(),
27
+ };
28
+
29
+ export const threads = aiSchema.table("threads", {
30
+ id: uniqueIdentifier()
31
+ .default(sql`NEWID()`)
32
+ .primaryKey(),
33
+ userId: uniqueIdentifier().notNull(),
34
+ agentId: nvarchar({ length: 128 }).notNull().default("default"),
35
+ title: nvarchar({ length: 256 }),
36
+ session: nvarchar({ mode: "json", length: "max" }).$type<
37
+ Record<string, unknown>
38
+ >(),
39
+ ...auditColumns,
40
+ });
41
+
42
+ export const messages = aiSchema.table("messages", {
43
+ id: nvarchar({ length: 128 }).primaryKey(),
44
+ threadId: uniqueIdentifier()
45
+ .references(() => threads.id, { onDelete: "cascade" })
46
+ .notNull(),
47
+ text: nvarchar({ length: "max" }),
48
+ content: nvarchar({ mode: "json", length: "max" })
49
+ .notNull()
50
+ .$type<UIMessage>(),
51
+ role: nvarchar({
52
+ enum: ["system", "user", "assistant", "tool"],
53
+ length: 16,
54
+ }).notNull(),
55
+ ...auditColumns,
56
+ });
57
+
58
+ export const capturedFiles = aiSchema.table(
59
+ "captured_files",
60
+ {
61
+ id: uniqueIdentifier()
62
+ .default(sql`NEWID()`)
63
+ .primaryKey(),
64
+ name: nvarchar({ length: 2048 }).notNull(),
65
+ userId: uniqueIdentifier().notNull(),
66
+ agentGeneratedId: nvarchar({ length: 1024 }).notNull(),
67
+ messageId: nvarchar({ length: 128 })
68
+ .references(() => messages.id, {
69
+ onDelete: "cascade",
70
+ })
71
+ .notNull(),
72
+ toolPart: nvarchar({ length: "max", mode: "json" })
73
+ .notNull()
74
+ .$type<ToolUIPart>(),
75
+ },
76
+ (table) => [index(table.agentGeneratedId)],
77
+ );