family-ai-agent 1.0.5 → 1.0.7
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/.letta/settings.local.json +3 -0
- package/dist/cli/index.js +6 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/database/adapters/base-adapter.d.ts +81 -0
- package/dist/database/adapters/base-adapter.d.ts.map +1 -0
- package/dist/database/adapters/base-adapter.js +105 -0
- package/dist/database/adapters/base-adapter.js.map +1 -0
- package/dist/database/adapters/index.d.ts +49 -0
- package/dist/database/adapters/index.d.ts.map +1 -0
- package/dist/database/adapters/index.js +200 -0
- package/dist/database/adapters/index.js.map +1 -0
- package/dist/database/adapters/postgres-adapter.d.ts +75 -0
- package/dist/database/adapters/postgres-adapter.d.ts.map +1 -0
- package/dist/database/adapters/postgres-adapter.js +225 -0
- package/dist/database/adapters/postgres-adapter.js.map +1 -0
- package/dist/database/adapters/sqlite-adapter.d.ts +72 -0
- package/dist/database/adapters/sqlite-adapter.d.ts.map +1 -0
- package/dist/database/adapters/sqlite-adapter.js +368 -0
- package/dist/database/adapters/sqlite-adapter.js.map +1 -0
- package/dist/database/cache/cache-keys.d.ts +180 -0
- package/dist/database/cache/cache-keys.d.ts.map +1 -0
- package/dist/database/cache/cache-keys.js +107 -0
- package/dist/database/cache/cache-keys.js.map +1 -0
- package/dist/database/cache/index.d.ts +24 -0
- package/dist/database/cache/index.d.ts.map +1 -0
- package/dist/database/cache/index.js +34 -0
- package/dist/database/cache/index.js.map +1 -0
- package/dist/database/cache/query-cache.d.ts +67 -0
- package/dist/database/cache/query-cache.d.ts.map +1 -0
- package/dist/database/cache/query-cache.js +177 -0
- package/dist/database/cache/query-cache.js.map +1 -0
- package/dist/database/client.d.ts +63 -4
- package/dist/database/client.d.ts.map +1 -1
- package/dist/database/client.js +147 -59
- package/dist/database/client.js.map +1 -1
- package/dist/database/db-config.d.ts +104 -0
- package/dist/database/db-config.d.ts.map +1 -0
- package/dist/database/db-config.js +167 -0
- package/dist/database/db-config.js.map +1 -0
- package/dist/database/drizzle/index.d.ts +42 -0
- package/dist/database/drizzle/index.d.ts.map +1 -0
- package/dist/database/drizzle/index.js +48 -0
- package/dist/database/drizzle/index.js.map +1 -0
- package/dist/database/drizzle/schema/audit.d.ts +533 -0
- package/dist/database/drizzle/schema/audit.d.ts.map +1 -0
- package/dist/database/drizzle/schema/audit.js +71 -0
- package/dist/database/drizzle/schema/audit.js.map +1 -0
- package/dist/database/drizzle/schema/checkpoints.d.ts +665 -0
- package/dist/database/drizzle/schema/checkpoints.d.ts.map +1 -0
- package/dist/database/drizzle/schema/checkpoints.js +110 -0
- package/dist/database/drizzle/schema/checkpoints.js.map +1 -0
- package/dist/database/drizzle/schema/conversations.d.ts +449 -0
- package/dist/database/drizzle/schema/conversations.d.ts.map +1 -0
- package/dist/database/drizzle/schema/conversations.js +91 -0
- package/dist/database/drizzle/schema/conversations.js.map +1 -0
- package/dist/database/drizzle/schema/documents.d.ts +600 -0
- package/dist/database/drizzle/schema/documents.d.ts.map +1 -0
- package/dist/database/drizzle/schema/documents.js +100 -0
- package/dist/database/drizzle/schema/documents.js.map +1 -0
- package/dist/database/drizzle/schema/index.d.ts +3084 -0
- package/dist/database/drizzle/schema/index.d.ts.map +1 -0
- package/dist/database/drizzle/schema/index.js +46 -0
- package/dist/database/drizzle/schema/index.js.map +1 -0
- package/dist/database/drizzle/schema/memories.d.ts +435 -0
- package/dist/database/drizzle/schema/memories.d.ts.map +1 -0
- package/dist/database/drizzle/schema/memories.js +73 -0
- package/dist/database/drizzle/schema/memories.js.map +1 -0
- package/dist/database/drizzle/schema/tasks.d.ts +565 -0
- package/dist/database/drizzle/schema/tasks.d.ts.map +1 -0
- package/dist/database/drizzle/schema/tasks.js +84 -0
- package/dist/database/drizzle/schema/tasks.js.map +1 -0
- package/dist/database/health/circuit-breaker.d.ts +81 -0
- package/dist/database/health/circuit-breaker.d.ts.map +1 -0
- package/dist/database/health/circuit-breaker.js +184 -0
- package/dist/database/health/circuit-breaker.js.map +1 -0
- package/dist/database/health/health-monitor.d.ts +69 -0
- package/dist/database/health/health-monitor.d.ts.map +1 -0
- package/dist/database/health/health-monitor.js +174 -0
- package/dist/database/health/health-monitor.js.map +1 -0
- package/dist/database/health/index.d.ts +27 -0
- package/dist/database/health/index.d.ts.map +1 -0
- package/dist/database/health/index.js +23 -0
- package/dist/database/health/index.js.map +1 -0
- package/dist/database/index.d.ts +16 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +41 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/migrations/index.d.ts +34 -0
- package/dist/database/migrations/index.d.ts.map +1 -0
- package/dist/database/migrations/index.js +45 -0
- package/dist/database/migrations/index.js.map +1 -0
- package/dist/database/migrations/migrator.d.ts +77 -0
- package/dist/database/migrations/migrator.d.ts.map +1 -0
- package/dist/database/migrations/migrator.js +258 -0
- package/dist/database/migrations/migrator.js.map +1 -0
- package/dist/database/migrations/versions/001_initial.d.ts +9 -0
- package/dist/database/migrations/versions/001_initial.d.ts.map +1 -0
- package/dist/database/migrations/versions/001_initial.js +183 -0
- package/dist/database/migrations/versions/001_initial.js.map +1 -0
- package/dist/database/types.d.ts +255 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +8 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database/vector/embedding-cache.d.ts +92 -0
- package/dist/database/vector/embedding-cache.d.ts.map +1 -0
- package/dist/database/vector/embedding-cache.js +185 -0
- package/dist/database/vector/embedding-cache.js.map +1 -0
- package/dist/database/vector/hnsw-index.d.ts +111 -0
- package/dist/database/vector/hnsw-index.d.ts.map +1 -0
- package/dist/database/vector/hnsw-index.js +337 -0
- package/dist/database/vector/hnsw-index.js.map +1 -0
- package/dist/database/vector/index.d.ts +75 -0
- package/dist/database/vector/index.d.ts.map +1 -0
- package/dist/database/vector/index.js +213 -0
- package/dist/database/vector/index.js.map +1 -0
- package/dist/database/vector/similarity.d.ts +67 -0
- package/dist/database/vector/similarity.d.ts.map +1 -0
- package/dist/database/vector/similarity.js +176 -0
- package/dist/database/vector/similarity.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -3
- package/src/cli/index.ts +5 -5
- package/src/database/adapters/base-adapter.ts +171 -0
- package/src/database/adapters/index.ts +224 -0
- package/src/database/adapters/postgres-adapter.ts +285 -0
- package/src/database/adapters/sqlite-adapter.ts +420 -0
- package/src/database/cache/cache-keys.ts +150 -0
- package/src/database/cache/index.ts +44 -0
- package/src/database/cache/query-cache.ts +213 -0
- package/src/database/client.ts +166 -64
- package/src/database/db-config.ts +194 -0
- package/src/database/drizzle/index.ts +66 -0
- package/src/database/drizzle/schema/audit.ts +127 -0
- package/src/database/drizzle/schema/checkpoints.ts +164 -0
- package/src/database/drizzle/schema/conversations.ts +138 -0
- package/src/database/drizzle/schema/documents.ts +157 -0
- package/src/database/drizzle/schema/index.ts +139 -0
- package/src/database/drizzle/schema/memories.ts +127 -0
- package/src/database/drizzle/schema/tasks.ts +129 -0
- package/src/database/health/circuit-breaker.ts +214 -0
- package/src/database/health/health-monitor.ts +224 -0
- package/src/database/health/index.ts +41 -0
- package/src/database/index.ts +157 -0
- package/src/database/migrations/index.ts +52 -0
- package/src/database/migrations/migrator.ts +325 -0
- package/src/database/migrations/versions/001_initial.ts +198 -0
- package/src/database/types.ts +324 -0
- package/src/database/vector/embedding-cache.ts +234 -0
- package/src/database/vector/hnsw-index.ts +452 -0
- package/src/database/vector/index.ts +292 -0
- package/src/database/vector/similarity.ts +198 -0
- package/src/index.ts +1 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drizzle ORM Instance Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates and manages Drizzle ORM instances for both PostgreSQL and SQLite.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';
|
|
8
|
+
import { drizzle as drizzleSqlite } from 'drizzle-orm/better-sqlite3';
|
|
9
|
+
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
10
|
+
import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
|
|
11
|
+
import type { Pool } from 'pg';
|
|
12
|
+
import type Database from 'better-sqlite3';
|
|
13
|
+
|
|
14
|
+
import * as pgSchema from './schema/conversations.js';
|
|
15
|
+
import * as sqliteSchema from './schema/conversations.js';
|
|
16
|
+
|
|
17
|
+
// Re-export schema
|
|
18
|
+
export * from './schema/index.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Drizzle instance types
|
|
22
|
+
*/
|
|
23
|
+
export type DrizzlePgInstance = NodePgDatabase<typeof pgSchema>;
|
|
24
|
+
export type DrizzleSqliteInstance = BetterSQLite3Database<typeof sqliteSchema>;
|
|
25
|
+
export type DrizzleInstance = DrizzlePgInstance | DrizzleSqliteInstance;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create Drizzle instance for PostgreSQL
|
|
29
|
+
*/
|
|
30
|
+
export function createPgDrizzle(pool: Pool): DrizzlePgInstance {
|
|
31
|
+
return drizzlePg(pool, {
|
|
32
|
+
schema: pgSchema,
|
|
33
|
+
logger: process.env.NODE_ENV === 'development',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create Drizzle instance for SQLite
|
|
39
|
+
*/
|
|
40
|
+
export function createSqliteDrizzle(database: Database.Database): DrizzleSqliteInstance {
|
|
41
|
+
return drizzleSqlite(database, {
|
|
42
|
+
schema: sqliteSchema,
|
|
43
|
+
logger: process.env.NODE_ENV === 'development',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Database type guard for PostgreSQL
|
|
49
|
+
*/
|
|
50
|
+
export function isPgDrizzle(db: DrizzleInstance): db is DrizzlePgInstance {
|
|
51
|
+
return 'dialect' in db && (db as unknown as { dialect: { name: string } }).dialect?.name === 'pg';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Database type guard for SQLite
|
|
56
|
+
*/
|
|
57
|
+
export function isSqliteDrizzle(db: DrizzleInstance): db is DrizzleSqliteInstance {
|
|
58
|
+
return 'dialect' in db && (db as unknown as { dialect: { name: string } }).dialect?.name === 'sqlite';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default {
|
|
62
|
+
createPgDrizzle,
|
|
63
|
+
createSqliteDrizzle,
|
|
64
|
+
isPgDrizzle,
|
|
65
|
+
isSqliteDrizzle,
|
|
66
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Logs Schema
|
|
3
|
+
*
|
|
4
|
+
* Drizzle ORM schema for safety and compliance audit logging.
|
|
5
|
+
* Tracks all significant actions in the system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
pgTable,
|
|
10
|
+
uuid,
|
|
11
|
+
text,
|
|
12
|
+
integer,
|
|
13
|
+
timestamp,
|
|
14
|
+
jsonb,
|
|
15
|
+
boolean,
|
|
16
|
+
index,
|
|
17
|
+
} from 'drizzle-orm/pg-core';
|
|
18
|
+
import {
|
|
19
|
+
sqliteTable,
|
|
20
|
+
text as sqliteText,
|
|
21
|
+
integer as sqliteInteger,
|
|
22
|
+
} from 'drizzle-orm/sqlite-core';
|
|
23
|
+
import { sql } from 'drizzle-orm';
|
|
24
|
+
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// PostgreSQL Schema
|
|
27
|
+
// =============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Audit logs table (PostgreSQL)
|
|
31
|
+
*/
|
|
32
|
+
export const auditLogsPg = pgTable(
|
|
33
|
+
'audit_logs',
|
|
34
|
+
{
|
|
35
|
+
id: uuid('id')
|
|
36
|
+
.primaryKey()
|
|
37
|
+
.default(sql`gen_random_uuid()`),
|
|
38
|
+
userId: text('user_id'),
|
|
39
|
+
agentId: text('agent_id'),
|
|
40
|
+
actionType: text('action_type').notNull(),
|
|
41
|
+
actionDetails: jsonb('action_details').default({}).notNull(),
|
|
42
|
+
inputHash: text('input_hash'),
|
|
43
|
+
outputHash: text('output_hash'),
|
|
44
|
+
status: text('status').default('success').notNull(),
|
|
45
|
+
errorMessage: text('error_message'),
|
|
46
|
+
executionTimeMs: integer('execution_time_ms'),
|
|
47
|
+
ipAddress: text('ip_address'),
|
|
48
|
+
userAgent: text('user_agent'),
|
|
49
|
+
success: boolean('success').default(true).notNull(),
|
|
50
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
51
|
+
.defaultNow()
|
|
52
|
+
.notNull(),
|
|
53
|
+
},
|
|
54
|
+
(table) => ({
|
|
55
|
+
userIdIdx: index('audit_user_id_idx').on(table.userId),
|
|
56
|
+
agentIdIdx: index('audit_agent_id_idx').on(table.agentId),
|
|
57
|
+
actionTypeIdx: index('audit_action_type_idx').on(table.actionType),
|
|
58
|
+
createdAtIdx: index('audit_created_at_idx').on(table.createdAt),
|
|
59
|
+
statusIdx: index('audit_status_idx').on(table.status),
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// SQLite Schema
|
|
65
|
+
// =============================================================================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Audit logs table (SQLite)
|
|
69
|
+
*/
|
|
70
|
+
export const auditLogsSqlite = sqliteTable('audit_logs', {
|
|
71
|
+
id: sqliteText('id')
|
|
72
|
+
.primaryKey()
|
|
73
|
+
.$defaultFn(() => crypto.randomUUID()),
|
|
74
|
+
userId: sqliteText('user_id'),
|
|
75
|
+
agentId: sqliteText('agent_id'),
|
|
76
|
+
actionType: sqliteText('action_type').notNull(),
|
|
77
|
+
actionDetails: sqliteText('action_details', { mode: 'json' })
|
|
78
|
+
.notNull()
|
|
79
|
+
.$type<Record<string, unknown>>()
|
|
80
|
+
.default({}),
|
|
81
|
+
inputHash: sqliteText('input_hash'),
|
|
82
|
+
outputHash: sqliteText('output_hash'),
|
|
83
|
+
status: sqliteText('status').default('success').notNull(),
|
|
84
|
+
errorMessage: sqliteText('error_message'),
|
|
85
|
+
executionTimeMs: sqliteInteger('execution_time_ms'),
|
|
86
|
+
ipAddress: sqliteText('ip_address'),
|
|
87
|
+
userAgent: sqliteText('user_agent'),
|
|
88
|
+
success: sqliteInteger('success', { mode: 'boolean' }).default(true).notNull(),
|
|
89
|
+
createdAt: sqliteInteger('created_at', { mode: 'timestamp' })
|
|
90
|
+
.notNull()
|
|
91
|
+
.$defaultFn(() => new Date()),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// =============================================================================
|
|
95
|
+
// TypeScript Types
|
|
96
|
+
// =============================================================================
|
|
97
|
+
|
|
98
|
+
export type AuditLogPg = typeof auditLogsPg.$inferSelect;
|
|
99
|
+
export type NewAuditLogPg = typeof auditLogsPg.$inferInsert;
|
|
100
|
+
|
|
101
|
+
export type AuditLogSqlite = typeof auditLogsSqlite.$inferSelect;
|
|
102
|
+
export type NewAuditLogSqlite = typeof auditLogsSqlite.$inferInsert;
|
|
103
|
+
|
|
104
|
+
// Unified types
|
|
105
|
+
export type AuditLog = AuditLogPg | AuditLogSqlite;
|
|
106
|
+
export type NewAuditLog = NewAuditLogPg | NewAuditLogSqlite;
|
|
107
|
+
|
|
108
|
+
// Action types enum
|
|
109
|
+
export type AuditActionType =
|
|
110
|
+
| 'chat_message'
|
|
111
|
+
| 'memory_store'
|
|
112
|
+
| 'memory_search'
|
|
113
|
+
| 'memory_delete'
|
|
114
|
+
| 'document_upload'
|
|
115
|
+
| 'document_search'
|
|
116
|
+
| 'document_delete'
|
|
117
|
+
| 'agent_invocation'
|
|
118
|
+
| 'tool_execution'
|
|
119
|
+
| 'safety_block'
|
|
120
|
+
| 'safety_warning'
|
|
121
|
+
| 'authentication'
|
|
122
|
+
| 'authorization'
|
|
123
|
+
| 'config_change'
|
|
124
|
+
| 'system_event';
|
|
125
|
+
|
|
126
|
+
// Status types
|
|
127
|
+
export type AuditStatus = 'success' | 'failure' | 'blocked' | 'warning';
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoints Schema
|
|
3
|
+
*
|
|
4
|
+
* Drizzle ORM schema for LangGraph checkpointing.
|
|
5
|
+
* Stores execution state for resumable workflows.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
pgTable,
|
|
10
|
+
text,
|
|
11
|
+
timestamp,
|
|
12
|
+
jsonb,
|
|
13
|
+
primaryKey,
|
|
14
|
+
integer,
|
|
15
|
+
} from 'drizzle-orm/pg-core';
|
|
16
|
+
import {
|
|
17
|
+
sqliteTable,
|
|
18
|
+
text as sqliteText,
|
|
19
|
+
integer as sqliteInteger,
|
|
20
|
+
primaryKey as sqlitePrimaryKey,
|
|
21
|
+
} from 'drizzle-orm/sqlite-core';
|
|
22
|
+
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// PostgreSQL Schema
|
|
25
|
+
// =============================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checkpoints table (PostgreSQL)
|
|
29
|
+
*/
|
|
30
|
+
export const checkpointsPg = pgTable(
|
|
31
|
+
'checkpoints',
|
|
32
|
+
{
|
|
33
|
+
threadId: text('thread_id').notNull(),
|
|
34
|
+
checkpointNs: text('checkpoint_ns').default('').notNull(),
|
|
35
|
+
checkpointId: text('checkpoint_id').notNull(),
|
|
36
|
+
parentCheckpointId: text('parent_checkpoint_id'),
|
|
37
|
+
type: text('type'),
|
|
38
|
+
checkpoint: jsonb('checkpoint').notNull(),
|
|
39
|
+
metadata: jsonb('metadata').default({}).notNull(),
|
|
40
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
41
|
+
.defaultNow()
|
|
42
|
+
.notNull(),
|
|
43
|
+
},
|
|
44
|
+
(table) => ({
|
|
45
|
+
pk: primaryKey({
|
|
46
|
+
columns: [table.threadId, table.checkpointNs, table.checkpointId],
|
|
47
|
+
}),
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Checkpoint writes table (PostgreSQL)
|
|
53
|
+
*/
|
|
54
|
+
export const checkpointWritesPg = pgTable(
|
|
55
|
+
'checkpoint_writes',
|
|
56
|
+
{
|
|
57
|
+
threadId: text('thread_id').notNull(),
|
|
58
|
+
checkpointNs: text('checkpoint_ns').default('').notNull(),
|
|
59
|
+
checkpointId: text('checkpoint_id').notNull(),
|
|
60
|
+
taskId: text('task_id').notNull(),
|
|
61
|
+
idx: integer('idx').notNull(),
|
|
62
|
+
channel: text('channel').notNull(),
|
|
63
|
+
type: text('type'),
|
|
64
|
+
value: jsonb('value'),
|
|
65
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
66
|
+
.defaultNow()
|
|
67
|
+
.notNull(),
|
|
68
|
+
},
|
|
69
|
+
(table) => ({
|
|
70
|
+
pk: primaryKey({
|
|
71
|
+
columns: [
|
|
72
|
+
table.threadId,
|
|
73
|
+
table.checkpointNs,
|
|
74
|
+
table.checkpointId,
|
|
75
|
+
table.taskId,
|
|
76
|
+
table.idx,
|
|
77
|
+
],
|
|
78
|
+
}),
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// =============================================================================
|
|
83
|
+
// SQLite Schema
|
|
84
|
+
// =============================================================================
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Checkpoints table (SQLite)
|
|
88
|
+
*/
|
|
89
|
+
export const checkpointsSqlite = sqliteTable(
|
|
90
|
+
'checkpoints',
|
|
91
|
+
{
|
|
92
|
+
threadId: sqliteText('thread_id').notNull(),
|
|
93
|
+
checkpointNs: sqliteText('checkpoint_ns').default('').notNull(),
|
|
94
|
+
checkpointId: sqliteText('checkpoint_id').notNull(),
|
|
95
|
+
parentCheckpointId: sqliteText('parent_checkpoint_id'),
|
|
96
|
+
type: sqliteText('type'),
|
|
97
|
+
checkpoint: sqliteText('checkpoint', { mode: 'json' })
|
|
98
|
+
.notNull()
|
|
99
|
+
.$type<Record<string, unknown>>(),
|
|
100
|
+
metadata: sqliteText('metadata', { mode: 'json' })
|
|
101
|
+
.notNull()
|
|
102
|
+
.$type<Record<string, unknown>>()
|
|
103
|
+
.default({}),
|
|
104
|
+
createdAt: sqliteInteger('created_at', { mode: 'timestamp' })
|
|
105
|
+
.notNull()
|
|
106
|
+
.$defaultFn(() => new Date()),
|
|
107
|
+
},
|
|
108
|
+
(table) => ({
|
|
109
|
+
pk: sqlitePrimaryKey({
|
|
110
|
+
columns: [table.threadId, table.checkpointNs, table.checkpointId],
|
|
111
|
+
}),
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Checkpoint writes table (SQLite)
|
|
117
|
+
*/
|
|
118
|
+
export const checkpointWritesSqlite = sqliteTable(
|
|
119
|
+
'checkpoint_writes',
|
|
120
|
+
{
|
|
121
|
+
threadId: sqliteText('thread_id').notNull(),
|
|
122
|
+
checkpointNs: sqliteText('checkpoint_ns').default('').notNull(),
|
|
123
|
+
checkpointId: sqliteText('checkpoint_id').notNull(),
|
|
124
|
+
taskId: sqliteText('task_id').notNull(),
|
|
125
|
+
idx: sqliteInteger('idx').notNull(),
|
|
126
|
+
channel: sqliteText('channel').notNull(),
|
|
127
|
+
type: sqliteText('type'),
|
|
128
|
+
value: sqliteText('value', { mode: 'json' }).$type<unknown>(),
|
|
129
|
+
createdAt: sqliteInteger('created_at', { mode: 'timestamp' })
|
|
130
|
+
.notNull()
|
|
131
|
+
.$defaultFn(() => new Date()),
|
|
132
|
+
},
|
|
133
|
+
(table) => ({
|
|
134
|
+
pk: sqlitePrimaryKey({
|
|
135
|
+
columns: [
|
|
136
|
+
table.threadId,
|
|
137
|
+
table.checkpointNs,
|
|
138
|
+
table.checkpointId,
|
|
139
|
+
table.taskId,
|
|
140
|
+
table.idx,
|
|
141
|
+
],
|
|
142
|
+
}),
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// =============================================================================
|
|
147
|
+
// TypeScript Types
|
|
148
|
+
// =============================================================================
|
|
149
|
+
|
|
150
|
+
export type CheckpointPg = typeof checkpointsPg.$inferSelect;
|
|
151
|
+
export type NewCheckpointPg = typeof checkpointsPg.$inferInsert;
|
|
152
|
+
export type CheckpointWritePg = typeof checkpointWritesPg.$inferSelect;
|
|
153
|
+
export type NewCheckpointWritePg = typeof checkpointWritesPg.$inferInsert;
|
|
154
|
+
|
|
155
|
+
export type CheckpointSqlite = typeof checkpointsSqlite.$inferSelect;
|
|
156
|
+
export type NewCheckpointSqlite = typeof checkpointsSqlite.$inferInsert;
|
|
157
|
+
export type CheckpointWriteSqlite = typeof checkpointWritesSqlite.$inferSelect;
|
|
158
|
+
export type NewCheckpointWriteSqlite = typeof checkpointWritesSqlite.$inferInsert;
|
|
159
|
+
|
|
160
|
+
// Unified types
|
|
161
|
+
export type Checkpoint = CheckpointPg | CheckpointSqlite;
|
|
162
|
+
export type NewCheckpoint = NewCheckpointPg | NewCheckpointSqlite;
|
|
163
|
+
export type CheckpointWrite = CheckpointWritePg | CheckpointWriteSqlite;
|
|
164
|
+
export type NewCheckpointWrite = NewCheckpointWritePg | NewCheckpointWriteSqlite;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversations Schema
|
|
3
|
+
*
|
|
4
|
+
* Drizzle ORM schema for conversations and messages tables.
|
|
5
|
+
* Supports both PostgreSQL and SQLite.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
pgTable,
|
|
10
|
+
uuid,
|
|
11
|
+
text,
|
|
12
|
+
timestamp,
|
|
13
|
+
jsonb,
|
|
14
|
+
index,
|
|
15
|
+
} from 'drizzle-orm/pg-core';
|
|
16
|
+
import {
|
|
17
|
+
sqliteTable,
|
|
18
|
+
text as sqliteText,
|
|
19
|
+
integer,
|
|
20
|
+
} from 'drizzle-orm/sqlite-core';
|
|
21
|
+
import { sql } from 'drizzle-orm';
|
|
22
|
+
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// PostgreSQL Schema
|
|
25
|
+
// =============================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Conversations table (PostgreSQL)
|
|
29
|
+
*/
|
|
30
|
+
export const conversationsPg = pgTable(
|
|
31
|
+
'conversations',
|
|
32
|
+
{
|
|
33
|
+
id: uuid('id')
|
|
34
|
+
.primaryKey()
|
|
35
|
+
.default(sql`gen_random_uuid()`),
|
|
36
|
+
threadId: text('thread_id').notNull(),
|
|
37
|
+
userId: text('user_id'),
|
|
38
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
39
|
+
.defaultNow()
|
|
40
|
+
.notNull(),
|
|
41
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
42
|
+
.defaultNow()
|
|
43
|
+
.notNull(),
|
|
44
|
+
},
|
|
45
|
+
(table) => ({
|
|
46
|
+
threadIdIdx: index('conversations_thread_id_idx').on(table.threadId),
|
|
47
|
+
userIdIdx: index('conversations_user_id_idx').on(table.userId),
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Messages table (PostgreSQL)
|
|
53
|
+
*/
|
|
54
|
+
export const messagesPg = pgTable(
|
|
55
|
+
'messages',
|
|
56
|
+
{
|
|
57
|
+
id: uuid('id')
|
|
58
|
+
.primaryKey()
|
|
59
|
+
.default(sql`gen_random_uuid()`),
|
|
60
|
+
conversationId: uuid('conversation_id')
|
|
61
|
+
.notNull()
|
|
62
|
+
.references(() => conversationsPg.id, { onDelete: 'cascade' }),
|
|
63
|
+
role: text('role').notNull(), // 'user' | 'assistant' | 'system'
|
|
64
|
+
content: text('content').notNull(),
|
|
65
|
+
metadata: jsonb('metadata').default({}).notNull(),
|
|
66
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
67
|
+
.defaultNow()
|
|
68
|
+
.notNull(),
|
|
69
|
+
},
|
|
70
|
+
(table) => ({
|
|
71
|
+
conversationIdIdx: index('messages_conversation_id_idx').on(
|
|
72
|
+
table.conversationId
|
|
73
|
+
),
|
|
74
|
+
createdAtIdx: index('messages_created_at_idx').on(table.createdAt),
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// =============================================================================
|
|
79
|
+
// SQLite Schema
|
|
80
|
+
// =============================================================================
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Conversations table (SQLite)
|
|
84
|
+
*/
|
|
85
|
+
export const conversationsSqlite = sqliteTable('conversations', {
|
|
86
|
+
id: sqliteText('id')
|
|
87
|
+
.primaryKey()
|
|
88
|
+
.$defaultFn(() => crypto.randomUUID()),
|
|
89
|
+
threadId: sqliteText('thread_id').notNull(),
|
|
90
|
+
userId: sqliteText('user_id'),
|
|
91
|
+
createdAt: integer('created_at', { mode: 'timestamp' })
|
|
92
|
+
.notNull()
|
|
93
|
+
.$defaultFn(() => new Date()),
|
|
94
|
+
updatedAt: integer('updated_at', { mode: 'timestamp' })
|
|
95
|
+
.notNull()
|
|
96
|
+
.$defaultFn(() => new Date()),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Messages table (SQLite)
|
|
101
|
+
*/
|
|
102
|
+
export const messagesSqlite = sqliteTable('messages', {
|
|
103
|
+
id: sqliteText('id')
|
|
104
|
+
.primaryKey()
|
|
105
|
+
.$defaultFn(() => crypto.randomUUID()),
|
|
106
|
+
conversationId: sqliteText('conversation_id')
|
|
107
|
+
.notNull()
|
|
108
|
+
.references(() => conversationsSqlite.id, { onDelete: 'cascade' }),
|
|
109
|
+
role: sqliteText('role').notNull(),
|
|
110
|
+
content: sqliteText('content').notNull(),
|
|
111
|
+
metadata: sqliteText('metadata', { mode: 'json' })
|
|
112
|
+
.notNull()
|
|
113
|
+
.$type<Record<string, unknown>>()
|
|
114
|
+
.default({}),
|
|
115
|
+
createdAt: integer('created_at', { mode: 'timestamp' })
|
|
116
|
+
.notNull()
|
|
117
|
+
.$defaultFn(() => new Date()),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// =============================================================================
|
|
121
|
+
// TypeScript Types
|
|
122
|
+
// =============================================================================
|
|
123
|
+
|
|
124
|
+
export type ConversationPg = typeof conversationsPg.$inferSelect;
|
|
125
|
+
export type NewConversationPg = typeof conversationsPg.$inferInsert;
|
|
126
|
+
export type MessagePg = typeof messagesPg.$inferSelect;
|
|
127
|
+
export type NewMessagePg = typeof messagesPg.$inferInsert;
|
|
128
|
+
|
|
129
|
+
export type ConversationSqlite = typeof conversationsSqlite.$inferSelect;
|
|
130
|
+
export type NewConversationSqlite = typeof conversationsSqlite.$inferInsert;
|
|
131
|
+
export type MessageSqlite = typeof messagesSqlite.$inferSelect;
|
|
132
|
+
export type NewMessageSqlite = typeof messagesSqlite.$inferInsert;
|
|
133
|
+
|
|
134
|
+
// Unified types
|
|
135
|
+
export type Conversation = ConversationPg | ConversationSqlite;
|
|
136
|
+
export type NewConversation = NewConversationPg | NewConversationSqlite;
|
|
137
|
+
export type Message = MessagePg | MessageSqlite;
|
|
138
|
+
export type NewMessage = NewMessagePg | NewMessageSqlite;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documents Schema
|
|
3
|
+
*
|
|
4
|
+
* Drizzle ORM schema for knowledge base documents and chunks.
|
|
5
|
+
* Supports vector embeddings for RAG (Retrieval Augmented Generation).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
pgTable,
|
|
10
|
+
uuid,
|
|
11
|
+
text,
|
|
12
|
+
integer,
|
|
13
|
+
timestamp,
|
|
14
|
+
jsonb,
|
|
15
|
+
index,
|
|
16
|
+
} from 'drizzle-orm/pg-core';
|
|
17
|
+
import {
|
|
18
|
+
sqliteTable,
|
|
19
|
+
text as sqliteText,
|
|
20
|
+
integer as sqliteInteger,
|
|
21
|
+
} from 'drizzle-orm/sqlite-core';
|
|
22
|
+
import { sql } from 'drizzle-orm';
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// PostgreSQL Schema
|
|
26
|
+
// =============================================================================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Documents table (PostgreSQL)
|
|
30
|
+
*/
|
|
31
|
+
export const documentsPg = pgTable(
|
|
32
|
+
'documents',
|
|
33
|
+
{
|
|
34
|
+
id: uuid('id')
|
|
35
|
+
.primaryKey()
|
|
36
|
+
.default(sql`gen_random_uuid()`),
|
|
37
|
+
userId: text('user_id'),
|
|
38
|
+
filename: text('filename').notNull(),
|
|
39
|
+
fileType: text('file_type'),
|
|
40
|
+
fileSize: integer('file_size'),
|
|
41
|
+
content: text('content'),
|
|
42
|
+
metadata: jsonb('metadata').default({}).notNull(),
|
|
43
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
44
|
+
.defaultNow()
|
|
45
|
+
.notNull(),
|
|
46
|
+
},
|
|
47
|
+
(table) => ({
|
|
48
|
+
userIdIdx: index('documents_user_id_idx').on(table.userId),
|
|
49
|
+
filenameIdx: index('documents_filename_idx').on(table.filename),
|
|
50
|
+
createdAtIdx: index('documents_created_at_idx').on(table.createdAt),
|
|
51
|
+
})
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Document chunks table (PostgreSQL)
|
|
56
|
+
*/
|
|
57
|
+
export const documentChunksPg = pgTable(
|
|
58
|
+
'document_chunks',
|
|
59
|
+
{
|
|
60
|
+
id: uuid('id')
|
|
61
|
+
.primaryKey()
|
|
62
|
+
.default(sql`gen_random_uuid()`),
|
|
63
|
+
documentId: uuid('document_id')
|
|
64
|
+
.notNull()
|
|
65
|
+
.references(() => documentsPg.id, { onDelete: 'cascade' }),
|
|
66
|
+
chunkIndex: integer('chunk_index').notNull(),
|
|
67
|
+
content: text('content').notNull(),
|
|
68
|
+
// pgvector embedding
|
|
69
|
+
embedding: text('embedding').notNull(),
|
|
70
|
+
metadata: jsonb('metadata').default({}).notNull(),
|
|
71
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
72
|
+
.defaultNow()
|
|
73
|
+
.notNull(),
|
|
74
|
+
},
|
|
75
|
+
(table) => ({
|
|
76
|
+
documentIdIdx: index('chunks_document_id_idx').on(table.documentId),
|
|
77
|
+
chunkIndexIdx: index('chunks_chunk_index_idx').on(table.chunkIndex),
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// =============================================================================
|
|
82
|
+
// SQLite Schema
|
|
83
|
+
// =============================================================================
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Documents table (SQLite)
|
|
87
|
+
*/
|
|
88
|
+
export const documentsSqlite = sqliteTable('documents', {
|
|
89
|
+
id: sqliteText('id')
|
|
90
|
+
.primaryKey()
|
|
91
|
+
.$defaultFn(() => crypto.randomUUID()),
|
|
92
|
+
userId: sqliteText('user_id'),
|
|
93
|
+
filename: sqliteText('filename').notNull(),
|
|
94
|
+
fileType: sqliteText('file_type'),
|
|
95
|
+
fileSize: sqliteInteger('file_size'),
|
|
96
|
+
content: sqliteText('content'),
|
|
97
|
+
metadata: sqliteText('metadata', { mode: 'json' })
|
|
98
|
+
.notNull()
|
|
99
|
+
.$type<Record<string, unknown>>()
|
|
100
|
+
.default({}),
|
|
101
|
+
createdAt: sqliteInteger('created_at', { mode: 'timestamp' })
|
|
102
|
+
.notNull()
|
|
103
|
+
.$defaultFn(() => new Date()),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Document chunks table (SQLite)
|
|
108
|
+
*/
|
|
109
|
+
export const documentChunksSqlite = sqliteTable('document_chunks', {
|
|
110
|
+
id: sqliteText('id')
|
|
111
|
+
.primaryKey()
|
|
112
|
+
.$defaultFn(() => crypto.randomUUID()),
|
|
113
|
+
documentId: sqliteText('document_id')
|
|
114
|
+
.notNull()
|
|
115
|
+
.references(() => documentsSqlite.id, { onDelete: 'cascade' }),
|
|
116
|
+
chunkIndex: sqliteInteger('chunk_index').notNull(),
|
|
117
|
+
content: sqliteText('content').notNull(),
|
|
118
|
+
embedding: sqliteText('embedding').notNull(),
|
|
119
|
+
metadata: sqliteText('metadata', { mode: 'json' })
|
|
120
|
+
.notNull()
|
|
121
|
+
.$type<Record<string, unknown>>()
|
|
122
|
+
.default({}),
|
|
123
|
+
createdAt: sqliteInteger('created_at', { mode: 'timestamp' })
|
|
124
|
+
.notNull()
|
|
125
|
+
.$defaultFn(() => new Date()),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// =============================================================================
|
|
129
|
+
// TypeScript Types
|
|
130
|
+
// =============================================================================
|
|
131
|
+
|
|
132
|
+
export type DocumentPg = typeof documentsPg.$inferSelect;
|
|
133
|
+
export type NewDocumentPg = typeof documentsPg.$inferInsert;
|
|
134
|
+
export type DocumentChunkPg = typeof documentChunksPg.$inferSelect;
|
|
135
|
+
export type NewDocumentChunkPg = typeof documentChunksPg.$inferInsert;
|
|
136
|
+
|
|
137
|
+
export type DocumentSqlite = typeof documentsSqlite.$inferSelect;
|
|
138
|
+
export type NewDocumentSqlite = typeof documentsSqlite.$inferInsert;
|
|
139
|
+
export type DocumentChunkSqlite = typeof documentChunksSqlite.$inferSelect;
|
|
140
|
+
export type NewDocumentChunkSqlite = typeof documentChunksSqlite.$inferInsert;
|
|
141
|
+
|
|
142
|
+
// Unified types
|
|
143
|
+
export type Document = DocumentPg | DocumentSqlite;
|
|
144
|
+
export type NewDocument = NewDocumentPg | NewDocumentSqlite;
|
|
145
|
+
export type DocumentChunk = DocumentChunkPg | DocumentChunkSqlite;
|
|
146
|
+
export type NewDocumentChunk = NewDocumentChunkPg | NewDocumentChunkSqlite;
|
|
147
|
+
|
|
148
|
+
// Parsed chunk with embedding array
|
|
149
|
+
export interface ParsedDocumentChunk {
|
|
150
|
+
id: string;
|
|
151
|
+
documentId: string;
|
|
152
|
+
chunkIndex: number;
|
|
153
|
+
content: string;
|
|
154
|
+
embedding: number[];
|
|
155
|
+
metadata: Record<string, unknown>;
|
|
156
|
+
createdAt: Date;
|
|
157
|
+
}
|