@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.
- package/dist/index.cjs +351 -42
- package/dist/index.d.cts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +340 -38
- package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
- package/ee/python/README.md +295 -0
- package/ee/python/documents/processing/README.md +155 -0
- package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
- package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
- package/ee/python/setup.sh +180 -0
- package/package.json +14 -3
- package/scripts/postinstall.cjs +149 -0
- package/.agents/skills/mintlify/SKILL.md +0 -347
- package/.editorconfig +0 -15
- package/.eslintrc.json +0 -52
- package/.github/workflows/release-backend.yml +0 -38
- package/.husky/commit-msg +0 -1
- package/.jscpd.json +0 -18
- package/.mcp.json +0 -25
- package/.nvmrc +0 -1
- package/.prettierignore +0 -5
- package/.prettierrc.json +0 -12
- package/CHANGELOG.md +0 -8
- package/SECURITY.md +0 -5
- package/commitlint.config.js +0 -4
- package/devops/documentation/patch-older-releases.md +0 -42
- package/ee/documents/processing/build_pdf_processor.sh +0 -35
- package/ee/documents/processing/chunk_markdown.py +0 -263
- package/ee/documents/processing/pdf_processor.spec +0 -115
- package/eslint.config.js +0 -88
- package/jest.config.ts +0 -25
- package/mintlify-docs/.mintignore +0 -7
- package/mintlify-docs/AGENTS.md +0 -33
- package/mintlify-docs/CLAUDE.MD +0 -50
- package/mintlify-docs/CONTRIBUTING.md +0 -32
- package/mintlify-docs/LICENSE +0 -21
- package/mintlify-docs/README.md +0 -55
- package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
- package/mintlify-docs/ai-tools/cursor.mdx +0 -39
- package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
- package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
- package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
- package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
- package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
- package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
- package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
- package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
- package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
- package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
- package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
- package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
- package/mintlify-docs/api-reference/core-types.mdx +0 -585
- package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
- package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
- package/mintlify-docs/api-reference/introduction.mdx +0 -661
- package/mintlify-docs/api-reference/mutations.mdx +0 -1012
- package/mintlify-docs/api-reference/openapi.json +0 -217
- package/mintlify-docs/api-reference/queries.mdx +0 -1154
- package/mintlify-docs/backend/introduction.mdx +0 -218
- package/mintlify-docs/changelog.mdx +0 -387
- package/mintlify-docs/community-edition.mdx +0 -304
- package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
- package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
- package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
- package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
- package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
- package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
- package/mintlify-docs/core/exulu-authentication.mdx +0 -810
- package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
- package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
- package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
- package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
- package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
- package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
- package/mintlify-docs/core/exulu-database.mdx +0 -811
- package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
- package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
- package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
- package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
- package/mintlify-docs/core/exulu-logging.mdx +0 -464
- package/mintlify-docs/core/exulu-otel.mdx +0 -670
- package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
- package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
- package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
- package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
- package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
- package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
- package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
- package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
- package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
- package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
- package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
- package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
- package/mintlify-docs/development.mdx +0 -94
- package/mintlify-docs/docs.json +0 -248
- package/mintlify-docs/enterprise-edition.mdx +0 -538
- package/mintlify-docs/essentials/code.mdx +0 -35
- package/mintlify-docs/essentials/images.mdx +0 -59
- package/mintlify-docs/essentials/markdown.mdx +0 -88
- package/mintlify-docs/essentials/navigation.mdx +0 -87
- package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
- package/mintlify-docs/essentials/settings.mdx +0 -318
- package/mintlify-docs/favicon.svg +0 -3
- package/mintlify-docs/frontend/introduction.mdx +0 -39
- package/mintlify-docs/getting-started.mdx +0 -267
- package/mintlify-docs/guides/custom-agent.mdx +0 -608
- package/mintlify-docs/guides/first-agent.mdx +0 -315
- package/mintlify-docs/images/admin_ui.png +0 -0
- package/mintlify-docs/images/contexts.png +0 -0
- package/mintlify-docs/images/create_agents.png +0 -0
- package/mintlify-docs/images/evals.png +0 -0
- package/mintlify-docs/images/graphql.png +0 -0
- package/mintlify-docs/images/graphql_api.png +0 -0
- package/mintlify-docs/images/hero-dark.png +0 -0
- package/mintlify-docs/images/hero-light.png +0 -0
- package/mintlify-docs/images/hero.png +0 -0
- package/mintlify-docs/images/knowledge_sources.png +0 -0
- package/mintlify-docs/images/mcp.png +0 -0
- package/mintlify-docs/images/scaling.png +0 -0
- package/mintlify-docs/index.mdx +0 -411
- package/mintlify-docs/logo/dark.svg +0 -9
- package/mintlify-docs/logo/light.svg +0 -9
- package/mintlify-docs/partners.mdx +0 -558
- package/mintlify-docs/products.mdx +0 -77
- package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
- package/mintlify-docs/styles.css +0 -207
- package/ngrok.bash +0 -1
- package/ngrok.md +0 -6
- package/ngrok.yml +0 -10
- package/release.config.cjs +0 -15
- package/skills-lock.json +0 -10
- package/types/context-processor.ts +0 -45
- package/types/enums/eval-types.ts +0 -5
- package/types/enums/field-types.ts +0 -1
- package/types/enums/jobs.ts +0 -11
- package/types/enums/statistics.ts +0 -13
- package/types/exulu-table-definition.ts +0 -79
- package/types/file-types.ts +0 -18
- package/types/models/agent-session.ts +0 -27
- package/types/models/agent.ts +0 -68
- package/types/models/context.ts +0 -53
- package/types/models/embedding.ts +0 -17
- package/types/models/eval-run.ts +0 -40
- package/types/models/exulu-agent-tool-config.ts +0 -11
- package/types/models/item.ts +0 -21
- package/types/models/job.ts +0 -8
- package/types/models/project.ts +0 -16
- package/types/models/rate-limiter-rules.ts +0 -7
- package/types/models/test-case.ts +0 -25
- package/types/models/tool.ts +0 -9
- package/types/models/user-role.ts +0 -12
- package/types/models/user.ts +0 -20
- package/types/models/variable.ts +0 -8
- package/types/models/vector-methods.ts +0 -7
- package/types/provider-config.ts +0 -21
- package/types/queue-config.ts +0 -16
- package/types/rbac-rights-modes.ts +0 -1
- package/types/statistics.ts +0 -20
- package/types/workflow.ts +0 -31
- /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
- /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>
|