n8n-nodes-cosmosdb 0.1.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/LICENSE.md +19 -0
- package/README.md +490 -0
- package/dist/credentials/CosmosDbCredentialsApi.credentials.d.ts +9 -0
- package/dist/credentials/CosmosDbCredentialsApi.credentials.js +61 -0
- package/dist/credentials/CosmosDbCredentialsApi.credentials.js.map +1 -0
- package/dist/nodes/CosmosDb/CosmosDb.node.d.ts +11 -0
- package/dist/nodes/CosmosDb/CosmosDb.node.js +678 -0
- package/dist/nodes/CosmosDb/CosmosDb.node.js.map +1 -0
- package/dist/nodes/CosmosDb/database.svg +8 -0
- package/dist/nodes/CosmosDb/lightDatabase.svg +7 -0
- package/dist/nodes/MarkdownChunker/MarkdownChunker.node.d.ts +5 -0
- package/dist/nodes/MarkdownChunker/MarkdownChunker.node.js +514 -0
- package/dist/nodes/MarkdownChunker/MarkdownChunker.node.js.map +1 -0
- package/dist/nodes/MarkdownChunker/chunking.svg +5 -0
- package/dist/nodes/MarkdownChunker/lightChunking.svg +7 -0
- package/dist/package.json +57 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +57 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2022 n8n
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
# HKU Cosmos DB Custom Node for n8n
|
|
2
|
+
|
|
3
|
+
A custom n8n node for interacting with Azure Cosmos DB, featuring vector search capabilities, AI embedding integration, and hybrid search using Reciprocal Rank Fusion (RRF).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This custom node provides three main operations for working with Azure Cosmos DB:
|
|
8
|
+
|
|
9
|
+
1. **Select** - Query documents using SQL
|
|
10
|
+
2. **Create or Update** - Upsert documents with optional embeddings and metadata
|
|
11
|
+
3. **Hybrid Search** - Advanced search combining full-text and vector similarity using RRF
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
### Core Components
|
|
16
|
+
|
|
17
|
+
#### 1. Credentials (`HkuCosmosDbCredentialsApi.credentials.ts`)
|
|
18
|
+
|
|
19
|
+
Manages Azure Cosmos DB connection credentials:
|
|
20
|
+
|
|
21
|
+
- **Endpoint**: Your Cosmos DB account URI
|
|
22
|
+
- **Key**: Primary or secondary key for authentication
|
|
23
|
+
|
|
24
|
+
#### 2. Main Node (`HkuCosmosDbNode.node.ts`)
|
|
25
|
+
|
|
26
|
+
The primary node implementation with the following structure:
|
|
27
|
+
|
|
28
|
+
**Inputs:**
|
|
29
|
+
|
|
30
|
+
- **Main Input**: Standard n8n workflow data
|
|
31
|
+
- **Embedding Input** (Optional): Connection to an AI embedding model (OpenAI, Azure OpenAI, etc.)
|
|
32
|
+
|
|
33
|
+
**Outputs:**
|
|
34
|
+
|
|
35
|
+
- **Main Output**: Query results or operation confirmations
|
|
36
|
+
|
|
37
|
+
### How It Works
|
|
38
|
+
|
|
39
|
+
## Operation 1: Select
|
|
40
|
+
|
|
41
|
+
Executes SQL queries against your Cosmos DB container.
|
|
42
|
+
|
|
43
|
+
### Key Features:
|
|
44
|
+
|
|
45
|
+
- **SQL Query**: Write custom SQL queries to retrieve documents
|
|
46
|
+
- **Result Limiting**: Option to return all results or limit to a specific number
|
|
47
|
+
- **Simplify Output**: Automatically removes Cosmos DB internal fields (`_rid`, `_self`, `_etag`, `_attachments`, `_ts`)
|
|
48
|
+
- **Exclude Fields**: Custom field exclusion to reduce payload size
|
|
49
|
+
|
|
50
|
+
### Code Flow:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
1. Parse SQL query from parameters
|
|
54
|
+
2. Connect to Cosmos DB using SDK client
|
|
55
|
+
3. Execute query: container.items.query(sqlQuery).fetchAll()
|
|
56
|
+
4. Process results:
|
|
57
|
+
- Remove internal fields if simplifyOutput enabled
|
|
58
|
+
- Remove custom fields if excludeFields enabled
|
|
59
|
+
5. Return processed documents
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Example Use Case:
|
|
63
|
+
|
|
64
|
+
```sql
|
|
65
|
+
SELECT * FROM c WHERE c.category = 'research' ORDER BY c._ts DESC
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Operation 2: Create or Update (Upsert)
|
|
71
|
+
|
|
72
|
+
Inserts or updates documents in Cosmos DB with intelligent field additions.
|
|
73
|
+
|
|
74
|
+
### Key Features:
|
|
75
|
+
|
|
76
|
+
- **JSON Document Input**: Accepts JSON documents with required `id` and partition key fields
|
|
77
|
+
- **Add Embedding**: Automatically generate and add vector embeddings using connected AI model
|
|
78
|
+
- **Add Text**: Add text content to a specified field
|
|
79
|
+
- **Add Metadata**: Merge custom metadata into the document
|
|
80
|
+
|
|
81
|
+
### Code Flow:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
1. Parse JSON document from input
|
|
85
|
+
2. Validate document structure (id field required)
|
|
86
|
+
|
|
87
|
+
3. IF "Add Embedding" enabled:
|
|
88
|
+
- Get text content to embed
|
|
89
|
+
- Connect to AI embedding model via NodeConnectionTypes.AiEmbedding
|
|
90
|
+
- Generate embedding: await aiData.embedQuery(textToEmbed)
|
|
91
|
+
- Add vector to document: document[vectorFieldName] = embedding
|
|
92
|
+
|
|
93
|
+
4. IF "Add Text" enabled:
|
|
94
|
+
- Get text content from parameters
|
|
95
|
+
- Add to document: document[textFieldName] = textContent
|
|
96
|
+
|
|
97
|
+
5. IF "Add Metadata" enabled:
|
|
98
|
+
- Parse metadata key-value pairs
|
|
99
|
+
- Merge into document.metadata object
|
|
100
|
+
|
|
101
|
+
6. Validate partition key field exists
|
|
102
|
+
7. Execute upsert: container.items.upsert(document)
|
|
103
|
+
8. Return created/updated document
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Why This Matters:
|
|
107
|
+
|
|
108
|
+
- **Embeddings**: Enables vector similarity search by converting text to high-dimensional vectors
|
|
109
|
+
- **Text Field**: Stores original text alongside embeddings for retrieval and display
|
|
110
|
+
- **Metadata**: Adds structured metadata without modifying main document structure
|
|
111
|
+
|
|
112
|
+
### Example Workflow:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
Input Document:
|
|
116
|
+
{
|
|
117
|
+
"id": "doc-123",
|
|
118
|
+
"category": "AI",
|
|
119
|
+
"title": "Machine Learning Basics"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
With "Add Text" enabled (field: "text", content: "Introduction to ML"):
|
|
123
|
+
With "Add Embedding" enabled (field: "vector", text: "Introduction to ML"):
|
|
124
|
+
|
|
125
|
+
Output Document:
|
|
126
|
+
{
|
|
127
|
+
"id": "doc-123",
|
|
128
|
+
"category": "AI",
|
|
129
|
+
"title": "Machine Learning Basics",
|
|
130
|
+
"text": "Introduction to ML",
|
|
131
|
+
"vector": [0.123, -0.456, 0.789, ...] // 1536-dimensional vector
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Operation 3: Hybrid Search
|
|
138
|
+
|
|
139
|
+
Advanced search combining full-text search and vector similarity using Reciprocal Rank Fusion (RRF).
|
|
140
|
+
|
|
141
|
+
### What is RRF?
|
|
142
|
+
|
|
143
|
+
Reciprocal Rank Fusion is a technique that combines multiple ranking signals:
|
|
144
|
+
|
|
145
|
+
- **Full-Text Search**: Traditional keyword matching using `FullTextScore()`
|
|
146
|
+
- **Vector Search**: Semantic similarity using `VectorDistance()`
|
|
147
|
+
|
|
148
|
+
RRF formula: `RRF_score = 1/(k + rank)` for each ranking method, then sum the scores.
|
|
149
|
+
|
|
150
|
+
### Key Features:
|
|
151
|
+
|
|
152
|
+
- **Keyword Search**: Full-text search on indexed text fields
|
|
153
|
+
- **Semantic Search**: Vector similarity search using AI embeddings
|
|
154
|
+
- **Top K Results**: Control number of results returned
|
|
155
|
+
- **Partition Key Filtering**: Optional filtering by partition key
|
|
156
|
+
- **Simplify/Exclude Fields**: Control output format
|
|
157
|
+
|
|
158
|
+
### Code Flow:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
1. Get search parameters (keyword, searchQuery, topK)
|
|
162
|
+
|
|
163
|
+
2. Connect to AI embedding model
|
|
164
|
+
- Validate connection exists
|
|
165
|
+
- Generate embedding for search query: await aiData.embedQuery(searchQuery)
|
|
166
|
+
|
|
167
|
+
3. Build RRF SQL query:
|
|
168
|
+
- Escape special characters in keyword
|
|
169
|
+
- Convert embedding array to SQL literal: [0.1, 0.2, ...]
|
|
170
|
+
- Construct query:
|
|
171
|
+
SELECT TOP ${topK} * FROM c
|
|
172
|
+
ORDER BY RANK RRF(
|
|
173
|
+
FullTextScore(c.text, '${keywords}'),
|
|
174
|
+
VectorDistance(c.vector, ${embeddingArray})
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
4. Add partition key filter if specified:
|
|
178
|
+
WHERE c.${partitionKeyField} = '${partitionKeyValue}'
|
|
179
|
+
|
|
180
|
+
5. Execute query via Cosmos SDK: container.items.query(rrfQuery).fetchAll()
|
|
181
|
+
|
|
182
|
+
6. Process results:
|
|
183
|
+
- Remove internal fields if simplifyOutput enabled
|
|
184
|
+
- Remove custom fields if excludeFields enabled
|
|
185
|
+
|
|
186
|
+
7. Return ranked results
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Why Direct SQL Execution?
|
|
190
|
+
|
|
191
|
+
Previously, this node used Azure Functions to execute RRF queries. Now it uses **inline SQL with embedding literals**:
|
|
192
|
+
|
|
193
|
+
**Advantages:**
|
|
194
|
+
|
|
195
|
+
- ✅ No external dependencies (no Function App needed)
|
|
196
|
+
- ✅ Lower latency (direct SDK call)
|
|
197
|
+
- ✅ Reduced costs (no Function App hosting)
|
|
198
|
+
- ✅ Simpler architecture
|
|
199
|
+
|
|
200
|
+
**How It Works:**
|
|
201
|
+
The embedding vector is directly embedded in the SQL query as an array literal:
|
|
202
|
+
|
|
203
|
+
```sql
|
|
204
|
+
SELECT TOP 10 * FROM c
|
|
205
|
+
ORDER BY RANK RRF(
|
|
206
|
+
FullTextScore(c.text, 'machine learning'),
|
|
207
|
+
VectorDistance(c.vector, [0.123, -0.456, 0.789, ...])
|
|
208
|
+
)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Example Search:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
Keyword: "machine learning"
|
|
215
|
+
Search Query: "What is neural network?"
|
|
216
|
+
Top K: 10
|
|
217
|
+
|
|
218
|
+
Result: Documents ranked by combined relevance of:
|
|
219
|
+
1. Keyword match with "machine learning"
|
|
220
|
+
2. Semantic similarity to "What is neural network?"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## AI Agent Tool Integration
|
|
226
|
+
|
|
227
|
+
This node is designed to work as an **AI Agent Tool** in n8n workflows.
|
|
228
|
+
|
|
229
|
+
### Key Implementation Details:
|
|
230
|
+
|
|
231
|
+
#### Static vs Dynamic Inputs
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
// ✅ CORRECT - Static inputs (works as tool)
|
|
235
|
+
inputs: [
|
|
236
|
+
NodeConnectionTypes.Main,
|
|
237
|
+
{
|
|
238
|
+
displayName: 'Embedding',
|
|
239
|
+
type: NodeConnectionTypes.AiEmbedding,
|
|
240
|
+
required: false,
|
|
241
|
+
maxConnections: 1,
|
|
242
|
+
},
|
|
243
|
+
];
|
|
244
|
+
|
|
245
|
+
// ❌ WRONG - Dynamic inputs (breaks tool registration)
|
|
246
|
+
inputs: `={{...}}`; // Template expressions don't work for tools
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Why Static?**
|
|
250
|
+
|
|
251
|
+
- AI Agent tools are registered at startup, not runtime
|
|
252
|
+
- n8n needs to know connection types before workflow execution
|
|
253
|
+
- Static inputs with `required: false` provide flexibility
|
|
254
|
+
|
|
255
|
+
#### Connection Retrieval
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// Correct way to get embedding connection
|
|
259
|
+
const aiData = (await this.getInputConnectionData(NodeConnectionTypes.AiEmbedding, 0)) as {
|
|
260
|
+
embedQuery: (query: string) => Promise<number[]>;
|
|
261
|
+
};
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Tool Enablement
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
usableAsTool: true, // Enables node as AI Agent tool
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Workflow Example:
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
AI Agent → HKU Cosmos DB (Tool) → Connected Embedding Model
|
|
274
|
+
↓
|
|
275
|
+
User Query
|
|
276
|
+
↓
|
|
277
|
+
Agent decides to search knowledge base
|
|
278
|
+
↓
|
|
279
|
+
Calls HKU Cosmos DB hybrid search with query
|
|
280
|
+
↓
|
|
281
|
+
Embedding model generates vector
|
|
282
|
+
↓
|
|
283
|
+
RRF search executed
|
|
284
|
+
↓
|
|
285
|
+
Results returned to Agent
|
|
286
|
+
↓
|
|
287
|
+
Agent formulates response
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Technical Details
|
|
293
|
+
|
|
294
|
+
### Dependencies
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"@azure/cosmos": "^4.x",
|
|
299
|
+
"n8n-workflow": "^1.x"
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Connection Types
|
|
304
|
+
|
|
305
|
+
- `NodeConnectionTypes.Main`: Standard workflow data flow
|
|
306
|
+
- `NodeConnectionTypes.AiEmbedding`: AI embedding model connections (OpenAI, Azure OpenAI, etc.)
|
|
307
|
+
- `NodeConnectionTypes.AiTool`: Enables use as AI Agent tool
|
|
308
|
+
|
|
309
|
+
### Error Handling
|
|
310
|
+
|
|
311
|
+
The node implements comprehensive error handling:
|
|
312
|
+
|
|
313
|
+
- **Invalid JSON**: Validates document parsing in upsert operation
|
|
314
|
+
- **Missing ID**: Ensures documents have required `id` field
|
|
315
|
+
- **Missing Partition Key**: Validates partition key field exists
|
|
316
|
+
- **No Embedding Model**: Checks for connected embedding model when required
|
|
317
|
+
- **SQL Injection Protection**: Escapes special characters in queries
|
|
318
|
+
|
|
319
|
+
### Input Sanitization
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
// Double quote escaping for FullTextScore
|
|
323
|
+
const escapeDoubleQuotes = (s: string) => s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
324
|
+
|
|
325
|
+
// Single quote escaping for partition key values
|
|
326
|
+
const escapeSingleQuotes = (s: string) => s.replace(/'/g, "''");
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Installation
|
|
332
|
+
|
|
333
|
+
1. Clone this repository to your n8n custom nodes directory:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
~/.n8n/custom/
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
2. Install dependencies:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
cd ~/.n8n/custom/n8n-custom-hkunode
|
|
343
|
+
npm install
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
3. Restart n8n:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
n8n start
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
4. The node will appear in the n8n editor under "HKU Cosmos DB"
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Configuration
|
|
357
|
+
|
|
358
|
+
### 1. Set Up Credentials
|
|
359
|
+
|
|
360
|
+
- Navigate to Credentials in n8n
|
|
361
|
+
- Create new "HKU Cosmos DB API" credential
|
|
362
|
+
- Enter your Cosmos DB endpoint and key
|
|
363
|
+
|
|
364
|
+
### 2. Create Container with Vector Index
|
|
365
|
+
|
|
366
|
+
Your Cosmos DB container should have:
|
|
367
|
+
|
|
368
|
+
- **Full-text index** on text fields (for keyword search)
|
|
369
|
+
- **Vector index** on embedding fields (for semantic search)
|
|
370
|
+
|
|
371
|
+
Example index policy:
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"indexingMode": "consistent",
|
|
376
|
+
"automatic": true,
|
|
377
|
+
"includedPaths": [{ "path": "/*" }],
|
|
378
|
+
"vectorIndexes": [
|
|
379
|
+
{
|
|
380
|
+
"path": "/vector",
|
|
381
|
+
"type": "quantizedFlat"
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### 3. Connect Embedding Model
|
|
388
|
+
|
|
389
|
+
- Add an Embeddings node (OpenAI Embeddings, Azure OpenAI Embeddings, etc.)
|
|
390
|
+
- Connect it to the "Embedding" input of HKU Cosmos DB node
|
|
391
|
+
- Works for both Upsert and Hybrid Search operations
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Use Cases
|
|
396
|
+
|
|
397
|
+
### 1. **Knowledge Base Search**
|
|
398
|
+
|
|
399
|
+
- Store documents with text and embeddings
|
|
400
|
+
- Use hybrid search to find relevant information
|
|
401
|
+
- Combine with AI Agent for conversational search
|
|
402
|
+
|
|
403
|
+
### 2. **Document Management**
|
|
404
|
+
|
|
405
|
+
- Upsert documents with automatic embedding generation
|
|
406
|
+
- Query documents using SQL
|
|
407
|
+
- Maintain metadata alongside content
|
|
408
|
+
|
|
409
|
+
### 3. **Semantic Search Application**
|
|
410
|
+
|
|
411
|
+
- Index content with embeddings
|
|
412
|
+
- Enable natural language search
|
|
413
|
+
- Rank results by relevance (RRF)
|
|
414
|
+
|
|
415
|
+
### 4. **AI Agent Tool**
|
|
416
|
+
|
|
417
|
+
- Provide knowledge base access to AI agents
|
|
418
|
+
- Enable agents to search and retrieve information
|
|
419
|
+
- Combine multiple data sources in agent workflows
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Troubleshooting
|
|
424
|
+
|
|
425
|
+
### "No embedding model connected" Error
|
|
426
|
+
|
|
427
|
+
**Solution**: Connect an Embeddings node to the "Embedding" input
|
|
428
|
+
|
|
429
|
+
### "Document must include partition key field" Error
|
|
430
|
+
|
|
431
|
+
**Solution**: Ensure your document includes the partition key field defined in your container
|
|
432
|
+
|
|
433
|
+
### "Invalid JSON in Document field" Error
|
|
434
|
+
|
|
435
|
+
**Solution**: Validate your JSON syntax in the Item Content field
|
|
436
|
+
|
|
437
|
+
### Tool Not Appearing in AI Agent
|
|
438
|
+
|
|
439
|
+
**Solution**: Ensure `usableAsTool: true` is set and inputs are defined as static array (not dynamic template)
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## Development Notes
|
|
444
|
+
|
|
445
|
+
### File Structure
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
Hku-CosmosDB/
|
|
449
|
+
├── credentials/
|
|
450
|
+
│ └── HkuCosmosDbCredentialsApi.credentials.ts
|
|
451
|
+
├── nodes/
|
|
452
|
+
│ └── HkuCosmosDbNode/
|
|
453
|
+
│ └── HkuCosmosDbNode.node.ts
|
|
454
|
+
├── package.json
|
|
455
|
+
└── README.md
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Key Design Decisions
|
|
459
|
+
|
|
460
|
+
1. **Static Inputs**: Required for AI Agent tool compatibility
|
|
461
|
+
2. **Optional Embedding Input**: Allows flexibility across operations
|
|
462
|
+
3. **Direct SQL Execution**: Eliminates Azure Function dependency
|
|
463
|
+
4. **RRF Implementation**: Combines full-text and vector search effectively
|
|
464
|
+
5. **Field Simplification**: Reduces noise in output data
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Future Enhancements
|
|
469
|
+
|
|
470
|
+
Potential improvements:
|
|
471
|
+
|
|
472
|
+
- [ ] Batch operations support
|
|
473
|
+
- [ ] Custom RRF weighting parameters
|
|
474
|
+
- [ ] Multiple vector field support
|
|
475
|
+
- [ ] Query result caching
|
|
476
|
+
- [ ] Streaming results for large datasets
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## License
|
|
481
|
+
|
|
482
|
+
[Your License Here]
|
|
483
|
+
|
|
484
|
+
## Contributing
|
|
485
|
+
|
|
486
|
+
Contributions are welcome! Please submit issues and pull requests.
|
|
487
|
+
|
|
488
|
+
## Support
|
|
489
|
+
|
|
490
|
+
For questions or issues, please open a GitHub issue.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ICredentialDataDecryptedObject, ICredentialTestRequest, ICredentialType, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class CosmosDbCredentialsApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions>;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CosmosDbCredentialsApi = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
class CosmosDbCredentialsApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.name = 'cosmosDbApi';
|
|
8
|
+
this.displayName = 'Cosmos DB API';
|
|
9
|
+
this.documentationUrl = 'https://docs.microsoft.com/en-us/azure/cosmos-db/';
|
|
10
|
+
this.properties = [
|
|
11
|
+
{
|
|
12
|
+
displayName: 'Endpoint',
|
|
13
|
+
name: 'endpoint',
|
|
14
|
+
type: 'string',
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
placeholder: 'https://your-account.documents.azure.com:443/',
|
|
18
|
+
description: 'The Cosmos DB account endpoint URL',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Access Key',
|
|
22
|
+
name: 'key',
|
|
23
|
+
type: 'string',
|
|
24
|
+
typeOptions: {
|
|
25
|
+
password: true,
|
|
26
|
+
},
|
|
27
|
+
default: '',
|
|
28
|
+
required: true,
|
|
29
|
+
description: 'The primary or secondary key for your Cosmos DB account',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
this.test = {
|
|
33
|
+
request: {
|
|
34
|
+
baseURL: '={{$credentials.endpoint}}',
|
|
35
|
+
url: '/dbs',
|
|
36
|
+
method: 'GET',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async authenticate(credentials, requestOptions) {
|
|
41
|
+
const verb = (requestOptions.method || 'GET').toUpperCase();
|
|
42
|
+
const resourceType = 'dbs';
|
|
43
|
+
const resourceId = '';
|
|
44
|
+
const date = new Date().toUTCString();
|
|
45
|
+
const key = credentials.key;
|
|
46
|
+
const text = `${verb.toLowerCase()}\n${resourceType.toLowerCase()}\n${resourceId}\n${date.toLowerCase()}\n\n`;
|
|
47
|
+
const signature = (0, crypto_1.createHmac)('sha256', Buffer.from(key, 'base64'))
|
|
48
|
+
.update(text)
|
|
49
|
+
.digest('base64');
|
|
50
|
+
const authToken = `type=master&ver=1.0&sig=${signature}`;
|
|
51
|
+
requestOptions.headers = {
|
|
52
|
+
...requestOptions.headers,
|
|
53
|
+
Authorization: authToken,
|
|
54
|
+
'x-ms-date': date,
|
|
55
|
+
'x-ms-version': '2018-12-31',
|
|
56
|
+
};
|
|
57
|
+
return requestOptions;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.CosmosDbCredentialsApi = CosmosDbCredentialsApi;
|
|
61
|
+
//# sourceMappingURL=CosmosDbCredentialsApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CosmosDbCredentialsApi.credentials.js","sourceRoot":"","sources":["../../credentials/CosmosDbCredentialsApi.credentials.ts"],"names":[],"mappings":";;;AAOA,mCAAoC;AAEpC,MAAa,sBAAsB;IAAnC;QACC,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GAAG,eAAe,CAAC;QAC9B,qBAAgB,GAAG,mDAAmD,CAAC;QACvE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,+CAA+C;gBAC5D,WAAW,EAAE,oCAAoC;aACjD;YACD;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,yDAAyD;aACtE;SACD,CAAC;QAiCF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,4BAA4B;gBACrC,GAAG,EAAE,MAAM;gBACX,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;IAtCA,KAAK,CAAC,YAAY,CACjB,WAA2C,EAC3C,cAAmC;QAEnC,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5D,MAAM,YAAY,GAAG,KAAK,CAAC;QAC3B,MAAM,UAAU,GAAG,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAa,CAAC;QAGtC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,KAAK,UAAU,KAAK,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;QAG9G,MAAM,SAAS,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;aAChE,MAAM,CAAC,IAAI,CAAC;aACZ,MAAM,CAAC,QAAQ,CAAC,CAAC;QAGnB,MAAM,SAAS,GAAG,2BAA2B,SAAS,EAAE,CAAC;QAEzD,cAAc,CAAC,OAAO,GAAG;YACxB,GAAG,cAAc,CAAC,OAAO;YACzB,aAAa,EAAE,SAAS;YACxB,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,YAAY;SAC5B,CAAC;QAEF,OAAO,cAAc,CAAC;IACvB,CAAC;CASD;AAjED,wDAiEC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class CosmosDbNode implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
methods: {
|
|
6
|
+
loadOptions: {
|
|
7
|
+
getDatabases(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
8
|
+
getContainers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
}
|