@m6d/cortex-server 2.3.0 → 2.5.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 (62) hide show
  1. package/contracts/src/runtime/index.ts +99 -3
  2. package/dist/contracts/src/graph/helpers.d.ts +5 -5
  3. package/dist/contracts/src/runtime/index.d.ts +175 -3
  4. package/dist/src/lib/adapters/database/index.d.ts +20 -2
  5. package/dist/src/lib/adapters/database/mssql/attachments.d.ts +9 -9
  6. package/dist/src/lib/adapters/database/mssql/index.d.ts +133 -28
  7. package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +3 -2
  8. package/dist/src/lib/adapters/database/mssql/messages.d.ts +6 -5
  9. package/dist/src/lib/adapters/database/mssql/outbox.d.ts +103 -0
  10. package/dist/src/lib/adapters/database/mssql/threads.d.ts +21 -14
  11. package/dist/src/lib/adapters/database/postgres/attachments.d.ts +9 -9
  12. package/dist/src/lib/adapters/database/postgres/index.d.ts +133 -28
  13. package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +3 -2
  14. package/dist/src/lib/adapters/database/postgres/messages.d.ts +6 -5
  15. package/dist/src/lib/adapters/database/postgres/outbox.d.ts +103 -0
  16. package/dist/src/lib/adapters/database/postgres/threads.d.ts +21 -14
  17. package/dist/src/lib/ai/attachments.d.ts +2 -2
  18. package/dist/src/lib/ai/client-tools.d.ts +1 -1
  19. package/dist/src/lib/auth/middleware.d.ts +2 -2
  20. package/dist/src/lib/auth/playground.d.ts +14 -0
  21. package/dist/src/lib/cc/client.d.ts +9 -1
  22. package/dist/src/lib/cc/flusher.d.ts +40 -0
  23. package/dist/src/lib/cc/sync-events.d.ts +45 -0
  24. package/dist/src/lib/cc/types.d.ts +1 -1
  25. package/dist/src/lib/config.d.ts +11 -0
  26. package/dist/src/lib/db/schema.mssql.d.ts +161 -0
  27. package/dist/src/lib/db/schema.pg.d.ts +199 -0
  28. package/dist/src/lib/factory.d.ts +3 -0
  29. package/dist/src/lib/routes/owned-thread.d.ts +5 -4
  30. package/package.json +2 -2
  31. package/src/lib/adapters/database/index.ts +15 -1
  32. package/src/lib/adapters/database/mssql/index.ts +13 -4
  33. package/src/lib/adapters/database/mssql/llm-requests.ts +35 -15
  34. package/src/lib/adapters/database/mssql/messages.ts +81 -30
  35. package/src/lib/adapters/database/mssql/outbox.ts +71 -0
  36. package/src/lib/adapters/database/mssql/threads.ts +42 -11
  37. package/src/lib/adapters/database/postgres/index.ts +13 -4
  38. package/src/lib/adapters/database/postgres/llm-requests.ts +35 -15
  39. package/src/lib/adapters/database/postgres/messages.ts +81 -30
  40. package/src/lib/adapters/database/postgres/outbox.ts +66 -0
  41. package/src/lib/adapters/database/postgres/threads.ts +39 -11
  42. package/src/lib/ai/finish-turn.ts +3 -1
  43. package/src/lib/ai/prompt.ts +3 -1
  44. package/src/lib/auth/middleware.ts +34 -8
  45. package/src/lib/auth/playground.ts +72 -0
  46. package/src/lib/cc/client.ts +21 -1
  47. package/src/lib/cc/flusher.ts +147 -0
  48. package/src/lib/cc/sync-events.ts +65 -0
  49. package/src/lib/cc/types.ts +3 -0
  50. package/src/lib/config.ts +11 -0
  51. package/src/lib/db/migrations/mssql/20260829050547_friendly_red_shift/migration.sql +8 -0
  52. package/src/lib/db/migrations/mssql/20260829050547_friendly_red_shift/snapshot.json +581 -0
  53. package/src/lib/db/migrations/mssql/20260830022424_easy_nicolaos/migration.sql +5 -0
  54. package/src/lib/db/migrations/mssql/20260830022424_easy_nicolaos/snapshot.json +614 -0
  55. package/src/lib/db/migrations/pg/20260829050547_perfect_wildside/migration.sql +7 -0
  56. package/src/lib/db/migrations/pg/20260829050547_perfect_wildside/snapshot.json +650 -0
  57. package/src/lib/db/migrations/pg/20260830022424_serious_deadpool/migration.sql +4 -0
  58. package/src/lib/db/migrations/pg/20260830022424_serious_deadpool/snapshot.json +690 -0
  59. package/src/lib/db/schema.mssql.ts +32 -1
  60. package/src/lib/db/schema.pg.ts +24 -0
  61. package/src/lib/factory.ts +22 -8
  62. package/src/lib/routes/threads.ts +5 -1
