@exulu/backend 1.48.2 → 1.49.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 (164) hide show
  1. package/dist/index.cjs +351 -42
  2. package/dist/index.d.cts +96 -1
  3. package/dist/index.d.ts +96 -1
  4. package/dist/index.js +340 -38
  5. package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
  6. package/ee/python/README.md +295 -0
  7. package/ee/python/documents/processing/README.md +155 -0
  8. package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
  9. package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
  10. package/ee/python/setup.sh +180 -0
  11. package/package.json +14 -3
  12. package/scripts/postinstall.cjs +149 -0
  13. package/.agents/skills/mintlify/SKILL.md +0 -347
  14. package/.editorconfig +0 -15
  15. package/.eslintrc.json +0 -52
  16. package/.github/workflows/release-backend.yml +0 -38
  17. package/.husky/commit-msg +0 -1
  18. package/.jscpd.json +0 -18
  19. package/.mcp.json +0 -25
  20. package/.nvmrc +0 -1
  21. package/.prettierignore +0 -5
  22. package/.prettierrc.json +0 -12
  23. package/CHANGELOG.md +0 -8
  24. package/SECURITY.md +0 -5
  25. package/commitlint.config.js +0 -4
  26. package/devops/documentation/patch-older-releases.md +0 -42
  27. package/ee/documents/processing/build_pdf_processor.sh +0 -35
  28. package/ee/documents/processing/chunk_markdown.py +0 -263
  29. package/ee/documents/processing/pdf_processor.spec +0 -115
  30. package/eslint.config.js +0 -88
  31. package/jest.config.ts +0 -25
  32. package/mintlify-docs/.mintignore +0 -7
  33. package/mintlify-docs/AGENTS.md +0 -33
  34. package/mintlify-docs/CLAUDE.MD +0 -50
  35. package/mintlify-docs/CONTRIBUTING.md +0 -32
  36. package/mintlify-docs/LICENSE +0 -21
  37. package/mintlify-docs/README.md +0 -55
  38. package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
  39. package/mintlify-docs/ai-tools/cursor.mdx +0 -39
  40. package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
  41. package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
  42. package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
  43. package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
  44. package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
  45. package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
  46. package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
  47. package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
  48. package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
  49. package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
  50. package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
  51. package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
  52. package/mintlify-docs/api-reference/core-types.mdx +0 -585
  53. package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
  54. package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
  55. package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
  56. package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
  57. package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
  58. package/mintlify-docs/api-reference/introduction.mdx +0 -661
  59. package/mintlify-docs/api-reference/mutations.mdx +0 -1012
  60. package/mintlify-docs/api-reference/openapi.json +0 -217
  61. package/mintlify-docs/api-reference/queries.mdx +0 -1154
  62. package/mintlify-docs/backend/introduction.mdx +0 -218
  63. package/mintlify-docs/changelog.mdx +0 -387
  64. package/mintlify-docs/community-edition.mdx +0 -304
  65. package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
  66. package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
  67. package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
  68. package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
  69. package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
  70. package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
  71. package/mintlify-docs/core/exulu-authentication.mdx +0 -810
  72. package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
  73. package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
  74. package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
  75. package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
  76. package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
  77. package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
  78. package/mintlify-docs/core/exulu-database.mdx +0 -811
  79. package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
  80. package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
  81. package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
  82. package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
  83. package/mintlify-docs/core/exulu-logging.mdx +0 -464
  84. package/mintlify-docs/core/exulu-otel.mdx +0 -670
  85. package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
  86. package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
  87. package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
  88. package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
  89. package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
  90. package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
  91. package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
  92. package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
  93. package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
  94. package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
  95. package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
  96. package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
  97. package/mintlify-docs/development.mdx +0 -94
  98. package/mintlify-docs/docs.json +0 -248
  99. package/mintlify-docs/enterprise-edition.mdx +0 -538
  100. package/mintlify-docs/essentials/code.mdx +0 -35
  101. package/mintlify-docs/essentials/images.mdx +0 -59
  102. package/mintlify-docs/essentials/markdown.mdx +0 -88
  103. package/mintlify-docs/essentials/navigation.mdx +0 -87
  104. package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
  105. package/mintlify-docs/essentials/settings.mdx +0 -318
  106. package/mintlify-docs/favicon.svg +0 -3
  107. package/mintlify-docs/frontend/introduction.mdx +0 -39
  108. package/mintlify-docs/getting-started.mdx +0 -267
  109. package/mintlify-docs/guides/custom-agent.mdx +0 -608
  110. package/mintlify-docs/guides/first-agent.mdx +0 -315
  111. package/mintlify-docs/images/admin_ui.png +0 -0
  112. package/mintlify-docs/images/contexts.png +0 -0
  113. package/mintlify-docs/images/create_agents.png +0 -0
  114. package/mintlify-docs/images/evals.png +0 -0
  115. package/mintlify-docs/images/graphql.png +0 -0
  116. package/mintlify-docs/images/graphql_api.png +0 -0
  117. package/mintlify-docs/images/hero-dark.png +0 -0
  118. package/mintlify-docs/images/hero-light.png +0 -0
  119. package/mintlify-docs/images/hero.png +0 -0
  120. package/mintlify-docs/images/knowledge_sources.png +0 -0
  121. package/mintlify-docs/images/mcp.png +0 -0
  122. package/mintlify-docs/images/scaling.png +0 -0
  123. package/mintlify-docs/index.mdx +0 -411
  124. package/mintlify-docs/logo/dark.svg +0 -9
  125. package/mintlify-docs/logo/light.svg +0 -9
  126. package/mintlify-docs/partners.mdx +0 -558
  127. package/mintlify-docs/products.mdx +0 -77
  128. package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
  129. package/mintlify-docs/styles.css +0 -207
  130. package/ngrok.bash +0 -1
  131. package/ngrok.md +0 -6
  132. package/ngrok.yml +0 -10
  133. package/release.config.cjs +0 -15
  134. package/skills-lock.json +0 -10
  135. package/types/context-processor.ts +0 -45
  136. package/types/enums/eval-types.ts +0 -5
  137. package/types/enums/field-types.ts +0 -1
  138. package/types/enums/jobs.ts +0 -11
  139. package/types/enums/statistics.ts +0 -13
  140. package/types/exulu-table-definition.ts +0 -79
  141. package/types/file-types.ts +0 -18
  142. package/types/models/agent-session.ts +0 -27
  143. package/types/models/agent.ts +0 -68
  144. package/types/models/context.ts +0 -53
  145. package/types/models/embedding.ts +0 -17
  146. package/types/models/eval-run.ts +0 -40
  147. package/types/models/exulu-agent-tool-config.ts +0 -11
  148. package/types/models/item.ts +0 -21
  149. package/types/models/job.ts +0 -8
  150. package/types/models/project.ts +0 -16
  151. package/types/models/rate-limiter-rules.ts +0 -7
  152. package/types/models/test-case.ts +0 -25
  153. package/types/models/tool.ts +0 -9
  154. package/types/models/user-role.ts +0 -12
  155. package/types/models/user.ts +0 -20
  156. package/types/models/variable.ts +0 -8
  157. package/types/models/vector-methods.ts +0 -7
  158. package/types/provider-config.ts +0 -21
  159. package/types/queue-config.ts +0 -16
  160. package/types/rbac-rights-modes.ts +0 -1
  161. package/types/statistics.ts +0 -20
  162. package/types/workflow.ts +0 -31
  163. /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
  164. /package/ee/{documents/processing → python}/requirements.txt +0 -0
