@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.
- package/contracts/src/runtime/index.ts +99 -3
- package/dist/contracts/src/graph/helpers.d.ts +5 -5
- package/dist/contracts/src/runtime/index.d.ts +175 -3
- package/dist/src/lib/adapters/database/index.d.ts +20 -2
- package/dist/src/lib/adapters/database/mssql/attachments.d.ts +9 -9
- package/dist/src/lib/adapters/database/mssql/index.d.ts +133 -28
- package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +3 -2
- package/dist/src/lib/adapters/database/mssql/messages.d.ts +6 -5
- package/dist/src/lib/adapters/database/mssql/outbox.d.ts +103 -0
- package/dist/src/lib/adapters/database/mssql/threads.d.ts +21 -14
- package/dist/src/lib/adapters/database/postgres/attachments.d.ts +9 -9
- package/dist/src/lib/adapters/database/postgres/index.d.ts +133 -28
- package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +3 -2
- package/dist/src/lib/adapters/database/postgres/messages.d.ts +6 -5
- package/dist/src/lib/adapters/database/postgres/outbox.d.ts +103 -0
- package/dist/src/lib/adapters/database/postgres/threads.d.ts +21 -14
- package/dist/src/lib/ai/attachments.d.ts +2 -2
- package/dist/src/lib/ai/client-tools.d.ts +1 -1
- package/dist/src/lib/auth/middleware.d.ts +2 -2
- package/dist/src/lib/auth/playground.d.ts +14 -0
- package/dist/src/lib/cc/client.d.ts +9 -1
- package/dist/src/lib/cc/flusher.d.ts +40 -0
- package/dist/src/lib/cc/sync-events.d.ts +45 -0
- package/dist/src/lib/cc/types.d.ts +1 -1
- package/dist/src/lib/config.d.ts +11 -0
- package/dist/src/lib/db/schema.mssql.d.ts +161 -0
- package/dist/src/lib/db/schema.pg.d.ts +199 -0
- package/dist/src/lib/factory.d.ts +3 -0
- package/dist/src/lib/routes/owned-thread.d.ts +5 -4
- package/package.json +2 -2
- package/src/lib/adapters/database/index.ts +15 -1
- package/src/lib/adapters/database/mssql/index.ts +13 -4
- package/src/lib/adapters/database/mssql/llm-requests.ts +35 -15
- package/src/lib/adapters/database/mssql/messages.ts +81 -30
- package/src/lib/adapters/database/mssql/outbox.ts +71 -0
- package/src/lib/adapters/database/mssql/threads.ts +42 -11
- package/src/lib/adapters/database/postgres/index.ts +13 -4
- package/src/lib/adapters/database/postgres/llm-requests.ts +35 -15
- package/src/lib/adapters/database/postgres/messages.ts +81 -30
- package/src/lib/adapters/database/postgres/outbox.ts +66 -0
- package/src/lib/adapters/database/postgres/threads.ts +39 -11
- package/src/lib/ai/finish-turn.ts +3 -1
- package/src/lib/ai/prompt.ts +3 -1
- package/src/lib/auth/middleware.ts +34 -8
- package/src/lib/auth/playground.ts +72 -0
- package/src/lib/cc/client.ts +21 -1
- package/src/lib/cc/flusher.ts +147 -0
- package/src/lib/cc/sync-events.ts +65 -0
- package/src/lib/cc/types.ts +3 -0
- package/src/lib/config.ts +11 -0
- package/src/lib/db/migrations/mssql/20260829050547_friendly_red_shift/migration.sql +8 -0
- package/src/lib/db/migrations/mssql/20260829050547_friendly_red_shift/snapshot.json +581 -0
- package/src/lib/db/migrations/mssql/20260830022424_easy_nicolaos/migration.sql +5 -0
- package/src/lib/db/migrations/mssql/20260830022424_easy_nicolaos/snapshot.json +614 -0
- package/src/lib/db/migrations/pg/20260829050547_perfect_wildside/migration.sql +7 -0
- package/src/lib/db/migrations/pg/20260829050547_perfect_wildside/snapshot.json +650 -0
- package/src/lib/db/migrations/pg/20260830022424_serious_deadpool/migration.sql +4 -0
- package/src/lib/db/migrations/pg/20260830022424_serious_deadpool/snapshot.json +690 -0
- package/src/lib/db/schema.mssql.ts +32 -1
- package/src/lib/db/schema.pg.ts +24 -0
- package/src/lib/factory.ts +22 -8
- package/src/lib/routes/threads.ts +5 -1
|
@@ -101,6 +101,22 @@ export declare const threads: import("drizzle-orm/mssql-core").MsSqlTableWithCol
|
|
|
101
101
|
identity: undefined;
|
|
102
102
|
generated: undefined;
|
|
103
103
|
}, {}>;
|
|
104
|
+
isTest: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
105
|
+
name: string;
|
|
106
|
+
tableName: "threads";
|
|
107
|
+
dataType: "boolean";
|
|
108
|
+
data: boolean;
|
|
109
|
+
driverParam: string | number;
|
|
110
|
+
notNull: true;
|
|
111
|
+
hasDefault: true;
|
|
112
|
+
isPrimaryKey: false;
|
|
113
|
+
isAutoincrement: false;
|
|
114
|
+
hasRuntimeDefault: false;
|
|
115
|
+
enumValues: undefined;
|
|
116
|
+
baseColumn: never;
|
|
117
|
+
identity: undefined;
|
|
118
|
+
generated: undefined;
|
|
119
|
+
}, {}>;
|
|
104
120
|
session: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
105
121
|
name: string;
|
|
106
122
|
tableName: "threads";
|
|
@@ -573,3 +589,148 @@ export declare const attachments: import("drizzle-orm/mssql-core").MsSqlTableWit
|
|
|
573
589
|
};
|
|
574
590
|
dialect: "mssql";
|
|
575
591
|
}>;
|
|
592
|
+
/**
|
|
593
|
+
* Events awaiting the cc sync flusher. Insertion order (the identity id) is
|
|
594
|
+
* flush order; `ack` deletes.
|
|
595
|
+
*/
|
|
596
|
+
/** Single row naming this database's generation. `epoch` is minted on first
|
|
597
|
+
* flush and changes only when the database is recreated, letting cc tell a
|
|
598
|
+
* reset outbox sequence from a stale sync batch. */
|
|
599
|
+
export declare const syncMeta: import("drizzle-orm/mssql-core").MsSqlTableWithColumns<{
|
|
600
|
+
name: "sync_meta";
|
|
601
|
+
schema: "ai";
|
|
602
|
+
columns: {
|
|
603
|
+
id: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
604
|
+
name: string;
|
|
605
|
+
tableName: "sync_meta";
|
|
606
|
+
dataType: "number int32";
|
|
607
|
+
data: number;
|
|
608
|
+
driverParam: number;
|
|
609
|
+
notNull: true;
|
|
610
|
+
hasDefault: false;
|
|
611
|
+
isPrimaryKey: true;
|
|
612
|
+
isAutoincrement: false;
|
|
613
|
+
hasRuntimeDefault: false;
|
|
614
|
+
enumValues: undefined;
|
|
615
|
+
baseColumn: never;
|
|
616
|
+
identity: undefined;
|
|
617
|
+
generated: undefined;
|
|
618
|
+
}, {}>;
|
|
619
|
+
epoch: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
620
|
+
name: string;
|
|
621
|
+
tableName: "sync_meta";
|
|
622
|
+
dataType: "string";
|
|
623
|
+
data: string;
|
|
624
|
+
driverParam: string | number;
|
|
625
|
+
notNull: true;
|
|
626
|
+
hasDefault: false;
|
|
627
|
+
isPrimaryKey: false;
|
|
628
|
+
isAutoincrement: false;
|
|
629
|
+
hasRuntimeDefault: false;
|
|
630
|
+
enumValues: [string, ...string[]];
|
|
631
|
+
baseColumn: never;
|
|
632
|
+
identity: undefined;
|
|
633
|
+
generated: undefined;
|
|
634
|
+
}, {}>;
|
|
635
|
+
};
|
|
636
|
+
dialect: "mssql";
|
|
637
|
+
}>;
|
|
638
|
+
export declare const syncOutbox: import("drizzle-orm/mssql-core").MsSqlTableWithColumns<{
|
|
639
|
+
name: "sync_outbox";
|
|
640
|
+
schema: "ai";
|
|
641
|
+
columns: {
|
|
642
|
+
id: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
643
|
+
name: string;
|
|
644
|
+
tableName: "sync_outbox";
|
|
645
|
+
dataType: "number int53";
|
|
646
|
+
data: number;
|
|
647
|
+
driverParam: string;
|
|
648
|
+
notNull: true;
|
|
649
|
+
hasDefault: true;
|
|
650
|
+
isPrimaryKey: true;
|
|
651
|
+
isAutoincrement: false;
|
|
652
|
+
hasRuntimeDefault: false;
|
|
653
|
+
enumValues: undefined;
|
|
654
|
+
baseColumn: never;
|
|
655
|
+
identity: undefined;
|
|
656
|
+
generated: {};
|
|
657
|
+
}, {}>;
|
|
658
|
+
event: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
659
|
+
name: string;
|
|
660
|
+
tableName: "sync_outbox";
|
|
661
|
+
dataType: "object json";
|
|
662
|
+
data: {
|
|
663
|
+
type: "thread.upsert";
|
|
664
|
+
id: string;
|
|
665
|
+
agentSlug: string;
|
|
666
|
+
userId: string;
|
|
667
|
+
title: string | null;
|
|
668
|
+
isTest: boolean;
|
|
669
|
+
createdAt: string;
|
|
670
|
+
updatedAt: string;
|
|
671
|
+
} | {
|
|
672
|
+
type: "thread.delete";
|
|
673
|
+
id: string;
|
|
674
|
+
} | {
|
|
675
|
+
type: "message.upsert";
|
|
676
|
+
id: string;
|
|
677
|
+
threadId: string;
|
|
678
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
679
|
+
text: string | null;
|
|
680
|
+
ordinal: number;
|
|
681
|
+
content: {
|
|
682
|
+
[x: string]: unknown;
|
|
683
|
+
};
|
|
684
|
+
createdAt: string;
|
|
685
|
+
} | {
|
|
686
|
+
type: "usage.record";
|
|
687
|
+
id: string;
|
|
688
|
+
messageId: string;
|
|
689
|
+
threadId: string;
|
|
690
|
+
stepNumber: number;
|
|
691
|
+
tokenUsage: {
|
|
692
|
+
input: {
|
|
693
|
+
noCache: number;
|
|
694
|
+
cacheRead: number;
|
|
695
|
+
cacheWrite: number;
|
|
696
|
+
total: number;
|
|
697
|
+
};
|
|
698
|
+
output: {
|
|
699
|
+
reasoning: number;
|
|
700
|
+
text: number;
|
|
701
|
+
total: number;
|
|
702
|
+
};
|
|
703
|
+
total: number;
|
|
704
|
+
};
|
|
705
|
+
createdAt: string;
|
|
706
|
+
};
|
|
707
|
+
driverParam: string;
|
|
708
|
+
notNull: true;
|
|
709
|
+
hasDefault: false;
|
|
710
|
+
isPrimaryKey: false;
|
|
711
|
+
isAutoincrement: false;
|
|
712
|
+
hasRuntimeDefault: false;
|
|
713
|
+
enumValues: undefined;
|
|
714
|
+
baseColumn: never;
|
|
715
|
+
identity: undefined;
|
|
716
|
+
generated: undefined;
|
|
717
|
+
}, {}>;
|
|
718
|
+
createdAt: import("drizzle-orm/mssql-core").MsSqlColumn<{
|
|
719
|
+
name: string;
|
|
720
|
+
tableName: "sync_outbox";
|
|
721
|
+
dataType: "object date";
|
|
722
|
+
data: Date;
|
|
723
|
+
driverParam: string | Date;
|
|
724
|
+
notNull: true;
|
|
725
|
+
hasDefault: true;
|
|
726
|
+
isPrimaryKey: false;
|
|
727
|
+
isAutoincrement: false;
|
|
728
|
+
hasRuntimeDefault: true;
|
|
729
|
+
enumValues: undefined;
|
|
730
|
+
baseColumn: never;
|
|
731
|
+
identity: undefined;
|
|
732
|
+
generated: undefined;
|
|
733
|
+
}, {}>;
|
|
734
|
+
};
|
|
735
|
+
dialect: "mssql";
|
|
736
|
+
}>;
|
|
@@ -100,6 +100,21 @@ export declare const threads: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
100
100
|
identity: undefined;
|
|
101
101
|
generated: undefined;
|
|
102
102
|
}>;
|
|
103
|
+
isTest: import("drizzle-orm/pg-core").PgBuildColumn<"threads", import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBooleanBuilder>>, {
|
|
104
|
+
name: string;
|
|
105
|
+
tableName: "threads";
|
|
106
|
+
dataType: "boolean";
|
|
107
|
+
data: boolean;
|
|
108
|
+
driverParam: boolean;
|
|
109
|
+
notNull: true;
|
|
110
|
+
hasDefault: true;
|
|
111
|
+
isPrimaryKey: false;
|
|
112
|
+
isAutoincrement: false;
|
|
113
|
+
hasRuntimeDefault: false;
|
|
114
|
+
enumValues: undefined;
|
|
115
|
+
identity: undefined;
|
|
116
|
+
generated: undefined;
|
|
117
|
+
}>;
|
|
103
118
|
session: import("drizzle-orm/pg-core").PgBuildColumn<"threads", import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").PgJsonbBuilder, Record<string, unknown>>, {
|
|
104
119
|
name: string;
|
|
105
120
|
tableName: "threads";
|
|
@@ -544,3 +559,187 @@ export declare const attachments: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
544
559
|
};
|
|
545
560
|
dialect: "pg";
|
|
546
561
|
}>;
|
|
562
|
+
/**
|
|
563
|
+
* Events awaiting the cc sync flusher. Insertion order (the bigserial id) is
|
|
564
|
+
* flush order; `ack` deletes.
|
|
565
|
+
*/
|
|
566
|
+
/** Single row naming this database's generation. `epoch` is minted on first
|
|
567
|
+
* flush and changes only when the database is recreated, letting cc tell a
|
|
568
|
+
* reset outbox sequence from a stale sync batch. */
|
|
569
|
+
export declare const syncMeta: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
570
|
+
name: "sync_meta";
|
|
571
|
+
schema: "ai";
|
|
572
|
+
columns: {
|
|
573
|
+
id: import("drizzle-orm/pg-core").PgBuildColumn<"sync_meta", import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgIntegerBuilder>, {
|
|
574
|
+
name: string;
|
|
575
|
+
tableName: "sync_meta";
|
|
576
|
+
dataType: "number int32";
|
|
577
|
+
data: number;
|
|
578
|
+
driverParam: string | number;
|
|
579
|
+
notNull: true;
|
|
580
|
+
hasDefault: false;
|
|
581
|
+
isPrimaryKey: false;
|
|
582
|
+
isAutoincrement: false;
|
|
583
|
+
hasRuntimeDefault: false;
|
|
584
|
+
enumValues: undefined;
|
|
585
|
+
identity: undefined;
|
|
586
|
+
generated: undefined;
|
|
587
|
+
}>;
|
|
588
|
+
epoch: import("drizzle-orm/pg-core").PgBuildColumn<"sync_meta", import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgVarcharBuilder<[string, ...string[]]>>, {
|
|
589
|
+
name: string;
|
|
590
|
+
tableName: "sync_meta";
|
|
591
|
+
dataType: "string";
|
|
592
|
+
data: string;
|
|
593
|
+
driverParam: string;
|
|
594
|
+
notNull: true;
|
|
595
|
+
hasDefault: false;
|
|
596
|
+
isPrimaryKey: false;
|
|
597
|
+
isAutoincrement: false;
|
|
598
|
+
hasRuntimeDefault: false;
|
|
599
|
+
enumValues: undefined;
|
|
600
|
+
identity: undefined;
|
|
601
|
+
generated: undefined;
|
|
602
|
+
}>;
|
|
603
|
+
};
|
|
604
|
+
dialect: "pg";
|
|
605
|
+
}>;
|
|
606
|
+
export declare const syncOutbox: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
607
|
+
name: "sync_outbox";
|
|
608
|
+
schema: "ai";
|
|
609
|
+
columns: {
|
|
610
|
+
id: import("drizzle-orm/pg-core").PgBuildColumn<"sync_outbox", import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgBigSerial53Builder>, {
|
|
611
|
+
name: string;
|
|
612
|
+
tableName: "sync_outbox";
|
|
613
|
+
dataType: "number int53";
|
|
614
|
+
data: number;
|
|
615
|
+
driverParam: number;
|
|
616
|
+
notNull: true;
|
|
617
|
+
hasDefault: true;
|
|
618
|
+
isPrimaryKey: false;
|
|
619
|
+
isAutoincrement: false;
|
|
620
|
+
hasRuntimeDefault: false;
|
|
621
|
+
enumValues: undefined;
|
|
622
|
+
identity: undefined;
|
|
623
|
+
generated: undefined;
|
|
624
|
+
}>;
|
|
625
|
+
event: import("drizzle-orm/pg-core").PgBuildColumn<"sync_outbox", import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgJsonbBuilder>, {
|
|
626
|
+
type: "thread.upsert";
|
|
627
|
+
id: string;
|
|
628
|
+
agentSlug: string;
|
|
629
|
+
userId: string;
|
|
630
|
+
title: string | null;
|
|
631
|
+
isTest: boolean;
|
|
632
|
+
createdAt: string;
|
|
633
|
+
updatedAt: string;
|
|
634
|
+
} | {
|
|
635
|
+
type: "thread.delete";
|
|
636
|
+
id: string;
|
|
637
|
+
} | {
|
|
638
|
+
type: "message.upsert";
|
|
639
|
+
id: string;
|
|
640
|
+
threadId: string;
|
|
641
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
642
|
+
text: string | null;
|
|
643
|
+
ordinal: number;
|
|
644
|
+
content: {
|
|
645
|
+
[x: string]: unknown;
|
|
646
|
+
};
|
|
647
|
+
createdAt: string;
|
|
648
|
+
} | {
|
|
649
|
+
type: "usage.record";
|
|
650
|
+
id: string;
|
|
651
|
+
messageId: string;
|
|
652
|
+
threadId: string;
|
|
653
|
+
stepNumber: number;
|
|
654
|
+
tokenUsage: {
|
|
655
|
+
input: {
|
|
656
|
+
noCache: number;
|
|
657
|
+
cacheRead: number;
|
|
658
|
+
cacheWrite: number;
|
|
659
|
+
total: number;
|
|
660
|
+
};
|
|
661
|
+
output: {
|
|
662
|
+
reasoning: number;
|
|
663
|
+
text: number;
|
|
664
|
+
total: number;
|
|
665
|
+
};
|
|
666
|
+
total: number;
|
|
667
|
+
};
|
|
668
|
+
createdAt: string;
|
|
669
|
+
}>, {
|
|
670
|
+
name: string;
|
|
671
|
+
tableName: "sync_outbox";
|
|
672
|
+
dataType: "object json";
|
|
673
|
+
data: {
|
|
674
|
+
type: "thread.upsert";
|
|
675
|
+
id: string;
|
|
676
|
+
agentSlug: string;
|
|
677
|
+
userId: string;
|
|
678
|
+
title: string | null;
|
|
679
|
+
isTest: boolean;
|
|
680
|
+
createdAt: string;
|
|
681
|
+
updatedAt: string;
|
|
682
|
+
} | {
|
|
683
|
+
type: "thread.delete";
|
|
684
|
+
id: string;
|
|
685
|
+
} | {
|
|
686
|
+
type: "message.upsert";
|
|
687
|
+
id: string;
|
|
688
|
+
threadId: string;
|
|
689
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
690
|
+
text: string | null;
|
|
691
|
+
ordinal: number;
|
|
692
|
+
content: {
|
|
693
|
+
[x: string]: unknown;
|
|
694
|
+
};
|
|
695
|
+
createdAt: string;
|
|
696
|
+
} | {
|
|
697
|
+
type: "usage.record";
|
|
698
|
+
id: string;
|
|
699
|
+
messageId: string;
|
|
700
|
+
threadId: string;
|
|
701
|
+
stepNumber: number;
|
|
702
|
+
tokenUsage: {
|
|
703
|
+
input: {
|
|
704
|
+
noCache: number;
|
|
705
|
+
cacheRead: number;
|
|
706
|
+
cacheWrite: number;
|
|
707
|
+
total: number;
|
|
708
|
+
};
|
|
709
|
+
output: {
|
|
710
|
+
reasoning: number;
|
|
711
|
+
text: number;
|
|
712
|
+
total: number;
|
|
713
|
+
};
|
|
714
|
+
total: number;
|
|
715
|
+
};
|
|
716
|
+
createdAt: string;
|
|
717
|
+
};
|
|
718
|
+
driverParam: unknown;
|
|
719
|
+
notNull: true;
|
|
720
|
+
hasDefault: false;
|
|
721
|
+
isPrimaryKey: false;
|
|
722
|
+
isAutoincrement: false;
|
|
723
|
+
hasRuntimeDefault: false;
|
|
724
|
+
enumValues: undefined;
|
|
725
|
+
identity: undefined;
|
|
726
|
+
generated: undefined;
|
|
727
|
+
}>;
|
|
728
|
+
createdAt: import("drizzle-orm/pg-core").PgBuildColumn<"sync_outbox", import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").SetHasRuntimeDefault<import("drizzle-orm/pg-core").PgTimestampBuilder>>, {
|
|
729
|
+
name: string;
|
|
730
|
+
tableName: "sync_outbox";
|
|
731
|
+
dataType: "object date";
|
|
732
|
+
data: Date;
|
|
733
|
+
driverParam: string;
|
|
734
|
+
notNull: true;
|
|
735
|
+
hasDefault: true;
|
|
736
|
+
isPrimaryKey: false;
|
|
737
|
+
isAutoincrement: false;
|
|
738
|
+
hasRuntimeDefault: false;
|
|
739
|
+
enumValues: undefined;
|
|
740
|
+
identity: undefined;
|
|
741
|
+
generated: undefined;
|
|
742
|
+
}>;
|
|
743
|
+
};
|
|
744
|
+
dialect: "pg";
|
|
745
|
+
}>;
|
|
@@ -9,6 +9,8 @@ export type CortexInstance = {
|
|
|
9
9
|
fetch: Hono<AppEnv>["fetch"];
|
|
10
10
|
websocket: typeof websocket;
|
|
11
11
|
}>;
|
|
12
|
+
/** Stops the cc sync flusher (a no-op before `serve` or without cc). */
|
|
13
|
+
stop(): void;
|
|
12
14
|
};
|
|
13
15
|
export declare function createCortex(config: CortexConfig): {
|
|
14
16
|
serve(): Promise<{
|
|
@@ -17,4 +19,5 @@ export declare function createCortex(config: CortexConfig): {
|
|
|
17
19
|
fetch: (request: Request, Env?: {} | undefined, executionCtx?: import("hono").ExecutionContext) => Response | Promise<Response>;
|
|
18
20
|
websocket: import("hono/bun").BunWebSocketHandler<import("hono/bun").BunWebSocketData>;
|
|
19
21
|
}>;
|
|
22
|
+
stop(): void;
|
|
20
23
|
};
|
|
@@ -6,12 +6,13 @@ import type { CortexAppEnv } from "../types";
|
|
|
6
6
|
* would confirm the thread exists, making cross-agent ids probeable.
|
|
7
7
|
*/
|
|
8
8
|
export declare function requireOwnedThread(c: Context<CortexAppEnv>, threadId: string): Promise<{
|
|
9
|
-
id: string;
|
|
10
|
-
userId: string;
|
|
11
9
|
agentId: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
id: string;
|
|
12
12
|
title: string | null;
|
|
13
|
-
|
|
14
|
-
contextMeta: import("..").ThreadContextMeta | null;
|
|
13
|
+
isTest: boolean;
|
|
15
14
|
createdAt: Date;
|
|
16
15
|
updatedAt: Date;
|
|
16
|
+
session: Record<string, unknown> | null;
|
|
17
|
+
contextMeta: import("..").ThreadContextMeta | null;
|
|
17
18
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m6d/cortex-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Reusable AI agent chat server library for Hono + Bun",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@tanstack/ai": "^0.43.1",
|
|
51
51
|
"@tanstack/ai-openai": "^0.18.0",
|
|
52
|
-
"@types/bun": "
|
|
52
|
+
"@types/bun": "1.3.14",
|
|
53
53
|
"@types/minio": "^7.1.1",
|
|
54
54
|
"@types/mssql": "^9.1.5",
|
|
55
55
|
"@types/pg": "^8.15.6",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SyncEvent } from "@cortex/contracts/runtime";
|
|
1
2
|
import type {
|
|
2
3
|
Attachment,
|
|
3
4
|
ChatMessage,
|
|
@@ -28,7 +29,7 @@ export type DatabaseAdapter = {
|
|
|
28
29
|
threads: {
|
|
29
30
|
list(userId: string, agentId: string): Promise<Thread[]>;
|
|
30
31
|
getById(userId: string, threadId: string): Promise<Thread | null>;
|
|
31
|
-
create(userId: string, agentId: string): Promise<Thread>;
|
|
32
|
+
create(userId: string, agentId: string, options?: { isTest?: boolean }): Promise<Thread>;
|
|
32
33
|
delete(userId: string, threadId: string): Promise<void>;
|
|
33
34
|
touch(threadId: string): Promise<Thread>;
|
|
34
35
|
updateTitle(threadId: string, title: string): Promise<void>;
|
|
@@ -45,6 +46,7 @@ export type DatabaseAdapter = {
|
|
|
45
46
|
};
|
|
46
47
|
llmRequests: {
|
|
47
48
|
insert(
|
|
49
|
+
threadId: string,
|
|
48
50
|
requests: {
|
|
49
51
|
messageId: string;
|
|
50
52
|
stepNumber: number;
|
|
@@ -75,4 +77,16 @@ export type DatabaseAdapter = {
|
|
|
75
77
|
): Promise<void>;
|
|
76
78
|
remove(id: string, userId: string): Promise<Attachment | undefined>;
|
|
77
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* The cc sync queue. Write sites enqueue through the dialect's
|
|
82
|
+
* `enqueueSyncEvents` inside their own transaction; the flusher drains via
|
|
83
|
+
* `peek` (id ascending = insertion order) and `ack` (delete) here.
|
|
84
|
+
*/
|
|
85
|
+
outbox: {
|
|
86
|
+
enqueue(events: SyncEvent[]): Promise<void>;
|
|
87
|
+
peek(limit: number): Promise<{ id: number; event: SyncEvent }[]>;
|
|
88
|
+
ack(ids: number[]): Promise<void>;
|
|
89
|
+
/** This database generation's id, minted on first use (see `syncMeta`). */
|
|
90
|
+
epoch(): Promise<string>;
|
|
91
|
+
};
|
|
78
92
|
};
|
|
@@ -5,19 +5,28 @@ import { createThreadsRepository } from "./threads";
|
|
|
5
5
|
import { createMessagesRepository } from "./messages";
|
|
6
6
|
import { createLlmRequestsRepository } from "./llm-requests";
|
|
7
7
|
import { createAttachmentsRepository } from "./attachments";
|
|
8
|
+
import { createOutboxRepository, enqueueSyncEvents } from "./outbox";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* The MSSQL implementation of the database contract. One repository per table;
|
|
11
12
|
* only threads takes storage, because deleting a thread is the one operation
|
|
12
13
|
* that also has to reach into object storage.
|
|
13
14
|
*/
|
|
14
|
-
export function createMssqlAdapter(
|
|
15
|
+
export function createMssqlAdapter(
|
|
16
|
+
connectionString: string,
|
|
17
|
+
storage?: StorageAdapter,
|
|
18
|
+
options?: { syncMirror?: boolean },
|
|
19
|
+
) {
|
|
15
20
|
const db = createMssqlDb(connectionString);
|
|
21
|
+
// Without a Control Center there is no flusher to drain the outbox, so
|
|
22
|
+
// enqueueing would only grow sync_outbox forever.
|
|
23
|
+
const enqueue = options?.syncMirror === false ? async () => {} : enqueueSyncEvents;
|
|
16
24
|
|
|
17
25
|
return {
|
|
18
|
-
threads: createThreadsRepository(db, storage),
|
|
19
|
-
messages: createMessagesRepository(db),
|
|
20
|
-
llmRequests: createLlmRequestsRepository(db),
|
|
26
|
+
threads: createThreadsRepository(db, storage, enqueue),
|
|
27
|
+
messages: createMessagesRepository(db, enqueue),
|
|
28
|
+
llmRequests: createLlmRequestsRepository(db, enqueue),
|
|
21
29
|
attachments: createAttachmentsRepository(db),
|
|
30
|
+
outbox: createOutboxRepository(db),
|
|
22
31
|
} satisfies DatabaseAdapter;
|
|
23
32
|
}
|
|
@@ -1,28 +1,48 @@
|
|
|
1
1
|
import { asc, eq, type InferInsertModel } from "drizzle-orm";
|
|
2
2
|
import { llmRequests } from "@/db/schema.mssql";
|
|
3
|
+
import { usageRecordEvent } from "@/cc/sync-events";
|
|
3
4
|
import type { DatabaseAdapter } from "@/adapters/database/index";
|
|
4
5
|
import type { MssqlDb } from "./client";
|
|
6
|
+
import { enqueueSyncEvents } from "./outbox";
|
|
5
7
|
|
|
6
|
-
export function createLlmRequestsRepository(
|
|
8
|
+
export function createLlmRequestsRepository(
|
|
9
|
+
db: MssqlDb,
|
|
10
|
+
enqueue: typeof enqueueSyncEvents = enqueueSyncEvents,
|
|
11
|
+
) {
|
|
7
12
|
return {
|
|
8
|
-
async insert(requests) {
|
|
13
|
+
async insert(threadId, requests) {
|
|
9
14
|
if (!requests.length) return;
|
|
10
15
|
|
|
11
|
-
await db
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
(
|
|
16
|
-
(
|
|
16
|
+
await db.transaction(async function (tx) {
|
|
17
|
+
await tx
|
|
18
|
+
.insert(llmRequests)
|
|
19
|
+
.values(
|
|
20
|
+
requests.map(
|
|
21
|
+
(r) =>
|
|
22
|
+
({
|
|
23
|
+
messageId: r.messageId,
|
|
24
|
+
stepNumber: r.stepNumber,
|
|
25
|
+
prompt: r.prompt,
|
|
26
|
+
output: r.output,
|
|
27
|
+
tokenUsage: r.tokenUsage,
|
|
28
|
+
}) satisfies InferInsertModel<typeof llmRequests>,
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
.execute();
|
|
32
|
+
await enqueue(
|
|
33
|
+
tx,
|
|
34
|
+
requests
|
|
35
|
+
.filter((r) => r.tokenUsage !== null)
|
|
36
|
+
.map((r) =>
|
|
37
|
+
usageRecordEvent({
|
|
38
|
+
threadId,
|
|
17
39
|
messageId: r.messageId,
|
|
18
40
|
stepNumber: r.stepNumber,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
.execute();
|
|
41
|
+
tokenUsage: r.tokenUsage!,
|
|
42
|
+
}),
|
|
43
|
+
),
|
|
44
|
+
);
|
|
45
|
+
});
|
|
26
46
|
},
|
|
27
47
|
|
|
28
48
|
/** Ordered by step so the inspector replays a turn in the order it ran. */
|