@@ -4,7 +4,9 @@ import type { StorageAdapter } from "../../../adapters/storage/index";
4
4
  * only threads takes storage, because deleting a thread is the one operation
5
5
  * that also has to reach into object storage.
6
6
  */
7
- export declare function createMssqlAdapter(connectionString: string, storage?: StorageAdapter): {
7
+ export declare function createMssqlAdapter(connectionString: string, storage?: StorageAdapter, options?: {
8
+ syncMirror?: boolean;
9
+ }): {
8
10
  threads: {
9
11
  list(userId: string, agentId: string): Promise<{
10
12
  createdAt: Date;
@@ -13,39 +15,45 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
13
15
  userId: string;
14
16
  agentId: string;
15
17
  title: string | null;
18
+ isTest: boolean;
16
19
  session: Record<string, unknown> | null;
17
20
  contextMeta: import("../../..").ThreadContextMeta | null;
18
21
  }[]>;
19
22
  getById(userId: string, threadId: string): Promise<{
20
- id: string;
21
- userId: string;
22
23
  agentId: string;
24
+ userId: string;
25
+ id: string;
23
26
  title: string | null;
24
- session: Record<string, unknown> | null;
25
- contextMeta: import("../../..").ThreadContextMeta | null;
27
+ isTest: boolean;
26
28
  createdAt: Date;
27
29
  updatedAt: Date;
30
+ session: Record<string, unknown> | null;
31
+ contextMeta: import("../../..").ThreadContextMeta | null;
28
32
  } | null>;
29
- create(userId: string, agentId: string): Promise<{
30
- id: string;
31
- userId: string;
33
+ create(userId: string, agentId: string, options: {
34
+ isTest?: boolean;
35
+ } | undefined): Promise<{
32
36
  agentId: string;
37
+ userId: string;
38
+ id: string;
33
39
  title: string | null;
34
- session: Record<string, unknown> | null;
35
- contextMeta: import("../../..").ThreadContextMeta | null;
40
+ isTest: boolean;
36
41
  createdAt: Date;
37
42
  updatedAt: Date;
43
+ session: Record<string, unknown> | null;
44
+ contextMeta: import("../../..").ThreadContextMeta | null;
38
45
  }>;
39
46
  delete(userId: string, threadId: string): Promise<void>;
40
47
  touch(threadId: string): Promise<{
41
- id: string;
42
- userId: string;
43
48
  agentId: string;
49
+ userId: string;
50
+ id: string;
44
51
  title: string | null;
45
- session: Record<string, unknown> | null;
46
- contextMeta: import("../../..").ThreadContextMeta | null;
52
+ isTest: boolean;
47
53
  createdAt: Date;
48
54
  updatedAt: Date;
55
+ session: Record<string, unknown> | null;
56
+ contextMeta: import("../../..").ThreadContextMeta | null;
49
57
  }>;
50
58
  updateTitle(threadId: string, title: string): Promise<void>;
51
59
  updateSession(threadId: string, session: Record<string, unknown>): Promise<void>;
@@ -55,14 +63,14 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
55
63
  list(userId: string, threadId: string, opts: {
56
64
  limit?: number;
57
65
  } | undefined): Promise<{
58
- id: string;
59
66
  text: string | null;
67
+ threadId: string;
68
+ id: string;
60
69
  createdAt: Date;
61
70
  updatedAt: Date;
62
- threadId: string;
63
- content: import("../../../types").ChatMessage;
64
- ordinal: number;
65
71
  role: "system" | "user" | "assistant" | "tool";
72
+ ordinal: number;
73
+ content: import("../../../types").ChatMessage;
66
74
  }[] | {
67
75
  createdAt: Date;
68
76
  updatedAt: Date;
@@ -78,7 +86,7 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
78
86
  }): Promise<void>;
79
87
  };
80
88
  llmRequests: {
81
- insert(requests: {
89
+ insert(threadId: string, requests: {
82
90
  messageId: string;
83
91
  stepNumber: number;
84
92
  prompt: string;
@@ -94,8 +102,8 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
94
102
  };
95
103
  attachments: {
96
104
  createPending(row: {
97
- userId: string;
98
105
  threadId: string;
106
+ userId: string;
99
107
  filename: string;
100
108
  contentType: string;
101
109
  sizeBytes: number;
@@ -107,11 +115,11 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
107
115
  messageId?: string | null | undefined;
108
116
  description?: string | null | undefined;
109
117
  }, limit: number): Promise<{
110
- id: string;
118
+ threadId: string;
111
119
  userId: string;
120
+ id: string;
112
121
  createdAt: Date;
113
122
  updatedAt: Date;
114
- threadId: string;
115
123
  messageId: string | null;
116
124
  filename: string;
117
125
  contentType: string;
@@ -121,11 +129,11 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
121
129
  description: string | null;
122
130
  } | undefined>;
123
131
  getById(id: string, userId: string): Promise<{
124
- id: string;
132
+ threadId: string;
125
133
  userId: string;
134
+ id: string;
126
135
  createdAt: Date;
127
136
  updatedAt: Date;
128
- threadId: string;
129
137
  messageId: string | null;
130
138
  filename: string;
131
139
  contentType: string;
@@ -162,11 +170,11 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
162
170
  description: string | null;
163
171
  }[]>;
164
172
  claimForMessage(threadId: string, userId: string, messageId: string): Promise<{
165
- id: string;
173
+ threadId: string;
166
174
  userId: string;
175
+ id: string;
167
176
  createdAt: Date;
168
177
  updatedAt: Date;
169
- threadId: string;
170
178
  messageId: string | null;
171
179
  filename: string;
172
180
  contentType: string;
@@ -177,11 +185,11 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
177
185
  }[]>;
178
186
  setDescription(id: string, userId: string, status: "pending" | "described" | "failed" | "skipped", description: string | undefined): Promise<void>;
179
187
  remove(id: string, userId: string): Promise<{
180
- id: string;
188
+ threadId: string;
181
189
  userId: string;
190
+ id: string;
182
191
  createdAt: Date;
183
192
  updatedAt: Date;
184
- threadId: string;
185
193
  messageId: string | null;
186
194
  filename: string;
187
195
  contentType: string;
@@ -191,4 +199,101 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
191
199
  description: string | null;
192
200
  } | undefined>;
193
201
  };
202
+ outbox: {
203
+ enqueue: (events: ({
204
+ type: "thread.upsert";
205
+ id: string;
206
+ agentSlug: string;
207
+ userId: string;
208
+ title: string | null;
209
+ isTest: boolean;
210
+ createdAt: string;
211
+ updatedAt: string;
212
+ } | {
213
+ type: "thread.delete";
214
+ id: string;
215
+ } | {
216
+ type: "message.upsert";
217
+ id: string;
218
+ threadId: string;
219
+ role: "system" | "user" | "assistant" | "tool";
220
+ text: string | null;
221
+ ordinal: number;
222
+ content: {
223
+ [x: string]: unknown;
224
+ };
225
+ createdAt: string;
226
+ } | {
227
+ type: "usage.record";
228
+ id: string;
229
+ messageId: string;
230
+ threadId: string;
231
+ stepNumber: number;
232
+ tokenUsage: {
233
+ input: {
234
+ noCache: number;
235
+ cacheRead: number;
236
+ cacheWrite: number;
237
+ total: number;
238
+ };
239
+ output: {
240
+ reasoning: number;
241
+ text: number;
242
+ total: number;
243
+ };
244
+ total: number;
245
+ };
246
+ createdAt: string;
247
+ })[]) => Promise<void>;
248
+ peek(limit: number): Promise<{
249
+ id: number;
250
+ event: {
251
+ type: "thread.upsert";
252
+ id: string;
253
+ agentSlug: string;
254
+ userId: string;
255
+ title: string | null;
256
+ isTest: boolean;
257
+ createdAt: string;
258
+ updatedAt: string;
259
+ } | {
260
+ type: "thread.delete";
261
+ id: string;
262
+ } | {
263
+ type: "message.upsert";
264
+ id: string;
265
+ threadId: string;
266
+ role: "system" | "user" | "assistant" | "tool";
267
+ text: string | null;
268
+ ordinal: number;
269
+ content: {
270
+ [x: string]: unknown;
271
+ };
272
+ createdAt: string;
273
+ } | {
274
+ type: "usage.record";
275
+ id: string;
276
+ messageId: string;
277
+ threadId: string;
278
+ stepNumber: number;
279
+ tokenUsage: {
280
+ input: {
281
+ noCache: number;
282
+ cacheRead: number;
283
+ cacheWrite: number;
284
+ total: number;
285
+ };
286
+ output: {
287
+ reasoning: number;
288
+ text: number;
289
+ total: number;
290
+ };
291
+ total: number;
292
+ };
293
+ createdAt: string;
294
+ };
295
+ }[]>;
296
+ epoch(): Promise<string>;
297
+ ack(ids: number[]): Promise<void>;
298
+ };
194
299
  };
@@ -1,6 +1,7 @@
1
1
  import type { MssqlDb } from "./client";
2
- export declare function createLlmRequestsRepository(db: MssqlDb): {
3
- insert(requests: {
2
+ import { enqueueSyncEvents } from "./outbox";
3
+ export declare function createLlmRequestsRepository(db: MssqlDb, enqueue?: typeof enqueueSyncEvents): {
4
+ insert(threadId: string, requests: {
4
5
  messageId: string;
5
6
  stepNumber: number;
6
7
  prompt: string;
@@ -1,6 +1,7 @@
1
1
  import type { ChatMessage } from "../../../types";
2
2
  import type { MssqlDb } from "./client";
3
- export declare function createMessagesRepository(db: MssqlDb): {
3
+ import { enqueueSyncEvents } from "./outbox";
4
+ export declare function createMessagesRepository(db: MssqlDb, enqueue?: typeof enqueueSyncEvents): {
4
5
  /**
5
6
  * Fetches the newest N and reverses, so a limit keeps the most recent
6
7
  * messages while callers still receive them oldest-first.
@@ -8,14 +9,14 @@ export declare function createMessagesRepository(db: MssqlDb): {
8
9
  list(userId: string, threadId: string, opts: {
9
10
  limit?: number;
10
11
  } | undefined): Promise<{
11
- id: string;
12
12
  text: string | null;
13
+ threadId: string;
14
+ id: string;
13
15
  createdAt: Date;
14
16
  updatedAt: Date;
15
- threadId: string;
16
- content: ChatMessage;
17
- ordinal: number;
18
17
  role: "system" | "user" | "assistant" | "tool";
18
+ ordinal: number;
19
+ content: ChatMessage;
19
20
  }[] | {
20
21
  createdAt: Date;
21
22
  updatedAt: Date;
@@ -0,0 +1,103 @@
1
+ import type { SyncEvent } from "../../../../../contracts/src/runtime";
2
+ import type { MssqlDb } from "./client";
3
+ /** A db or one of its transactions, so a write and its events commit together. */
4
+ type Executor = Pick<MssqlDb, "insert">;
5
+ export declare function enqueueSyncEvents(executor: Executor, events: SyncEvent[]): Promise<void>;
6
+ export declare function createOutboxRepository(db: MssqlDb): {
7
+ enqueue: (events: ({
8
+ type: "thread.upsert";
9
+ id: string;
10
+ agentSlug: string;
11
+ userId: string;
12
+ title: string | null;
13
+ isTest: boolean;
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ } | {
17
+ type: "thread.delete";
18
+ id: string;
19
+ } | {
20
+ type: "message.upsert";
21
+ id: string;
22
+ threadId: string;
23
+ role: "system" | "user" | "assistant" | "tool";
24
+ text: string | null;
25
+ ordinal: number;
26
+ content: {
27
+ [x: string]: unknown;
28
+ };
29
+ createdAt: string;
30
+ } | {
31
+ type: "usage.record";
32
+ id: string;
33
+ messageId: string;
34
+ threadId: string;
35
+ stepNumber: number;
36
+ tokenUsage: {
37
+ input: {
38
+ noCache: number;
39
+ cacheRead: number;
40
+ cacheWrite: number;
41
+ total: number;
42
+ };
43
+ output: {
44
+ reasoning: number;
45
+ text: number;
46
+ total: number;
47
+ };
48
+ total: number;
49
+ };
50
+ createdAt: string;
51
+ })[]) => Promise<void>;
52
+ peek(limit: number): Promise<{
53
+ id: number;
54
+ event: {
55
+ type: "thread.upsert";
56
+ id: string;
57
+ agentSlug: string;
58
+ userId: string;
59
+ title: string | null;
60
+ isTest: boolean;
61
+ createdAt: string;
62
+ updatedAt: string;
63
+ } | {
64
+ type: "thread.delete";
65
+ id: string;
66
+ } | {
67
+ type: "message.upsert";
68
+ id: string;
69
+ threadId: string;
70
+ role: "system" | "user" | "assistant" | "tool";
71
+ text: string | null;
72
+ ordinal: number;
73
+ content: {
74
+ [x: string]: unknown;
75
+ };
76
+ createdAt: string;
77
+ } | {
78
+ type: "usage.record";
79
+ id: string;
80
+ messageId: string;
81
+ threadId: string;
82
+ stepNumber: number;
83
+ tokenUsage: {
84
+ input: {
85
+ noCache: number;
86
+ cacheRead: number;
87
+ cacheWrite: number;
88
+ total: number;
89
+ };
90
+ output: {
91
+ reasoning: number;
92
+ text: number;
93
+ total: number;
94
+ };
95
+ total: number;
96
+ };
97
+ createdAt: string;
98
+ };
99
+ }[]>;
100
+ epoch(): Promise<string>;
101
+ ack(ids: number[]): Promise<void>;
102
+ };
103
+ export {};
@@ -1,7 +1,8 @@
1
1
  import type { ThreadContextMeta } from "../../../ai/context/types";
2
2
  import type { MssqlDb } from "./client";
3
+ import { enqueueSyncEvents } from "./outbox";
3
4
  import type { StorageAdapter } from "../../../adapters/storage/index";
4
- export declare function createThreadsRepository(db: MssqlDb, storage?: StorageAdapter): {
5
+ export declare function createThreadsRepository(db: MssqlDb, storage?: StorageAdapter, enqueue?: typeof enqueueSyncEvents): {
5
6
  list(userId: string, agentId: string): Promise<{
6
7
  createdAt: Date;
7
8
  updatedAt: Date;
@@ -9,40 +10,46 @@ export declare function createThreadsRepository(db: MssqlDb, storage?: StorageAd
9
10
  userId: string;
10
11
  agentId: string;
11
12
  title: string | null;
13
+ isTest: boolean;
12
14
  session: Record<string, unknown> | null;
13
15
  contextMeta: ThreadContextMeta | null;
14
16
  }[]>;
15
17
  getById(userId: string, threadId: string): Promise<{
16
- id: string;
17
- userId: string;
18
18
  agentId: string;
19
+ userId: string;
20
+ id: string;
19
21
  title: string | null;
20
- session: Record<string, unknown> | null;
21
- contextMeta: ThreadContextMeta | null;
22
+ isTest: boolean;
22
23
  createdAt: Date;
23
24
  updatedAt: Date;
25
+ session: Record<string, unknown> | null;
26
+ contextMeta: ThreadContextMeta | null;
24
27
  } | null>;
25
- create(userId: string, agentId: string): Promise<{
26
- id: string;
27
- userId: string;
28
+ create(userId: string, agentId: string, options: {
29
+ isTest?: boolean;
30
+ } | undefined): Promise<{
28
31
  agentId: string;
32
+ userId: string;
33
+ id: string;
29
34
  title: string | null;
30
- session: Record<string, unknown> | null;
31
- contextMeta: ThreadContextMeta | null;
35
+ isTest: boolean;
32
36
  createdAt: Date;
33
37
  updatedAt: Date;
38
+ session: Record<string, unknown> | null;
39
+ contextMeta: ThreadContextMeta | null;
34
40
  }>;
35
41
  /** Object storage has no foreign keys, so attachment paths must be swept before row cascade. */
36
42
  delete(userId: string, threadId: string): Promise<void>;
37
43
  touch(threadId: string): Promise<{
38
- id: string;
39
- userId: string;
40
44
  agentId: string;
45
+ userId: string;
46
+ id: string;
41
47
  title: string | null;
42
- session: Record<string, unknown> | null;
43
- contextMeta: ThreadContextMeta | null;
48
+ isTest: boolean;
44
49
  createdAt: Date;
45
50
  updatedAt: Date;
51
+ session: Record<string, unknown> | null;
52
+ contextMeta: ThreadContextMeta | null;
46
53
  }>;
47
54
  updateTitle(threadId: string, title: string): Promise<void>;
48
55
  updateSession(threadId: string, session: Record<string, unknown>): Promise<void>;
@@ -1,8 +1,8 @@
1
1
  import type { PostgresDb } from "./client";
2
2
  export declare function createAttachmentsRepository(db: PostgresDb): {
3
3
  createPending(row: {
4
- userId: string;
5
4
  threadId: string;
5
+ userId: string;
6
6
  filename: string;
7
7
  contentType: string;
8
8
  sizeBytes: number;
@@ -14,11 +14,11 @@ export declare function createAttachmentsRepository(db: PostgresDb): {
14
14
  messageId?: string | null | undefined;
15
15
  description?: string | null | undefined;
16
16
  }, limit: number): Promise<{
17
- id: string;
17
+ threadId: string;
18
18
  userId: string;
19
+ id: string;
19
20
  createdAt: Date;
20
21
  updatedAt: Date;
21
- threadId: string;
22
22
  messageId: string | null;
23
23
  filename: string;
24
24
  contentType: string;
@@ -28,11 +28,11 @@ export declare function createAttachmentsRepository(db: PostgresDb): {
28
28
  description: string | null;
29
29
  } | undefined>;
30
30
  getById(id: string, userId: string): Promise<{
31
- id: string;
31
+ threadId: string;
32
32
  userId: string;
33
+ id: string;
33
34
  createdAt: Date;
34
35
  updatedAt: Date;
35
- threadId: string;
36
36
  messageId: string | null;
37
37
  filename: string;
38
38
  contentType: string;
@@ -84,11 +84,11 @@ export declare function createAttachmentsRepository(db: PostgresDb): {
84
84
  }[]>;
85
85
  setDescription(id: string, userId: string, status: "pending" | "described" | "failed" | "skipped", description: string | undefined): Promise<void>;
86
86
  remove(id: string, userId: string): Promise<{
87
- id: string;
87
+ threadId: string;
88
88
  userId: string;
89
+ id: string;
89
90
  createdAt: Date;
90
91
  updatedAt: Date;
91
- threadId: string;
92
92
  messageId: string | null;
93
93
  filename: string;
94
94
  contentType: string;
@@ -97,11 +97,11 @@ export declare function createAttachmentsRepository(db: PostgresDb): {
97
97
  status: "pending" | "described" | "failed" | "skipped";
98
98
  description: string | null;
99
99
  } | {
100
- id: string;
100
+ threadId: string;
101
101
  userId: string;
102
+ id: string;
102
103
  createdAt: Date;
103
104
  updatedAt: Date;
104
- threadId: string;
105
105
  messageId: string | null;
106
106
  filename: string;
107
107
  contentType: string;