family-ai-agent 1.0.6 → 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.
Files changed (147) hide show
  1. package/.letta/settings.local.json +3 -0
  2. package/dist/database/adapters/base-adapter.d.ts +81 -0
  3. package/dist/database/adapters/base-adapter.d.ts.map +1 -0
  4. package/dist/database/adapters/base-adapter.js +105 -0
  5. package/dist/database/adapters/base-adapter.js.map +1 -0
  6. package/dist/database/adapters/index.d.ts +49 -0
  7. package/dist/database/adapters/index.d.ts.map +1 -0
  8. package/dist/database/adapters/index.js +200 -0
  9. package/dist/database/adapters/index.js.map +1 -0
  10. package/dist/database/adapters/postgres-adapter.d.ts +75 -0
  11. package/dist/database/adapters/postgres-adapter.d.ts.map +1 -0
  12. package/dist/database/adapters/postgres-adapter.js +225 -0
  13. package/dist/database/adapters/postgres-adapter.js.map +1 -0
  14. package/dist/database/adapters/sqlite-adapter.d.ts +72 -0
  15. package/dist/database/adapters/sqlite-adapter.d.ts.map +1 -0
  16. package/dist/database/adapters/sqlite-adapter.js +368 -0
  17. package/dist/database/adapters/sqlite-adapter.js.map +1 -0
  18. package/dist/database/cache/cache-keys.d.ts +180 -0
  19. package/dist/database/cache/cache-keys.d.ts.map +1 -0
  20. package/dist/database/cache/cache-keys.js +107 -0
  21. package/dist/database/cache/cache-keys.js.map +1 -0
  22. package/dist/database/cache/index.d.ts +24 -0
  23. package/dist/database/cache/index.d.ts.map +1 -0
  24. package/dist/database/cache/index.js +34 -0
  25. package/dist/database/cache/index.js.map +1 -0
  26. package/dist/database/cache/query-cache.d.ts +67 -0
  27. package/dist/database/cache/query-cache.d.ts.map +1 -0
  28. package/dist/database/cache/query-cache.js +177 -0
  29. package/dist/database/cache/query-cache.js.map +1 -0
  30. package/dist/database/client.d.ts +63 -4
  31. package/dist/database/client.d.ts.map +1 -1
  32. package/dist/database/client.js +147 -59
  33. package/dist/database/client.js.map +1 -1
  34. package/dist/database/db-config.d.ts +104 -0
  35. package/dist/database/db-config.d.ts.map +1 -0
  36. package/dist/database/db-config.js +167 -0
  37. package/dist/database/db-config.js.map +1 -0
  38. package/dist/database/drizzle/index.d.ts +42 -0
  39. package/dist/database/drizzle/index.d.ts.map +1 -0
  40. package/dist/database/drizzle/index.js +48 -0
  41. package/dist/database/drizzle/index.js.map +1 -0
  42. package/dist/database/drizzle/schema/audit.d.ts +533 -0
  43. package/dist/database/drizzle/schema/audit.d.ts.map +1 -0
  44. package/dist/database/drizzle/schema/audit.js +71 -0
  45. package/dist/database/drizzle/schema/audit.js.map +1 -0
  46. package/dist/database/drizzle/schema/checkpoints.d.ts +665 -0
  47. package/dist/database/drizzle/schema/checkpoints.d.ts.map +1 -0
  48. package/dist/database/drizzle/schema/checkpoints.js +110 -0
  49. package/dist/database/drizzle/schema/checkpoints.js.map +1 -0
  50. package/dist/database/drizzle/schema/conversations.d.ts +449 -0
  51. package/dist/database/drizzle/schema/conversations.d.ts.map +1 -0
  52. package/dist/database/drizzle/schema/conversations.js +91 -0
  53. package/dist/database/drizzle/schema/conversations.js.map +1 -0
  54. package/dist/database/drizzle/schema/documents.d.ts +600 -0
  55. package/dist/database/drizzle/schema/documents.d.ts.map +1 -0
  56. package/dist/database/drizzle/schema/documents.js +100 -0
  57. package/dist/database/drizzle/schema/documents.js.map +1 -0
  58. package/dist/database/drizzle/schema/index.d.ts +3084 -0
  59. package/dist/database/drizzle/schema/index.d.ts.map +1 -0
  60. package/dist/database/drizzle/schema/index.js +46 -0
  61. package/dist/database/drizzle/schema/index.js.map +1 -0
  62. package/dist/database/drizzle/schema/memories.d.ts +435 -0
  63. package/dist/database/drizzle/schema/memories.d.ts.map +1 -0
  64. package/dist/database/drizzle/schema/memories.js +73 -0
  65. package/dist/database/drizzle/schema/memories.js.map +1 -0
  66. package/dist/database/drizzle/schema/tasks.d.ts +565 -0
  67. package/dist/database/drizzle/schema/tasks.d.ts.map +1 -0
  68. package/dist/database/drizzle/schema/tasks.js +84 -0
  69. package/dist/database/drizzle/schema/tasks.js.map +1 -0
  70. package/dist/database/health/circuit-breaker.d.ts +81 -0
  71. package/dist/database/health/circuit-breaker.d.ts.map +1 -0
  72. package/dist/database/health/circuit-breaker.js +184 -0
  73. package/dist/database/health/circuit-breaker.js.map +1 -0
  74. package/dist/database/health/health-monitor.d.ts +69 -0
  75. package/dist/database/health/health-monitor.d.ts.map +1 -0
  76. package/dist/database/health/health-monitor.js +174 -0
  77. package/dist/database/health/health-monitor.js.map +1 -0
  78. package/dist/database/health/index.d.ts +27 -0
  79. package/dist/database/health/index.d.ts.map +1 -0
  80. package/dist/database/health/index.js +23 -0
  81. package/dist/database/health/index.js.map +1 -0
  82. package/dist/database/index.d.ts +16 -0
  83. package/dist/database/index.d.ts.map +1 -0
  84. package/dist/database/index.js +41 -0
  85. package/dist/database/index.js.map +1 -0
  86. package/dist/database/migrations/index.d.ts +34 -0
  87. package/dist/database/migrations/index.d.ts.map +1 -0
  88. package/dist/database/migrations/index.js +45 -0
  89. package/dist/database/migrations/index.js.map +1 -0
  90. package/dist/database/migrations/migrator.d.ts +77 -0
  91. package/dist/database/migrations/migrator.d.ts.map +1 -0
  92. package/dist/database/migrations/migrator.js +258 -0
  93. package/dist/database/migrations/migrator.js.map +1 -0
  94. package/dist/database/migrations/versions/001_initial.d.ts +9 -0
  95. package/dist/database/migrations/versions/001_initial.d.ts.map +1 -0
  96. package/dist/database/migrations/versions/001_initial.js +183 -0
  97. package/dist/database/migrations/versions/001_initial.js.map +1 -0
  98. package/dist/database/types.d.ts +255 -0
  99. package/dist/database/types.d.ts.map +1 -0
  100. package/dist/database/types.js +8 -0
  101. package/dist/database/types.js.map +1 -0
  102. package/dist/database/vector/embedding-cache.d.ts +92 -0
  103. package/dist/database/vector/embedding-cache.d.ts.map +1 -0
  104. package/dist/database/vector/embedding-cache.js +185 -0
  105. package/dist/database/vector/embedding-cache.js.map +1 -0
  106. package/dist/database/vector/hnsw-index.d.ts +111 -0
  107. package/dist/database/vector/hnsw-index.d.ts.map +1 -0
  108. package/dist/database/vector/hnsw-index.js +337 -0
  109. package/dist/database/vector/hnsw-index.js.map +1 -0
  110. package/dist/database/vector/index.d.ts +75 -0
  111. package/dist/database/vector/index.d.ts.map +1 -0
  112. package/dist/database/vector/index.js +213 -0
  113. package/dist/database/vector/index.js.map +1 -0
  114. package/dist/database/vector/similarity.d.ts +67 -0
  115. package/dist/database/vector/similarity.d.ts.map +1 -0
  116. package/dist/database/vector/similarity.js +176 -0
  117. package/dist/database/vector/similarity.js.map +1 -0
  118. package/package.json +6 -3
  119. package/src/database/adapters/base-adapter.ts +171 -0
  120. package/src/database/adapters/index.ts +224 -0
  121. package/src/database/adapters/postgres-adapter.ts +285 -0
  122. package/src/database/adapters/sqlite-adapter.ts +420 -0
  123. package/src/database/cache/cache-keys.ts +150 -0
  124. package/src/database/cache/index.ts +44 -0
  125. package/src/database/cache/query-cache.ts +213 -0
  126. package/src/database/client.ts +166 -64
  127. package/src/database/db-config.ts +194 -0
  128. package/src/database/drizzle/index.ts +66 -0
  129. package/src/database/drizzle/schema/audit.ts +127 -0
  130. package/src/database/drizzle/schema/checkpoints.ts +164 -0
  131. package/src/database/drizzle/schema/conversations.ts +138 -0
  132. package/src/database/drizzle/schema/documents.ts +157 -0
  133. package/src/database/drizzle/schema/index.ts +139 -0
  134. package/src/database/drizzle/schema/memories.ts +127 -0
  135. package/src/database/drizzle/schema/tasks.ts +129 -0
  136. package/src/database/health/circuit-breaker.ts +214 -0
  137. package/src/database/health/health-monitor.ts +224 -0
  138. package/src/database/health/index.ts +41 -0
  139. package/src/database/index.ts +157 -0
  140. package/src/database/migrations/index.ts +52 -0
  141. package/src/database/migrations/migrator.ts +325 -0
  142. package/src/database/migrations/versions/001_initial.ts +198 -0
  143. package/src/database/types.ts +324 -0
  144. package/src/database/vector/embedding-cache.ts +234 -0
  145. package/src/database/vector/hnsw-index.ts +452 -0
  146. package/src/database/vector/index.ts +292 -0
  147. package/src/database/vector/similarity.ts +198 -0
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Database Configuration
3
+ *
4
+ * Configuration management for the database layer.
5
+ * Supports both PostgreSQL and SQLite with validation.
6
+ */
7
+
8
+ import { z } from 'zod';
9
+ import { homedir } from 'os';
10
+ import { join } from 'path';
11
+ import type { DatabaseConfig, DatabaseDetectionMode } from './types.js';
12
+
13
+ /**
14
+ * Database configuration schema with Zod validation
15
+ */
16
+ export const databaseConfigSchema = z.object({
17
+ // Detection mode
18
+ DATABASE_TYPE: z
19
+ .enum(['auto', 'postgresql', 'sqlite'])
20
+ .default('auto')
21
+ .describe('Database type selection mode'),
22
+
23
+ // PostgreSQL settings
24
+ DATABASE_URL: z
25
+ .string()
26
+ .url()
27
+ .optional()
28
+ .describe('Full PostgreSQL connection URL'),
29
+ DB_HOST: z.string().default('localhost').describe('PostgreSQL host'),
30
+ DB_PORT: z.coerce.number().default(5432).describe('PostgreSQL port'),
31
+ DB_USER: z.string().default('familyai').describe('PostgreSQL user'),
32
+ DB_PASSWORD: z.string().default('familyai123').describe('PostgreSQL password'),
33
+ DB_NAME: z.string().default('familyai').describe('PostgreSQL database name'),
34
+ DB_POOL_MAX: z.coerce.number().default(20).describe('Maximum pool connections'),
35
+ DB_POOL_IDLE_TIMEOUT_MS: z.coerce
36
+ .number()
37
+ .default(30000)
38
+ .describe('Pool idle timeout'),
39
+ DB_POOL_CONNECTION_TIMEOUT_MS: z.coerce
40
+ .number()
41
+ .default(5000)
42
+ .describe('Connection timeout'),
43
+
44
+ // SQLite settings
45
+ SQLITE_PATH: z
46
+ .string()
47
+ .optional()
48
+ .describe('SQLite database file path'),
49
+
50
+ // Health monitoring
51
+ DB_HEALTH_CHECK_INTERVAL_MS: z.coerce
52
+ .number()
53
+ .default(30000)
54
+ .describe('Health check interval'),
55
+ DB_CIRCUIT_BREAKER_THRESHOLD: z.coerce
56
+ .number()
57
+ .default(5)
58
+ .describe('Circuit breaker failure threshold'),
59
+ DB_CIRCUIT_BREAKER_TIMEOUT_MS: z.coerce
60
+ .number()
61
+ .default(60000)
62
+ .describe('Circuit breaker reset timeout'),
63
+
64
+ // Cache settings
65
+ DB_CACHE_MAX_SIZE: z.coerce
66
+ .number()
67
+ .default(1000)
68
+ .describe('Maximum cache entries'),
69
+ DB_CACHE_TTL_MS: z.coerce
70
+ .number()
71
+ .default(300000)
72
+ .describe('Cache TTL in milliseconds'),
73
+
74
+ // Vector settings
75
+ VECTOR_DIMENSION: z.coerce
76
+ .number()
77
+ .default(1536)
78
+ .describe('Embedding vector dimension'),
79
+ VECTOR_MIN_SIMILARITY: z.coerce
80
+ .number()
81
+ .default(0.7)
82
+ .describe('Minimum similarity threshold'),
83
+ });
84
+
85
+ export type RawDatabaseConfig = z.infer<typeof databaseConfigSchema>;
86
+
87
+ /**
88
+ * Default SQLite database path
89
+ */
90
+ export function getDefaultSqlitePath(): string {
91
+ return join(homedir(), '.family-ai-agent', 'data', 'family-ai.db');
92
+ }
93
+
94
+ /**
95
+ * Build PostgreSQL connection URL from config
96
+ */
97
+ export function buildPostgresUrl(config: RawDatabaseConfig): string {
98
+ if (config.DATABASE_URL) {
99
+ return config.DATABASE_URL;
100
+ }
101
+ return `postgresql://${config.DB_USER}:${config.DB_PASSWORD}@${config.DB_HOST}:${config.DB_PORT}/${config.DB_NAME}`;
102
+ }
103
+
104
+ /**
105
+ * Load and validate database configuration from environment
106
+ */
107
+ export function loadDatabaseConfig(
108
+ env: Record<string, string | undefined> = process.env
109
+ ): DatabaseConfig {
110
+ const parsed = databaseConfigSchema.safeParse(env);
111
+
112
+ if (!parsed.success) {
113
+ // Return defaults on validation failure
114
+ const defaults = databaseConfigSchema.parse({});
115
+ return convertToConfig(defaults);
116
+ }
117
+
118
+ return convertToConfig(parsed.data);
119
+ }
120
+
121
+ /**
122
+ * Convert raw config to DatabaseConfig interface
123
+ */
124
+ function convertToConfig(raw: RawDatabaseConfig): DatabaseConfig {
125
+ return {
126
+ type: raw.DATABASE_TYPE as DatabaseDetectionMode,
127
+
128
+ // PostgreSQL
129
+ postgresUrl: raw.DATABASE_URL,
130
+ postgresHost: raw.DB_HOST,
131
+ postgresPort: raw.DB_PORT,
132
+ postgresUser: raw.DB_USER,
133
+ postgresPassword: raw.DB_PASSWORD,
134
+ postgresDatabase: raw.DB_NAME,
135
+ postgresPoolMax: raw.DB_POOL_MAX,
136
+ postgresIdleTimeoutMs: raw.DB_POOL_IDLE_TIMEOUT_MS,
137
+ postgresConnectionTimeoutMs: raw.DB_POOL_CONNECTION_TIMEOUT_MS,
138
+
139
+ // SQLite
140
+ sqlitePath: raw.SQLITE_PATH ?? getDefaultSqlitePath(),
141
+
142
+ // Health monitoring
143
+ healthCheckIntervalMs: raw.DB_HEALTH_CHECK_INTERVAL_MS,
144
+ circuitBreakerThreshold: raw.DB_CIRCUIT_BREAKER_THRESHOLD,
145
+ circuitBreakerTimeoutMs: raw.DB_CIRCUIT_BREAKER_TIMEOUT_MS,
146
+
147
+ // Cache
148
+ cacheMaxSize: raw.DB_CACHE_MAX_SIZE,
149
+ cacheTtlMs: raw.DB_CACHE_TTL_MS,
150
+
151
+ // Vector
152
+ vectorDimension: raw.VECTOR_DIMENSION,
153
+ vectorMinSimilarity: raw.VECTOR_MIN_SIMILARITY,
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Global database configuration instance
159
+ */
160
+ let dbConfig: DatabaseConfig | null = null;
161
+
162
+ /**
163
+ * Get database configuration
164
+ */
165
+ export function getDatabaseConfig(): DatabaseConfig {
166
+ if (!dbConfig) {
167
+ dbConfig = loadDatabaseConfig();
168
+ }
169
+ return dbConfig;
170
+ }
171
+
172
+ /**
173
+ * Reset configuration (for testing)
174
+ */
175
+ export function resetDatabaseConfig(): void {
176
+ dbConfig = null;
177
+ }
178
+
179
+ /**
180
+ * Set custom configuration (for testing)
181
+ */
182
+ export function setDatabaseConfig(config: Partial<DatabaseConfig>): void {
183
+ const defaults = loadDatabaseConfig();
184
+ dbConfig = { ...defaults, ...config };
185
+ }
186
+
187
+ export default {
188
+ loadDatabaseConfig,
189
+ getDatabaseConfig,
190
+ resetDatabaseConfig,
191
+ setDatabaseConfig,
192
+ getDefaultSqlitePath,
193
+ buildPostgresUrl,
194
+ };
@@ -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;