@rcrsr/rill-ext-chroma 0.8.6 → 0.11.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/README.md CHANGED
@@ -38,230 +38,16 @@ const result = await execute(parse(script), ctx);
38
38
  dispose?.();
39
39
  ```
40
40
 
41
- ## Host Functions
42
-
43
- All vector database extensions share identical function signatures. Swap `chroma::` for `qdrant::` or `pinecone::` with no script changes.
44
-
45
- ### chroma::upsert(id, vector, metadata?)
46
-
47
- Insert or update a single vector with metadata.
48
-
49
- ```rill
50
- chroma::upsert("doc-1", $embedding, [title: "Example", page: 1]) => $result
51
- $result.id -> log # "doc-1"
52
- $result.success -> log # true
53
- ```
54
-
55
- **Idempotent.** Duplicate ID overwrites existing vector.
56
-
57
- ### chroma::upsert_batch(items)
58
-
59
- Batch insert or update vectors. Processes sequentially; halts on first failure.
60
-
61
- ```rill
62
- chroma::upsert_batch([
63
- [id: "doc-1", vector: $v1, metadata: [title: "First"]],
64
- [id: "doc-2", vector: $v2, metadata: [title: "Second"]]
65
- ]) => $result
66
- $result.succeeded -> log # 2
67
- ```
68
-
69
- Returns `{ succeeded }` on success. Returns `{ succeeded, failed, error }` on failure.
70
-
71
- ### chroma::search(vector, options?)
72
-
73
- Search for k nearest neighbors.
74
-
75
- ```rill
76
- chroma::search($embedding, [k: 5, score_threshold: 0.8]) => $results
77
- $results -> each { "{.id}: {.score}" -> log }
78
- ```
79
-
80
- | Option | Type | Default | Description |
81
- |--------|------|---------|-------------|
82
- | `k` | number | `10` | Max results to return |
83
- | `filter` | dict | `{}` | Metadata filter conditions |
84
- | `score_threshold` | number | (none) | Exclude results below threshold |
85
-
86
- Returns `[{ id, score, metadata }]`. Empty results return `[]`.
87
-
88
- ### chroma::get(id)
89
-
90
- Fetch a vector by ID.
91
-
92
- ```rill
93
- chroma::get("doc-1") => $point
94
- $point.id -> log # "doc-1"
95
- $point.metadata -> log # [title: "Example", page: 1]
96
- ```
97
-
98
- Returns `{ id, vector, metadata }`. Halts with error if ID not found.
99
-
100
- ### chroma::delete(id)
101
-
102
- Delete a vector by ID.
103
-
104
- ```rill
105
- chroma::delete("doc-1") => $result
106
- $result.deleted -> log # true
107
- ```
108
-
109
- Returns `{ id, deleted }`. Halts with error if ID not found.
110
-
111
- ### chroma::delete_batch(ids)
112
-
113
- Batch delete vectors. Processes sequentially; halts on first failure.
114
-
115
- ```rill
116
- chroma::delete_batch(["doc-1", "doc-2", "doc-3"]) => $result
117
- $result.succeeded -> log # 3
118
- ```
119
-
120
- Returns `{ succeeded }` on success. Returns `{ succeeded, failed, error }` on failure.
121
-
122
- ### chroma::count()
123
-
124
- Count vectors in the collection.
125
-
126
- ```rill
127
- chroma::count() -> log # 42
128
- ```
129
-
130
- Returns a number.
131
-
132
- ### chroma::create_collection(name, options?)
133
-
134
- Create a new collection.
135
-
136
- ```rill
137
- chroma::create_collection("my_vectors", [dimensions: 384, distance: "cosine"]) => $result
138
- $result.created -> log # true
139
- ```
140
-
141
- | Option | Type | Default | Description |
142
- |--------|------|---------|-------------|
143
- | `dimensions` | number | (none) | Vector dimension size |
144
- | `distance` | string | `"cosine"` | `"cosine"`, `"euclidean"`, or `"dot"` |
145
-
146
- Returns `{ name, created }`. **Not idempotent** — halts if collection exists.
147
-
148
- ### chroma::delete_collection(id)
149
-
150
- Delete a collection.
151
-
152
- ```rill
153
- chroma::delete_collection("old_vectors") => $result
154
- $result.deleted -> log # true
155
- ```
156
-
157
- Returns `{ name, deleted }`. **Not idempotent** — halts if collection not found.
158
-
159
- ### chroma::list_collections()
160
-
161
- List all collection names.
162
-
163
- ```rill
164
- chroma::list_collections() -> log # ["my_vectors", "archive"]
165
- ```
166
-
167
- Returns a list of strings.
168
-
169
- ### chroma::describe()
170
-
171
- Describe the configured collection.
172
-
173
- ```rill
174
- chroma::describe() => $info
175
- $info.name -> log # "my_vectors"
176
- $info.count -> log # 42
177
- $info.dimensions -> log # 384
178
- $info.distance -> log # "cosine"
179
- ```
180
-
181
- Returns `{ name, count, dimensions, distance }`.
182
-
183
- ## Configuration
184
-
185
- ```typescript
186
- const ext = createChromaExtension({
187
- url: 'http://localhost:8000',
188
- collection: 'my_vectors',
189
- embeddingFunction: 'openai',
190
- timeout: 30000,
191
- });
192
- ```
193
-
194
- | Option | Type | Default | Description |
195
- |--------|------|---------|-------------|
196
- | `url` | string | undefined | ChromaDB API endpoint (undefined uses embedded mode) |
197
- | `collection` | string | required | Default collection name |
198
- | `embeddingFunction` | string | undefined | Embedding function name |
199
- | `timeout` | number | SDK default | Request timeout in ms |
200
-
201
- ## Error Handling
202
-
203
- All errors use `RuntimeError('RILL-R004', 'chroma: <message>')` and halt script execution.
204
-
205
- | Condition | Message |
206
- |-----------|---------|
207
- | HTTP 401 | `chroma: authentication failed (401)` |
208
- | Collection not found | `chroma: collection not found` |
209
- | Rate limit (429) | `chroma: rate limit exceeded` |
210
- | Timeout | `chroma: request timeout` |
211
- | Dimension mismatch | `chroma: dimension mismatch (expected N, got M)` |
212
- | Collection exists | `chroma: collection already exists` |
213
- | ID not found | `chroma: id not found` |
214
- | After dispose | `chroma: operation cancelled` |
215
- | Other | `chroma: <error message>` |
216
-
217
- ## Local Setup
218
-
219
- ### Embedded Mode (default)
220
-
221
- ChromaDB runs in-process without an external server:
222
-
223
- ```typescript
224
- const ext = createChromaExtension({
225
- collection: 'test_collection',
226
- });
227
- ```
228
-
229
- No Docker or server setup required.
230
-
231
- ### HTTP Server Mode
232
-
233
- Run ChromaDB with Docker:
234
-
235
- ```bash
236
- docker run -p 8000:8000 chromadb/chroma
237
- ```
238
-
239
- Verify: `curl http://localhost:8000/api/v1`
240
-
241
- ```typescript
242
- const ext = createChromaExtension({
243
- url: 'http://localhost:8000',
244
- collection: 'test_collection',
245
- });
246
- ```
247
-
248
- ## Lifecycle
249
-
250
- ```typescript
251
- const ext = createChromaExtension({ ... });
252
- // ... use extension ...
253
- await ext.dispose?.();
254
- ```
41
+ ## Documentation
255
42
 