@@ -1,811 +0,0 @@
1
- ---
2
- title: "ExuluDatabase"
3
- description: "Database initialization and management utilities for Exulu IMP"
4
- ---
5
-
6
- ## Overview
7
-
8
- `ExuluDatabase` provides utilities for initializing and managing the Exulu IMP database schema. It handles core table creation, context-specific tables (items and chunks), default user setup, and API key generation.
9
-
10
- ## What is ExuluDatabase?
11
-
12
- ExuluDatabase offers essential database management functions:
13
-
14
- - **Schema initialization**: Creates all core Exulu IMP tables
15
- - **Schema updates**: Adds missing fields to existing tables
16
- - **Context tables**: Creates items and chunks tables for ExuluContext instances
17
- - **Default setup**: Creates admin user, roles, and default API key
18
- - **API key generation**: Generates secure API keys for programmatic access
19
-
20
- <CardGroup cols={3}>
21
- <Card title="Initialize schema" icon="database">
22
- Create all core database tables
23
- </Card>
24
- <Card title="Context tables" icon="table">
25
- Setup items/chunks tables for contexts
26
- </Card>
27
- <Card title="Generate API keys" icon="key">
28
- Create secure API keys for users
29
- </Card>
30
- </CardGroup>
31
-
32
- ## Quick start
33
-
34
- ```typescript
35
- import { ExuluDatabase, ExuluContext } from "@exulu/backend";
36
-
37
- // Define your contexts
38
- const contexts = [
39
- new ExuluContext({
40
- id: "documentation",
41
- name: "Documentation",
42
- description: "Product documentation",
43
- // ... context configuration
44
- })
45
- ];
46
-
47
- // Initialize database
48
- await ExuluDatabase.init({ contexts });
49
-
50
- // Generate API key
51
- const { key } = await ExuluDatabase.api.key.generate(
52
- "production-api",
53
- "api@example.com"
54
- );
55
-
56
- console.log(`API Key: ${key}`);
57
- ```
58
-
59
- ## Methods
60
-
61
- ### init()
62
-
63
- Initializes the Exulu IMP database schema and creates context-specific tables.
64
-
65
- ```typescript
66
- await ExuluDatabase.init({
67
- contexts: ExuluContext[]
68
- }): Promise<void>
69
- ```
70
-
71
- <ParamField path="contexts" type="ExuluContext[]" required>
72
- Array of ExuluContext instances for which to create items/chunks tables
73
- </ParamField>
74
-
75
- **What it does:**
76
-
77
- 1. **Creates core tables**:
78
- - `users` - User accounts (NextAuth compatible)
79
- - `roles` - Role-based access control
80
- - `agents` - Agent configurations
81
- - `agent_sessions` - Conversation sessions
82
- - `agent_messages` - Chat messages
83
- - `test_cases` - Evaluation test cases
84
- - `eval_sets` - Evaluation sets
85
- - `eval_runs` - Evaluation run results
86
- - `statistics` - Usage statistics
87
- - `variables` - Encrypted variable storage
88
- - `workflow_templates` - Workflow definitions
89
- - `projects` - Project organization
90
- - `job_results` - Background job results
91
- - `prompt_library` - Saved prompts
92
- - `embedder_settings` - Embedder configurations
93
- - `prompt_favorites` - Favorited prompts
94
- - `platform_configurations` - Platform settings
95
- - `rbac` - Role-based access control
96
- - `accounts` - NextAuth account linking
97
- - `verification_token` - NextAuth token verification
98
-
99
- 2. **Creates default roles**:
100
- - `admin` - Full write access to all resources
101
- - `default` - Read access with write access to agents
102
-
103
- 3. **Creates default admin user**:
104
- - Email: `admin@exulu.com`
105
- - Password: `admin`
106
- - Super admin privileges
107
-
108
- 4. **Generates default API key**:
109
- - Name: `exulu`
110
- - Email: `api@exulu.com`
111
- - Admin role
112
-
113
- 5. **Creates context tables**:
114
- - Items table for each context (for document storage)
115
- - Chunks table for each context with embedder (for vector search)
116
-
117
- **Example:**
118
-
119
- ```typescript
120
- import { ExuluDatabase, ExuluContext, ExuluEmbedder } from "@exulu/backend";
121
-
122
- const embedder = new ExuluEmbedder({
123
- id: "openai_embedder",
124
- name: "OpenAI Embedder",
125
- provider: "openai",
126
- model: "text-embedding-3-small",
127
- vectorDimensions: 1536,
128
- authenticationInformation: process.env.OPENAI_API_KEY
129
- });
130
-
131
- const contexts = [
132
- new ExuluContext({
133
- id: "docs",
134
- name: "Documentation",
135
- description: "Product documentation",
136
- embedder,
137
- tableName: "docs_items"
138
- }),
139
- new ExuluContext({
140
- id: "support",
141
- name: "Support Tickets",
142
- description: "Customer support conversations",
143
- tableName: "support_items"
144
- })
145
- ];
146
-
147
- // Initialize database with contexts
148
- await ExuluDatabase.init({ contexts });
149
-
150
- // Console output:
151
- // [EXULU] Checking Exulu IMP database status.
152
- // [EXULU] Creating agents table.
153
- // [EXULU] Creating users table.
154
- // [EXULU] Creating roles table.
155
- // ...
156
- // [EXULU] Creating default admin role.
157
- // [EXULU] Creating default admin user.
158
- // [EXULU] Creating default api user.
159
- // [EXULU] items table does not exist, creating it.
160
- // [EXULU] chunks table does not exist, creating it.
161
- // [EXULU] Database initialized.
162
- // [EXULU] Default api key: sk_abc123def456.../exulu
163
- // [EXULU] Default password if using password auth: admin
164
- // [EXULU] Default email if using password auth: admin@exulu.com
165
- ```
166
-
167
- **When to use:**
168
-
169
- - First time setting up Exulu IMP
170
- - Adding new ExuluContext instances that need database tables
171
- - Resetting database to default state
172
-
173
- <Note>
174
- Running `init()` multiple times is safe - it only creates tables and fields that don't exist. Existing data is preserved.
175
- </Note>
176
-
177
- ### update()
178
-
179
- Alias for `init()`. Updates the database schema by adding missing tables and fields.
180
-
181
- ```typescript
182
- await ExuluDatabase.update({
183
- contexts: ExuluContext[]
184
- }): Promise<void>
185
- ```
186
-
187
- <ParamField path="contexts" type="ExuluContext[]" required>
188
- Array of ExuluContext instances to update
189
- </ParamField>
190
-
191
- **Example:**
192
-
193
- ```typescript
194
- import { ExuluDatabase } from "@exulu/backend";
195
-
196
- // Add a new context to existing database
197
- const newContext = new ExuluContext({
198
- id: "new_context",
199
- name: "New Context",
200
- description: "New knowledge base"
201
- });
202
-
203
- await ExuluDatabase.update({ contexts: [newContext] });
204
- ```
205
-
206
- **Use cases:**
207
-
208
- - Adding new ExuluContext instances to an existing installation
209
- - Migrating to new Exulu IMP versions with schema changes
210
- - Ensuring database schema is up to date
211
-
212
- <Tip>
213
- Use `update()` when adding new contexts to an existing database. It's the same as `init()` but semantically clearer.
214
- </Tip>
215
-
216
- ### api.key.generate()
217
-
218
- Generates a secure API key for a user.
219
-
220
- ```typescript
221
- await ExuluDatabase.api.key.generate(
222
- name: string,
223
- email: string
224
- ): Promise<{ key: string }>
225
- ```
226
-
227
- <ParamField path="name" type="string" required>
228
- Human-readable name for the API key (used as identifier)
229
- </ParamField>
230
-
231
- <ParamField path="email" type="string" required>
232
- Email address for the API user
233
- </ParamField>
234
-
235
- <ResponseField name="key" type="string">
236
- Generated API key in format: `sk_{random_string}/{sanitized_name}`
237
-
238
- **Warning:** This is the only time the plain-text key is available. Store it securely.
239
- </ResponseField>
240
-
241
- **Example:**
242
-
243
- ```typescript
244
- import { ExuluDatabase } from "@exulu/backend";
245
-
246
- // Generate API key for production environment
247
- const { key } = await ExuluDatabase.api.key.generate(
248
- "Production API",
249
- "api-prod@example.com"
250
- );
251
-
252
- console.log(`API Key: ${key}`);
253
- // Output: API Key: sk_abc123def456_xyz789/production_api
254
-
255
- // Store this key securely - it cannot be retrieved later
256
- process.env.EXULU_API_KEY = key;
257
- ```
258
-
259
- **How it works:**
260
-
261
- 1. Generates random key: `sk_{random}_{random}`
262
- 2. Hashes the key using bcrypt (12 salt rounds)
263
- 3. Sanitizes the name (lowercase, underscores)
264
- 4. Stores hashed key with postfix: `{bcrypt_hash}/{sanitized_name}`
265
- 5. Creates API user with admin role
266
- 6. Returns plain-text key (only time it's accessible)
267
-
268
- **Key format:**
269
-
270
- - **Prefix**: `sk_` (secret key)
271
- - **Random strings**: Two random alphanumeric segments
272
- - **Postfix**: `/{sanitized_name}` (lowercase, underscores)
273
-
274
- **Example key:** `sk_9x7h3j2k5l8_4m6n1p9q8r/production_api`
275
-
276
- **Security:**
277
-
278
- <Warning>
279
- The plain-text API key is only returned once. Store it securely. The database stores only the bcrypt hash, making the key unrecoverable if lost.
280
- </Warning>
281
-
282
- ## Usage patterns
283
-
284
- ### First-time setup
285
-
286
- ```typescript
287
- import { ExuluDatabase, ExuluContext, ExuluEmbedder } from "@exulu/backend";
288
-
289
- async function setupExulu() {
290
- // Configure embedder
291
- const embedder = new ExuluEmbedder({
292
- id: "embedder",
293
- name: "Text Embedder",
294
- provider: "openai",
295
- model: "text-embedding-3-small",
296
- vectorDimensions: 1536,
297
- authenticationInformation: process.env.OPENAI_API_KEY
298
- });
299
-
300
- // Define contexts
301
- const contexts = [
302
- new ExuluContext({
303
- id: "docs",
304
- name: "Documentation",
305
- description: "Product documentation",
306
- embedder,
307
- tableName: "docs_items"
308
- }),
309
- new ExuluContext({
310
- id: "knowledge",
311
- name: "Knowledge Base",
312
- description: "Company knowledge base",
313
- embedder,
314
- tableName: "knowledge_items"
315
- })
316
- ];
317
-
318
- // Initialize database
319
- await ExuluDatabase.init({ contexts });
320
-
321
- console.log("Exulu IMP database initialized successfully!");
322
- }
323
-
324
- setupExulu().catch(console.error);
325
- ```
326
-
327
- ### Adding new context
328
-
329
- ```typescript
330
- import { ExuluDatabase, ExuluContext } from "@exulu/backend";
331
-
332
- async function addNewContext() {
333
- const newContext = new ExuluContext({
334
- id: "support",
335
- name: "Support Tickets",
336
- description: "Customer support conversations",
337
- tableName: "support_items"
338
- });
339
-
340
- // Update database with new context
341
- await ExuluDatabase.update({ contexts: [newContext] });
342
-
343
- console.log("New context added successfully!");
344
- }
345
- ```
346
-
347
- ### Generating API keys for team members
348
-
349
- ```typescript
350
- import { ExuluDatabase } from "@exulu/backend";
351
-
352
- async function provisionTeamApiKeys() {
353
- const team = [
354
- { name: "Frontend API", email: "api-frontend@example.com" },
355
- { name: "Backend Service", email: "api-backend@example.com" },
356
- { name: "Mobile App", email: "api-mobile@example.com" }
357
- ];
358
-
359
- const apiKeys = [];
360
-
361
- for (const member of team) {
362
- const { key } = await ExuluDatabase.api.key.generate(
363
- member.name,
364
- member.email
365
- );
366
-
367
- apiKeys.push({
368
- name: member.name,
369
- email: member.email,
370
- key
371
- });
372
-
373
- console.log(`Generated API key for ${member.name}`);
374
- }
375
-
376
- // Save keys to secure location
377
- console.log("API Keys:", JSON.stringify(apiKeys, null, 2));
378
-
379
- // IMPORTANT: Store these keys securely (e.g., in a secrets manager)
380
- // They cannot be retrieved later
381
- }
382
- ```
383
-
384
- ### Integration with ExuluApp
385
-
386
- ```typescript
387
- import { ExuluApp, ExuluDatabase, ExuluContext } from "@exulu/backend";
388
-
389
- async function setupApplication() {
390
- // Define contexts
391
- const documentationContext = new ExuluContext({
392
- id: "docs",
393
- name: "Documentation",
394
- description: "Product documentation",
395
- tableName: "docs_items"
396
- });
397
-
398
- // Initialize database
399
- await ExuluDatabase.init({ contexts: [documentationContext] });
400
-
401
- // Create ExuluApp
402
- const app = new ExuluApp();
403
- await app.create({
404
- config: {
405
- express: {
406
- enabled: true,
407
- port: 3000
408
- }
409
- },
410
- contexts: {
411
- docs: documentationContext
412
- },
413
- agents: {}
414
- });
415
-
416
- console.log("Application ready!");
417
- }
418
- ```
419
-
420
- ### CI/CD database setup
421
-
422
- ```typescript
423
- import { ExuluDatabase, ExuluContext } from "@exulu/backend";
424
-
425
- async function ciDatabaseSetup() {
426
- console.log("Setting up test database...");
427
-
428
- const contexts = [
429
- new ExuluContext({
430
- id: "test_context",
431
- name: "Test Context",
432
- description: "Testing context",
433
- tableName: "test_items"
434
- })
435
- ];
436
-
437
- try {
438
- await ExuluDatabase.init({ contexts });
439
-
440
- // Generate test API key
441
- const { key } = await ExuluDatabase.api.key.generate(
442
- "CI Test Key",
443
- "ci@test.com"
444
- );
445
-
446
- // Export for test suite
447
- process.env.TEST_API_KEY = key;
448
-
449
- console.log("Test database ready!");
450
- } catch (error) {
451
- console.error("Database setup failed:", error);
452
- process.exit(1);
453
- }
454
- }
455
-
456
- if (process.env.CI) {
457
- ciDatabaseSetup();
458
- }
459
- ```
460
-
461
- ## Database schema
462
-
463
- ### Core tables structure
464
-
465
- All core tables include:
466
- - `id` (UUID) - Primary key
467
- - `createdAt` (timestamp) - Creation timestamp
468
- - `updatedAt` (timestamp) - Last update timestamp
469
-
470
- ### Users table
471
-
472
- ```sql
473
- CREATE TABLE users (
474
- id SERIAL PRIMARY KEY,
475
- "createdAt" TIMESTAMP DEFAULT NOW(),
476
- "updatedAt" TIMESTAMP DEFAULT NOW(),
477
- name VARCHAR(255),
478
- password VARCHAR(255),
479
- email VARCHAR(255),
480
- "emailVerified" TIMESTAMP,
481
- image TEXT,
482
- type VARCHAR(10), -- 'api' or 'user'
483
- apikey TEXT, -- Format: {bcrypt_hash}/{key_name}
484
- role UUID, -- Foreign key to roles table
485
- super_admin BOOLEAN
486
- );
487
- ```
488
-
489
- ### Roles table
490
-
491
- ```sql
492
- CREATE TABLE roles (
493
- id UUID PRIMARY KEY,
494
- "createdAt" TIMESTAMP DEFAULT NOW(),
495
- "updatedAt" TIMESTAMP DEFAULT NOW(),
496
- name VARCHAR(255),
497
- agents VARCHAR(10), -- 'read' or 'write'
498
- evals VARCHAR(10),
499
- workflows VARCHAR(10),
500
- variables VARCHAR(10),
501
- users VARCHAR(10),
502
- api VARCHAR(10)
503
- );
504
- ```
505
-
506
- ### Context tables
507
-
508
- **Items table** (created for each ExuluContext):
509
-
510
- ```sql
511
- CREATE TABLE {context.tableName} (
512
- id UUID PRIMARY KEY,
513
- "createdAt" TIMESTAMP DEFAULT NOW(),
514
- "updatedAt" TIMESTAMP DEFAULT NOW(),
515
- -- Additional fields from context schema
516
- );
517
- ```
518
-
519
- **Chunks table** (created for contexts with embedders):
520
-
521
- ```sql
522
- CREATE TABLE {context.tableName}_chunks (
523
- id UUID PRIMARY KEY,
524
- "createdAt" TIMESTAMP DEFAULT NOW(),
525
- "updatedAt" TIMESTAMP DEFAULT NOW(),
526
- item_id UUID, -- Foreign key to items table
527
- content TEXT,
528
- embedding VECTOR({dimensions}), -- pgvector extension
529
- metadata JSONB
530
- );
531
- ```
532
-
533
- ## Default credentials
534
-
535
- After running `ExuluDatabase.init()`, the following default credentials are created:
536
-
537
- <AccordionGroup>
538
- <Accordion title="Default admin user">
539
- **Email:** `admin@exulu.com`
540
- **Password:** `admin`
541
- **Role:** admin (full write access)
542
- **Super admin:** Yes
543
-
544
- <Warning>
545
- Change the default password immediately in production environments.
546
- </Warning>
547
- </Accordion>
548
-
549
- <Accordion title="Default API key">
550
- **Name:** `exulu`
551
- **Email:** `api@exulu.com`
552
- **Role:** admin (full write access)
553
- **Format:** `sk_{random}_{random}/exulu`
554
-
555
- The key is printed to console during initialization:
556
- ```
557
- [EXULU] Default api key: sk_abc123def456.../exulu
558
- ```
559
-
560
- <Warning>
561
- Save this key securely. It cannot be retrieved later.
562
- </Warning>
563
- </Accordion>
564
-
565
- <Accordion title="Default roles">
566
- **Admin role:**
567
- - agents: write
568
- - evals: write
569
- - workflows: write
570
- - variables: write
571
- - users: write
572
- - api: write
573
-
574
- **Default role:**
575
- - agents: write
576
- - evals: read
577
- - workflows: read
578
- - variables: read
579
- - users: read
580
- - api: read
581
- </Accordion>
582
- </AccordionGroup>
583
-
584
- ## Environment variables
585
-
586
- ExuluDatabase uses these environment variables:
587
-
588
- <ParamField path="DATABASE_URL" type="string" required>
589
- PostgreSQL connection string
590
-
591
- **Format:** `postgresql://user:password@host:port/database`
592
-
593
- **Example:** `postgresql://exulu:password@localhost:5432/exulu_db`
594
- </ParamField>
595
-
596
- <ParamField path="NEXTAUTH_SECRET" type="string" required>
597
- Secret key for NextAuth session encryption
598
-
599
- **Used for:** Password hashing, session tokens, encrypted variables
600
-
601
- **Generate:** `openssl rand -base64 32`
602
- </ParamField>
603
-
604
- ## Error handling
605
-
606
- ```typescript
607
- import { ExuluDatabase, ExuluContext } from "@exulu/backend";
608
-
609
- async function safeInit() {
610
- try {
611
- const contexts = [
612
- new ExuluContext({
613
- id: "docs",
614
- name: "Documentation",
615
- description: "Docs",
616
- tableName: "docs_items"
617
- })
618
- ];
619
-
620
- await ExuluDatabase.init({ contexts });
621
- console.log("Database initialized successfully!");
622
- } catch (error) {
623
- if (error.code === "ECONNREFUSED") {
624
- console.error("Cannot connect to database. Is PostgreSQL running?");
625
- } else if (error.code === "42P07") {
626
- console.error("Table already exists. Use update() instead of init().");
627
- } else {
628
- console.error("Database initialization failed:", error.message);
629
- }
630
- throw error;
631
- }
632
- }
633
- ```
634
-
635
- **Common errors:**
636
-
637
- - `ECONNREFUSED` - Database connection failed
638
- - `42P07` - Table already exists
639
- - `3D000` - Database does not exist
640
- - `28P01` - Authentication failed
641
-
642
- ## Migration from previous versions
643
-
644
- If upgrading from an older version of Exulu IMP:
645
-
646
- ```typescript
647
- import { ExuluDatabase } from "@exulu/backend";
648
-
649
- async function migrate() {
650
- // Run update to add missing tables/fields
651
- await ExuluDatabase.update({ contexts });
652
-
653
- console.log("Database migrated to latest schema!");
654
- }
655
- ```
656
-
657
- **What `update()` does:**
658
-
659
- 1. Checks for missing tables and creates them
660
- 2. Checks for missing fields in existing tables
661
- 3. Adds missing fields without affecting existing data
662
- 4. Creates new context tables if needed
663
-
664
- <Note>
665
- Database migrations are non-destructive. Existing data is preserved.
666
- </Note>
667
-
668
- ## Best practices
669
-
670
- <Tip>
671
- **Run init() on startup**: Initialize the database on application startup to ensure schema is up to date.
672
- </Tip>
673
-
674
- <Note>
675
- **Context management**: Always pass all ExuluContext instances to `init()` or `update()` to ensure all tables exist.
676
- </Note>
677
-
678
- <Warning>
679
- **Secure API keys**: Store generated API keys in a secrets manager. They cannot be retrieved from the database.
680
- </Warning>
681
-
682
- <Info>
683
- **Default credentials**: Change default admin password and API key in production environments.
684
- </Info>
685
-
686
- ## Integration with other Exulu components
687
-
688
- ### With ExuluContext
689
-
690
- ```typescript
691
- const context = new ExuluContext({
692
- id: "docs",
693
- name: "Documentation",
694
- description: "Product docs",
695
- tableName: "docs_items"
696
- });
697
-
698
- // Initialize creates the items table
699
- await ExuluDatabase.init({ contexts: [context] });
700
-
701
- // Now you can use the context
702
- await context.addItem({
703
- content: "Product documentation...",
704
- metadata: { source: "docs.example.com" }
705
- });
706
- ```
707
-
708
- ### With ExuluAuthentication
709
-
710
- ```typescript
711
- import { ExuluDatabase, ExuluAuthentication, postgresClient } from "@exulu/backend";
712
-
713
- // Generate API key
714
- const { key } = await ExuluDatabase.api.key.generate(
715
- "Service API",
716
- "service@example.com"
717
- );
718
-
719
- // Use API key for authentication
720
- const { db } = await postgresClient();
721
- const result = await ExuluAuthentication.authenticate({
722
- apikey: key,
723
- db
724
- });
725
-
726
- console.log(`Authenticated as: ${result.user?.email}`);
727
- ```
728
-
729
- ### With ExuluVariables
730
-
731
- ```typescript
732
- import { ExuluDatabase, ExuluVariables, postgresClient } from "@exulu/backend";
733
-
734
- // Initialize database (creates variables table)
735
- await ExuluDatabase.init({ contexts: [] });
736
-
737
- // Store encrypted variable
738
- const { db } = await postgresClient();
739
- await db.from("variables").insert({
740
- name: "openai_api_key",
741
- value: encryptedValue,
742
- encrypted: true
743
- });
744
-
745
- // Retrieve variable
746
- const apiKey = await ExuluVariables.get("openai_api_key");
747
- ```
748
-
749
- ## Troubleshooting
750
-
751
- <AccordionGroup>
752
- <Accordion title="Database connection fails">
753
- **Error:** `ECONNREFUSED` or `ETIMEDOUT`
754
-
755
- **Solutions:**
756
- 1. Verify PostgreSQL is running: `pg_isready`
757
- 2. Check `DATABASE_URL` environment variable
758
- 3. Verify network connectivity to database host
759
- 4. Check firewall rules allow PostgreSQL port (default: 5432)
760
- </Accordion>
761
-
762
- <Accordion title="Tables already exist">
763
- **Error:** `table "users" already exists`
764
-
765
- **Solutions:**
766
- - Use `update()` instead of `init()` for existing databases
767
- - `init()` is safe to run multiple times (checks existence first)
768
- - If seeing this error, there may be a race condition (multiple processes initializing simultaneously)
769
- </Accordion>
770
-
771
- <Accordion title="Missing pgvector extension">
772
- **Error:** `type "vector" does not exist`
773
-
774
- **Solutions:**
775
- 1. Install pgvector extension in PostgreSQL
776
- 2. Enable extension in your database:
777
- ```sql
778
- CREATE EXTENSION IF NOT EXISTS vector;
779
- ```
780
- 3. Verify installation: `SELECT * FROM pg_extension WHERE extname = 'vector';`
781
- </Accordion>
782
-
783
- <Accordion title="Permission denied">
784
- **Error:** `permission denied for schema public`
785
-
786
- **Solutions:**
787
- 1. Grant necessary permissions:
788
- ```sql
789
- GRANT ALL ON SCHEMA public TO your_user;
790
- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO your_user;
791
- ```
792
- 2. Use a database user with CREATE TABLE privileges
793
- </Accordion>
794
- </AccordionGroup>
795
-
796
- ## Next steps
797
-
798
- <CardGroup cols={2}>
799
- <Card title="ExuluContext" icon="database" href="/core/exulu-context/introduction">
800
- Create knowledge bases with context-specific tables
801
- </Card>
802
- <Card title="ExuluAuthentication" icon="shield" href="/core/exulu-authentication">
803
- Use generated API keys for authentication
804
- </Card>
805
- <Card title="ExuluVariables" icon="key" href="/core/exulu-variables/introduction">
806
- Store encrypted configuration variables
807
- </Card>
808
- <Card title="ExuluApp" icon="box" href="/core/exulu-app/introduction">
809
- Build applications with initialized database
810
- </Card>
811
- </CardGroup>