256
- `dispose()` aborts pending requests and closes the SDK client. Idempotent — second call resolves without error.
43
+ See [full documentation](docs/extension-vectordb-chroma.md) for configuration, functions, error handling, and local setup.
257
44
 
258
- ## Documentation
45
+ ## Related
259
46
 
260
- | Document | Description |
261
- |----------|-------------|
262
- | [Extensions Guide](https://github.com/rcrsr/rill/blob/main/docs/integration-extensions.md) | Extension contract and patterns |
263
- | [Host API Reference](https://github.com/rcrsr/rill/blob/main/docs/ref-host-api.md) | Runtime context and host functions |
264
- | [ChromaDB Documentation](https://docs.trychroma.com) | Official ChromaDB docs |
47
+ - [rill](https://github.com/rcrsr/rill) Core language runtime
48
+ - [Extensions Guide](https://github.com/rcrsr/rill/blob/main/docs/integration-extensions.md) — Extension contract and patterns
49
+ - [Host API Reference](https://github.com/rcrsr/rill/blob/main/docs/ref-host-api.md) Runtime context and host functions
50
+ - [ChromaDB Documentation](https://docs.trychroma.com) Official ChromaDB docs
265
51
 
266
52
  ## License
267
53
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- import { ExtensionResult } from '@rcrsr/rill';
3
+ import { ExtensionConfigSchema, ExtensionResult } from '@rcrsr/rill';
4
4
 
5
5
  /**
6
6
  * Type definitions for ChromaDB extension.
@@ -88,6 +88,7 @@ export type ChromaExtensionConfig = ChromaConfig;
88
88
  * ```
89
89
  */
90
90
  export declare function createChromaExtension(config: ChromaConfig): ExtensionResult;
91
+ export declare const configSchema: ExtensionConfigSchema;
91
92
  export declare const CHROMA_EXTENSION_VERSION = "0.0.1";
92
93
 
93
94
  export {};
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/factory.ts
2
2
  import { ChromaClient } from "chromadb";
3
3
  import {
4
- RuntimeError as RuntimeError4,
4
+ RuntimeError as RuntimeError6,
5
5
  emitExtensionEvent as emitExtensionEvent3,
6
6
  createVector
7
7
  } from "@rcrsr/rill";
@@ -87,6 +87,144 @@ function assertRequired(value, fieldName) {
87
87
  // ../../shared/ext-vector/dist/wrapper.js
88
88
  import { emitExtensionEvent as emitExtensionEvent2 } from "@rcrsr/rill";
89
89
 
90
+ // ../../shared/ext-vector/dist/param.js
91
+ import { RuntimeError as RuntimeError4 } from "@rcrsr/rill";
92
+ function validateParamName(name) {
93
+ if (name === "")
94
+ throw new RuntimeError4("RILL-R001", "param name must not be empty");
95
+ if (/\s/.test(name))
96
+ throw new RuntimeError4("RILL-R001", "param name must be a valid identifier");
97
+ }
98
+ function vectorParam(name) {
99
+ validateParamName(name);
100
+ return {
101
+ name,
102
+ type: { type: "vector" },
103
+ defaultValue: void 0,
104
+ annotations: {}
105
+ };
106
+ }
107
+
108
+ // ../../shared/ext-param/dist/param.js
109
+ import { RuntimeError as RuntimeError5 } from "@rcrsr/rill";
110
+ function validateParamName2(name) {
111
+ if (name === "") {
112
+ throw new RuntimeError5("RILL-R001", "param name must not be empty");
113
+ }
114
+ if (/\s/.test(name)) {
115
+ throw new RuntimeError5("RILL-R001", "param name must be a valid identifier");
116
+ }
117
+ }
118
+ function buildAnnotations(desc) {
119
+ if (desc !== void 0) {
120
+ return { description: desc };
121
+ }
122
+ return {};
123
+ }
124
+ var p = {
125
+ /**
126
+ * IR-1: Creates a string parameter descriptor.
127
+ *
128
+ * @param name - Parameter name (must be a valid identifier)
129
+ * @param desc - Optional description
130
+ * @returns RillParam with type 'string'
131
+ */
132
+ str(name, desc) {
133
+ validateParamName2(name);
134
+ return {
135
+ name,
136
+ type: { type: "string" },
137
+ defaultValue: void 0,
138
+ annotations: buildAnnotations(desc)
139
+ };
140
+ },
141
+ /**
142
+ * IR-2: Creates a number parameter descriptor.
143
+ *
144
+ * @param name - Parameter name (must be a valid identifier)
145
+ * @param desc - Optional description
146
+ * @param def - Optional default value
147
+ * @returns RillParam with type 'number'
148
+ */
149
+ num(name, desc, def) {
150
+ validateParamName2(name);
151
+ return {
152
+ name,
153
+ type: { type: "number" },
154
+ defaultValue: def,
155
+ annotations: buildAnnotations(desc)
156
+ };
157
+ },
158
+ /**
159
+ * IR-3: Creates a boolean parameter descriptor.
160
+ *
161
+ * @param name - Parameter name (must be a valid identifier)
162
+ * @param desc - Optional description
163
+ * @param def - Optional default value
164
+ * @returns RillParam with type 'bool'
165
+ */
166
+ bool(name, desc, def) {
167
+ validateParamName2(name);
168
+ return {
169
+ name,
170
+ type: { type: "bool" },
171
+ defaultValue: def,
172
+ annotations: buildAnnotations(desc)
173
+ };
174
+ },
175
+ /**
176
+ * IR-4: Creates a dict parameter descriptor.
177
+ *
178
+ * @param name - Parameter name (must be a valid identifier)
179
+ * @param desc - Optional description
180
+ * @param def - Optional default value
181
+ * @returns RillParam with type 'dict'
182
+ */
183
+ dict(name, desc, def) {
184
+ validateParamName2(name);
185
+ return {
186
+ name,
187
+ type: { type: "dict" },
188
+ defaultValue: def,
189
+ annotations: buildAnnotations(desc)
190
+ };
191
+ },
192
+ /**
193
+ * IR-5: Creates a list parameter descriptor.
194
+ *
195
+ * @param name - Parameter name (must be a valid identifier)
196
+ * @param itemType - Optional element type; omitted when not provided
197
+ * @param desc - Optional description
198
+ * @returns RillParam with type 'list' (with element if itemType provided)
199
+ */
200
+ list(name, itemType, desc) {
201
+ validateParamName2(name);
202
+ const type = itemType !== void 0 ? { type: "list", element: itemType } : { type: "list" };
203
+ return {
204
+ name,
205
+ type,
206
+ defaultValue: void 0,
207
+ annotations: buildAnnotations(desc)
208
+ };
209
+ },
210
+ /**
211
+ * IR-6: Creates a callable parameter descriptor.
212
+ *
213
+ * @param name - Parameter name (must be a valid identifier)
214
+ * @param desc - Optional description
215
+ * @returns RillParam with type 'closure'
216
+ */
217
+ callable(name, desc) {
218
+ validateParamName2(name);
219
+ return {
220
+ name,
221
+ type: { type: "closure" },
222
+ defaultValue: void 0,
223
+ annotations: buildAnnotations(desc)
224
+ };
225
+ }
226
+ };
227
+
90
228
  // src/factory.ts
91
229
  function createChromaExtension(config) {
92
230
  assertRequired(config.collection, "collection");
@@ -101,9 +239,9 @@ function createChromaExtension(config) {
101
239
  // IR-1: chroma::upsert
102
240
  upsert: {
103
241
  params: [
104
- { name: "id", type: "string" },
105
- { name: "vector", type: "vector" },
106
- { name: "metadata", type: "dict", defaultValue: {} }
242
+ p.str("id"),
243
+ vectorParam("vector"),
244
+ p.dict("metadata", void 0, {})
107
245
  ],
108
246
  fn: async (args, ctx) => {
109
247
  const startTime = Date.now();
@@ -145,11 +283,11 @@ function createChromaExtension(config) {
145
283
  }
146
284
  },
147
285
  description: "Insert or update single vector with metadata",
148
- returnType: "dict"
286
+ returnType: { type: "dict" }
149
287
  },
150
288
  // IR-2: chroma::upsert_batch
151
289
  upsert_batch: {
152
- params: [{ name: "items", type: "list" }],
290
+ params: [p.list("items")],
153
291
  fn: async (args, ctx) => {
154
292
  const startTime = Date.now();
155
293
  try {
@@ -230,13 +368,13 @@ function createChromaExtension(config) {
230
368
  }
231
369
  },
232
370
  description: "Batch insert/update vectors",
233
- returnType: "dict"
371
+ returnType: { type: "dict" }
234
372
  },
235
373
  // IR-3: chroma::search
236
374
  search: {
237
375
  params: [
238
- { name: "vector", type: "vector" },
239
- { name: "options", type: "dict", defaultValue: {} }
376
+ vectorParam("vector"),
377
+ p.dict("options", void 0, {})
240
378
  ],
241
379
  fn: async (args, ctx) => {
242
380
  const startTime = Date.now();
@@ -284,11 +422,11 @@ function createChromaExtension(config) {
284
422
  }
285
423
  },
286
424
  description: "Search k nearest neighbors",
287
- returnType: "list"
425
+ returnType: { type: "list" }
288
426
  },
289
427
  // IR-4: chroma::get
290
428
  get: {
291
- params: [{ name: "id", type: "string" }],
429
+ params: [p.str("id")],
292
430
  fn: async (args, ctx) => {
293
431
  const startTime = Date.now();
294
432
  try {
@@ -301,12 +439,12 @@ function createChromaExtension(config) {
301
439
  ids: [id]
302
440
  });
303
441
  if (response.ids.length === 0) {
304
- throw new RuntimeError4("RILL-R004", "chroma: id not found");
442
+ throw new RuntimeError6("RILL-R004", "chroma: id not found");
305
443
  }
306
444
  const embedding = response.embeddings?.[0];
307
445
  const metadata = response.metadatas?.[0];
308
446
  if (!embedding || !Array.isArray(embedding)) {
309
- throw new RuntimeError4(
447
+ throw new RuntimeError6(
310
448
  "RILL-R004",
311
449
  "chroma: invalid vector format"
312
450
  );
@@ -339,11 +477,11 @@ function createChromaExtension(config) {
339
477
  }
340
478
  },
341
479
  description: "Fetch vector by ID",
342
- returnType: "dict"
480
+ returnType: { type: "dict" }
343
481
  },
344
482
  // IR-5: chroma::delete
345
483
  delete: {
346
- params: [{ name: "id", type: "string" }],
484
+ params: [p.str("id")],
347
485
  fn: async (args, ctx) => {
348
486
  const startTime = Date.now();
349
487
  try {
@@ -380,11 +518,11 @@ function createChromaExtension(config) {
380
518
  }
381
519
  },
382
520
  description: "Delete vector by ID",
383
- returnType: "dict"
521
+ returnType: { type: "dict" }
384
522
  },
385
523
  // IR-6: chroma::delete_batch
386
524
  delete_batch: {
387
- params: [{ name: "ids", type: "list" }],
525
+ params: [p.list("ids")],
388
526
  fn: async (args, ctx) => {
389
527
  const startTime = Date.now();
390
528
  try {
@@ -442,7 +580,7 @@ function createChromaExtension(config) {
442
580
  }
443
581
  },
444
582
  description: "Batch delete vectors",
445
- returnType: "dict"
583
+ returnType: { type: "dict" }
446
584
  },
447
585
  // IR-7: chroma::count
448
586
  count: {
@@ -476,13 +614,13 @@ function createChromaExtension(config) {
476
614
  }
477
615
  },
478
616
  description: "Return total vector count in collection",
479
- returnType: "number"
617
+ returnType: { type: "number" }
480
618
  },
481
619
  // IR-8: chroma::create_collection
482
620
  create_collection: {
483
621
  params: [
484
- { name: "name", type: "string" },
485
- { name: "options", type: "dict", defaultValue: {} }
622
+ p.str("name"),
623
+ p.dict("options", void 0, {})
486
624
  ],
487
625
  fn: async (args, ctx) => {
488
626
  const startTime = Date.now();
@@ -520,11 +658,11 @@ function createChromaExtension(config) {
520
658
  }
521
659
  },
522
660
  description: "Create new vector collection",
523
- returnType: "dict"
661
+ returnType: { type: "dict" }
524
662
  },
525
663
  // IR-9: chroma::delete_collection
526
664
  delete_collection: {
527
- params: [{ name: "name", type: "string" }],
665
+ params: [p.str("name")],
528
666
  fn: async (args, ctx) => {
529
667
  const startTime = Date.now();
530
668
  try {
@@ -556,7 +694,7 @@ function createChromaExtension(config) {
556
694
  }
557
695
  },
558
696
  description: "Delete vector collection",
559
- returnType: "dict"
697
+ returnType: { type: "dict" }
560
698
  },
561
699
  // IR-10: chroma::list_collections
562
700
  list_collections: {
@@ -565,7 +703,7 @@ function createChromaExtension(config) {
565
703
  const startTime = Date.now();
566
704
  try {
567
705
  checkDisposed(disposalState, "chroma");
568
- const names = await client.listCollections();
706
+ const names = (await client.listCollections()).map((c) => c.name);
569
707
  const duration = Date.now() - startTime;
570
708
  emitExtensionEvent3(ctx, {
571
709
  event: "chroma:list_collections",
@@ -587,7 +725,7 @@ function createChromaExtension(config) {
587
725
  }
588
726
  },
589
727
  description: "List all collection names",
590
- returnType: "list"
728
+ returnType: { type: "list" }
591
729
  },
592
730
  // IR-11: chroma::describe
593
731
  describe: {
@@ -625,7 +763,7 @@ function createChromaExtension(config) {
625
763
  }
626
764
  },
627
765
  description: "Describe configured collection",
628
- returnType: "dict"
766
+ returnType: { type: "dict" }
629
767
  }
630
768
  };
631
769
  result.dispose = async () => {
@@ -636,8 +774,15 @@ function createChromaExtension(config) {
636
774
  }
637
775
 
638
776
  // src/index.ts
777
+ var configSchema = {
778
+ url: { type: "string" },
779
+ collection: { type: "string", required: true },
780
+ embeddingFunction: { type: "string" },
781
+ timeout: { type: "number" }
782
+ };
639
783
  var CHROMA_EXTENSION_VERSION = "0.0.1";
640
784
  export {
641
785
  CHROMA_EXTENSION_VERSION,
786
+ configSchema,
642
787
  createChromaExtension
643
788
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcrsr/rill-ext-chroma",
3
- "version": "0.8.6",
3
+ "version": "0.11.0",
4
4
  "description": "rill extension for ChromaDB vector database integration",
5
5
  "license": "MIT",
6
6
  "author": "Andre Bremer",
@@ -18,14 +18,14 @@
18
18
  "scripting"
19
19
  ],
20
20
  "peerDependencies": {
21
- "@rcrsr/rill": "^0.8.6"
21
+ "@rcrsr/rill": "^0.11.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@types/node": "^25.2.3",
24
+ "@rcrsr/rill": "^0.11.0",
25
+ "@types/node": "^25.3.0",
25
26
  "dts-bundle-generator": "^9.5.1",
26
- "tsup": "^8.5.0",
27
- "undici-types": "^7.21.0",
28
- "@rcrsr/rill": "^0.8.6",
27
+ "tsup": "^8.5.1",
28
+ "undici-types": "^7.22.0",
29
29
  "@rcrsr/rill-ext-vector-shared": "^0.0.1"
30
30
  },
31
31
  "files": [
@@ -33,18 +33,19 @@
33
33
  ],
34
34
  "repository": {
35
35
  "type": "git",
36
- "url": "git+https://github.com/rcrsr/rill.git",
36
+ "url": "git+https://github.com/rcrsr/rill-ext.git",
37
37
  "directory": "packages/ext/vectordb-chroma"
38
38
  },
39
- "homepage": "https://rill.run/docs/extensions/chroma/",
39
+ "homepage": "https://github.com/rcrsr/rill-ext/tree/main/packages/ext/vectordb-chroma#readme",
40
40
  "bugs": {
41
- "url": "https://github.com/rcrsr/rill/issues"
41
+ "url": "https://github.com/rcrsr/rill-ext/issues"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "chromadb": "^1.9.2"
47
+ "chromadb": "^3.3.1",
48
+ "@rcrsr/rill-ext-param-shared": "^0.0.1"
48
49
  },
49
50
  "scripts": {
50
51
  "build": "tsup && dts-bundle-generator --config dts-bundle-generator.config.cjs",