@sprucelabs/chroma-data-store 1.0.0 → 1.0.2

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 (80) hide show
  1. package/README.md +42 -0
  2. package/build/.spruce/settings.json +3 -1
  3. package/build/ChromaDatabase.d.ts +6 -1
  4. package/build/ChromaDatabase.js +23 -8
  5. package/build/MockChromaDatabase.d.ts +8 -0
  6. package/build/MockChromaDatabase.js +20 -0
  7. package/build/chroma.types.d.ts +21 -174
  8. package/build/chromaDbAssert.utility.d.ts +4 -0
  9. package/build/chromaDbAssert.utility.js +20 -0
  10. package/build/esm/ChromaDatabase.d.ts +6 -1
  11. package/build/esm/ChromaDatabase.js +28 -10
  12. package/build/esm/MockChromaDatabase.d.ts +8 -0
  13. package/build/esm/MockChromaDatabase.js +31 -0
  14. package/build/esm/chroma.types.d.ts +21 -174
  15. package/build/esm/chromaDbAssert.utility.d.ts +4 -0
  16. package/build/esm/chromaDbAssert.utility.js +16 -0
  17. package/build/esm/index.d.ts +2 -0
  18. package/build/esm/index.js +2 -0
  19. package/build/index.d.ts +2 -0
  20. package/build/index.js +5 -1
  21. package/package.json +26 -23
  22. package/build/esm/.spruce/errors/chromaDataStore/featureNotSupported.schema.d.ts +0 -3
  23. package/build/esm/.spruce/errors/chromaDataStore/featureNotSupported.schema.js +0 -18
  24. package/build/esm/.spruce/errors/chromaDataStore/featureNotSupported.schema.js.map +0 -1
  25. package/build/esm/.spruce/errors/errors.types.js.map +0 -1
  26. package/build/esm/.spruce/errors/options.types.js.map +0 -1
  27. package/build/esm/.spruce/schemas/fields/fieldClassMap.d.ts +0 -2
  28. package/build/esm/.spruce/schemas/fields/fieldClassMap.js +0 -4
  29. package/build/esm/.spruce/schemas/fields/fieldClassMap.js.map +0 -1
  30. package/build/esm/.spruce/schemas/fields/fields.types.d.ts +0 -1
  31. package/build/esm/.spruce/schemas/fields/fields.types.js +0 -2
  32. package/build/esm/.spruce/schemas/fields/fields.types.js.map +0 -1
  33. package/build/esm/.spruce/schemas/spruce/v2020_07_22/choice.schema.d.ts +0 -1
  34. package/build/esm/.spruce/schemas/spruce/v2020_07_22/choice.schema.js +0 -5
  35. package/build/esm/.spruce/schemas/spruce/v2020_07_22/choice.schema.js.map +0 -1
  36. package/build/esm/.spruce/schemas/spruce/v2020_07_22/link.schema.d.ts +0 -1
  37. package/build/esm/.spruce/schemas/spruce/v2020_07_22/link.schema.js +0 -5
  38. package/build/esm/.spruce/schemas/spruce/v2020_07_22/link.schema.js.map +0 -1
  39. package/build/esm/.spruce/schemas/spruce/v2020_07_22/location.schema.d.ts +0 -1
  40. package/build/esm/.spruce/schemas/spruce/v2020_07_22/location.schema.js +0 -5
  41. package/build/esm/.spruce/schemas/spruce/v2020_07_22/location.schema.js.map +0 -1
  42. package/build/esm/.spruce/schemas/spruce/v2020_07_22/message.schema.d.ts +0 -1
  43. package/build/esm/.spruce/schemas/spruce/v2020_07_22/message.schema.js +0 -5
  44. package/build/esm/.spruce/schemas/spruce/v2020_07_22/message.schema.js.map +0 -1
  45. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageSource.schema.d.ts +0 -1
  46. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageSource.schema.js +0 -5
  47. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageSource.schema.js.map +0 -1
  48. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageTarget.schema.d.ts +0 -1
  49. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageTarget.schema.js +0 -5
  50. package/build/esm/.spruce/schemas/spruce/v2020_07_22/messageTarget.schema.js.map +0 -1
  51. package/build/esm/.spruce/schemas/spruce/v2020_07_22/organization.schema.d.ts +0 -1
  52. package/build/esm/.spruce/schemas/spruce/v2020_07_22/organization.schema.js +0 -5
  53. package/build/esm/.spruce/schemas/spruce/v2020_07_22/organization.schema.js.map +0 -1
  54. package/build/esm/.spruce/schemas/spruce/v2020_07_22/person.schema.d.ts +0 -1
  55. package/build/esm/.spruce/schemas/spruce/v2020_07_22/person.schema.js +0 -5
  56. package/build/esm/.spruce/schemas/spruce/v2020_07_22/person.schema.js.map +0 -1
  57. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personLocation.schema.d.ts +0 -1
  58. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personLocation.schema.js +0 -5
  59. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personLocation.schema.js.map +0 -1
  60. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personOrganization.schema.d.ts +0 -1
  61. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personOrganization.schema.js +0 -5
  62. package/build/esm/.spruce/schemas/spruce/v2020_07_22/personOrganization.schema.js.map +0 -1
  63. package/build/esm/.spruce/schemas/spruce/v2020_07_22/role.schema.d.ts +0 -1
  64. package/build/esm/.spruce/schemas/spruce/v2020_07_22/role.schema.js +0 -5
  65. package/build/esm/.spruce/schemas/spruce/v2020_07_22/role.schema.js.map +0 -1
  66. package/build/esm/.spruce/schemas/spruce/v2020_07_22/sendMessage.schema.d.ts +0 -1
  67. package/build/esm/.spruce/schemas/spruce/v2020_07_22/sendMessage.schema.js +0 -5
  68. package/build/esm/.spruce/schemas/spruce/v2020_07_22/sendMessage.schema.js.map +0 -1
  69. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skill.schema.d.ts +0 -1
  70. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skill.schema.js +0 -5
  71. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skill.schema.js.map +0 -1
  72. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skillCreator.schema.d.ts +0 -1
  73. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skillCreator.schema.js +0 -5
  74. package/build/esm/.spruce/schemas/spruce/v2020_07_22/skillCreator.schema.js.map +0 -1
  75. package/build/esm/.spruce/settings.json +0 -13
  76. package/build/esm/ChromaDatabase.js.map +0 -1
  77. package/build/esm/chroma.types.js.map +0 -1
  78. package/build/esm/errors/SpruceError.js.map +0 -1
  79. package/build/esm/errors/featureNotSupported.builder.js.map +0 -1
  80. package/build/esm/index.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Chroma Data Store
2
+
3
+ Give your skill the ability to store and retrieve data from a Chroma database.
4
+
5
+ ## Running the Chroma Database
6
+
7
+ 1. Clone this rep
8
+ 2. Run `yarn start.chroma.docker`
9
+
10
+ ## Setting an embedding model
11
+
12
+ By default, the ChromaDabatase class will use llama3.2 hosted through Ollama to generate embeddings
13
+
14
+ ### Installing Ollama
15
+
16
+ 1. Visit https://ollama.com
17
+ 2. Click "Download"
18
+ 3. Select your OS
19
+
20
+ ### Installing Llama3.2
21
+
22
+ Llama 3.2 is the newest version of Llama (as of this writing) that supports embeddings.
23
+
24
+ 1. Inside of terminal, run `ollama run llama3.2`
25
+ 2. You should be able to visit http://localhost:11434/api/embeddings and get a 405 response (this is because the route only accepts POST requests)
26
+
27
+ ### Improving embeddings with `nomic-embed-text`
28
+
29
+ We have seen significantly better search performance when using `nomic-embed-text` to generate embeddings.
30
+
31
+ Run `ollama pull nomic-embed-text`
32
+
33
+
34
+ ## Using in your skill
35
+
36
+ Add the following to your env:
37
+
38
+ ```bash
39
+ DB_CONNECTION_STRING="chromadb://localhost:8000"
40
+ DB_ADAPTER="@sprucelabs/chroma-data-store"
41
+
42
+ ```
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "scriptUpdater": {
3
- "skipped": []
3
+ "skipped": [
4
+ "test"
5
+ ]
4
6
  },
5
7
  "skipped": [
6
8
  "skill"
@@ -1,14 +1,19 @@
1
1
  import { CreateOptions, Database, DatabaseInternalOptions, Index, IndexWithFilter, QueryOptions } from '@sprucelabs/data-stores';
2
+ import { OllamaEmbeddingFunction } from '@chroma-core/ollama';
2
3
  export default class ChromaDatabase implements Database {
4
+ static Class?: new (connectionString: string) => Database;
5
+ static EmbeddingFunction: typeof OllamaEmbeddingFunction;
6
+ private static embeddingFields?;
3
7
  private connectionString;
4
8
  private client;
5
9
  private _isConnected;
6
10
  private embeddings;
7
11
  private collections;
8
- private static embeddingFields?;
9
12
  constructor(connectionString: string);
13
+ static Database(connectionString: string): ChromaDatabase | Database;
10
14
  static setEmbeddingsFields(collectionName: string, fields: string[]): void;
11
15
  static clearEmbeddingsFields(): void;
16
+ static getEmbeddingsFields(): Record<string, string[]> | undefined;
12
17
  syncUniqueIndexes(_collectionName: string, _indexes: Index[]): Promise<void>;
13
18
  syncIndexes(_collectionName: string, _indexes: Index[]): Promise<void>;
14
19
  dropIndex(_collectionName: string, _index: Index): Promise<void>;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const data_stores_1 = require("@sprucelabs/data-stores");
7
7
  const schema_1 = require("@sprucelabs/schema");
8
8
  const test_utils_1 = require("@sprucelabs/test-utils");
9
+ const ollama_1 = require("@chroma-core/ollama");
9
10
  const chromadb_1 = require("chromadb");
10
11
  const SpruceError_1 = __importDefault(require("./errors/SpruceError"));
11
12
  class ChromaDatabase {
@@ -13,9 +14,9 @@ class ChromaDatabase {
13
14
  this._isConnected = false;
14
15
  this.collections = {};
15
16
  (0, schema_1.assertOptions)({ connectionString }, ['connectionString']);
16
- this.embeddings = new chromadb_1.OllamaEmbeddingFunction({
17
- model: 'llama3.2',
18
- url: 'http://localhost:11434/api/embeddings',
17
+ this.embeddings = new ChromaDatabase.EmbeddingFunction({
18
+ model: process.env.CHROMA_EMBEDDING_MODEL ?? 'llama3.2',
19
+ url: 'http://localhost:11434',
19
20
  });
20
21
  if (!connectionString.startsWith('chroma://')) {
21
22
  throw new data_stores_1.DataStoresError({
@@ -24,6 +25,9 @@ class ChromaDatabase {
24
25
  }
25
26
  this.connectionString = connectionString.replace('chroma://', 'http://');
26
27
  }
28
+ static Database(connectionString) {
29
+ return new (this.Class ?? this)(connectionString);
30
+ }
27
31
  static setEmbeddingsFields(collectionName, fields) {
28
32
  if (!this.embeddingFields) {
29
33
  this.embeddingFields = {};
@@ -33,6 +37,9 @@ class ChromaDatabase {
33
37
  static clearEmbeddingsFields() {
34
38
  delete this.embeddingFields;
35
39
  }
40
+ static getEmbeddingsFields() {
41
+ return this.embeddingFields;
42
+ }
36
43
  async syncUniqueIndexes(_collectionName, _indexes) {
37
44
  throw new SpruceError_1.default({
38
45
  code: 'FEATURE_NOT_SUPPORTED',
@@ -183,14 +190,19 @@ class ChromaDatabase {
183
190
  async find(collection, query, options, _dbOptions) {
184
191
  let { ids, where, skipIds } = this.buildQuery(query);
185
192
  let matches;
186
- const { limit, includeFields } = options ?? {};
193
+ let { limit, includeFields } = options ?? {};
187
194
  const col = await this.getCollection(collection);
195
+ if (!limit && where?.$prompt) {
196
+ limit = 10;
197
+ }
188
198
  if (where?.$prompt) {
189
199
  const { $prompt, ...rest } = where;
190
200
  const queryResults = await col.query({
191
201
  queryTexts: [$prompt],
192
- nResults: 1,
193
- where: Object.keys(rest).length > 0 ? rest : undefined,
202
+ nResults: limit,
203
+ where: (Object.keys(rest).length > 0
204
+ ? rest
205
+ : undefined),
194
206
  });
195
207
  matches = {
196
208
  ids: queryResults.ids[0],
@@ -201,7 +213,7 @@ class ChromaDatabase {
201
213
  matches = await col.get({
202
214
  ids,
203
215
  include: ['metadatas'],
204
- where,
216
+ where: where,
205
217
  limit: limit == 0 ? 1 : limit,
206
218
  });
207
219
  }
@@ -255,7 +267,6 @@ class ChromaDatabase {
255
267
  where = rest;
256
268
  }
257
269
  if (where?.$or && where.$or.length === 1) {
258
- //@ts-ignore
259
270
  where = where.$or[0];
260
271
  }
261
272
  if (where) {
@@ -348,6 +359,9 @@ class ChromaDatabase {
348
359
  }
349
360
  async delete(collection, query) {
350
361
  const matches = await this.find(collection, query);
362
+ if (matches.length === 0) {
363
+ return 0;
364
+ }
351
365
  const col = await this.getCollection(collection);
352
366
  await col.delete({
353
367
  ids: matches.map((m) => m.id),
@@ -382,4 +396,5 @@ class ChromaDatabase {
382
396
  });
383
397
  }
384
398
  }
399
+ ChromaDatabase.EmbeddingFunction = ollama_1.OllamaEmbeddingFunction;
385
400
  exports.default = ChromaDatabase;
@@ -0,0 +1,8 @@
1
+ import { NeDbDatabase } from '@sprucelabs/data-stores';
2
+ export default class MockChromaDatabase extends NeDbDatabase {
3
+ private connectionString;
4
+ constructor(connectionString: string);
5
+ assertConnectionStringEquals(connectionString: string): void;
6
+ connect(): Promise<void>;
7
+ assertIsConnected(): void;
8
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const data_stores_1 = require("@sprucelabs/data-stores");
4
+ const test_utils_1 = require("@sprucelabs/test-utils");
5
+ class MockChromaDatabase extends data_stores_1.NeDbDatabase {
6
+ constructor(connectionString) {
7
+ super();
8
+ this.connectionString = connectionString;
9
+ }
10
+ assertConnectionStringEquals(connectionString) {
11
+ test_utils_1.assert.isEqual(this.connectionString, connectionString, 'The connection string you passed to your ChromaDb does not equal what I expected!');
12
+ }
13
+ async connect() {
14
+ await super.connect();
15
+ }
16
+ assertIsConnected() {
17
+ test_utils_1.assert.isTrue(this.isConnected(), 'Database is not connected! Try calling db.connect()');
18
+ }
19
+ }
20
+ exports.default = MockChromaDatabase;
@@ -1,177 +1,24 @@
1
- import { AddRecordsParams, UpsertRecordsParams, GetResponse, UpdateRecordsParams, QueryRecordsParams, QueryResponse, CollectionMetadata, CollectionParams, PeekParams, DeleteParams, ID, IDs, Where, IncludeEnum, WhereDocument } from 'chromadb';
2
- export interface Collection {
3
- add(params: AddRecordsParams): Promise<void>;
4
- /**
5
- * Upsert items to the collection
6
- * @param {Object} params - The parameters for the query.
7
- * @param {ID | IDs} [params.ids] - IDs of the items to add.
8
- * @param {Embedding | Embeddings} [params.embeddings] - Optional embeddings of the items to add.
9
- * @param {Metadata | Metadatas} [params.metadatas] - Optional metadata of the items to add.
10
- * @param {Document | Documents} [params.documents] - Optional documents of the items to add.
11
- * @returns {Promise<void>}
12
- *
13
- * @example
14
- * ```typescript
15
- * const response = await collection.upsert({
16
- * ids: ["id1", "id2"],
17
- * embeddings: [[1, 2, 3], [4, 5, 6]],
18
- * metadatas: [{ "key": "value" }, { "key": "value" }],
19
- * documents: ["document1", "document2"],
20
- * });
21
- * ```
22
- */
23
- upsert(params: UpsertRecordsParams): Promise<void>;
24
- /**
25
- * Count the number of items in the collection
26
- * @returns {Promise<number>} - The number of items in the collection.
27
- *
28
- * @example
29
- * ```typescript
30
- * const count = await collection.count();
31
- * ```
32
- */
33
- count(): Promise<number>;
34
- /**
35
- * Get items from the collection
36
- * @param {Object} params - The parameters for the query.
37
- * @param {ID | IDs} [params.ids] - Optional IDs of the items to get.
38
- * @param {Where} [params.where] - Optional where clause to filter items by.
39
- * @param {PositiveInteger} [params.limit] - Optional limit on the number of items to get.
40
- * @param {PositiveInteger} [params.offset] - Optional offset on the items to get.
41
- * @param {IncludeEnum[]} [params.include] - Optional list of items to include in the response.
42
- * @param {WhereDocument} [params.whereDocument] - Optional where clause to filter items by.
43
- * @returns {Promise<GetResponse>} - The response from the server.
44
- *
45
- * @example
46
- * ```typescript
47
- * const response = await collection.get({
48
- * ids: ["id1", "id2"],
49
- * where: { "key": "value" },
50
- * limit: 10,
51
- * offset: 0,
52
- * include: ["embeddings", "metadatas", "documents"],
53
- * whereDocument: { $contains: "value" },
54
- * });
55
- * ```
56
- */
57
- get(options?: BaseGetParams): Promise<GetResponse>;
58
- /**
59
- * Update items in the collection
60
- * @param {Object} params - The parameters for the query.
61
- * @param {ID | IDs} [params.ids] - IDs of the items to add.
62
- * @param {Embedding | Embeddings} [params.embeddings] - Optional embeddings of the items to add.
63
- * @param {Metadata | Metadatas} [params.metadatas] - Optional metadata of the items to add.
64
- * @param {Document | Documents} [params.documents] - Optional documents of the items to add.
65
- * @returns {Promise<void>}
66
- *
67
- * @example
68
- * ```typescript
69
- * const response = await collection.update({
70
- * ids: ["id1", "id2"],
71
- * embeddings: [[1, 2, 3], [4, 5, 6]],
72
- * metadatas: [{ "key": "value" }, { "key": "value" }],
73
- * documents: ["document1", "document2"],
74
- * });
75
- * ```
76
- */
77
- update(params: UpdateRecordsParams): Promise<void>;
78
- /**
79
- * Performs a query on the collection using the specified parameters.
80
- *
81
- * @param {Object} params - The parameters for the query.
82
- * @param {Embedding | Embeddings} [params.queryEmbeddings] - Optional query embeddings to use for the search.
83
- * @param {PositiveInteger} [params.nResults] - Optional number of results to return (default is 10).
84
- * @param {Where} [params.where] - Optional query condition to filter results based on metadata values.
85
- * @param {string | string[]} [params.queryTexts] - Optional query text(s) to search for in the collection.
86
- * @param {WhereDocument} [params.whereDocument] - Optional query condition to filter results based on document content.
87
- * @param {IncludeEnum[]} [params.include] - Optional array of fields to include in the result, such as "metadata" and "document".
88
- *
89
- * @returns {Promise<QueryResponse>} A promise that resolves to the query results.
90
- * @throws {Error} If there is an issue executing the query.
91
- * @example
92
- * // Query the collection using embeddings
93
- * const results = await collection.query({
94
- * queryEmbeddings: [[0.1, 0.2, ...], ...],
95
- * nResults: 10,
96
- * where: {"name": {"$eq": "John Doe"}},
97
- * include: ["metadata", "document"]
98
- * });
99
- * @example
100
- * ```js
101
- * // Query the collection using query text
102
- * const results = await collection.query({
103
- * queryTexts: "some text",
104
- * nResults: 10,
105
- * where: {"name": {"$eq": "John Doe"}},
106
- * include: ["metadata", "document"]
107
- * });
108
- * ```
109
- *
110
- */
111
- query({ nResults, where, whereDocument, include, queryTexts, queryEmbeddings, }: QueryRecordsParams): Promise<QueryResponse>;
112
- /**
113
- * Modify the collection name or metadata
114
- * @param {Object} params - The parameters for the query.
115
- * @param {string} [params.name] - Optional new name for the collection.
116
- * @param {CollectionMetadata} [params.metadata] - Optional new metadata for the collection.
117
- * @returns {Promise<void>} - The response from the API.
118
- *
119
- * @example
120
- * ```typescript
121
- * const response = await client.updateCollection({
122
- * name: "new name",
123
- * metadata: { "key": "value" },
124
- * });
125
- * ```
126
- */
127
- modify({ name, metadata, }: {
128
- name?: string;
129
- metadata?: CollectionMetadata;
130
- }): Promise<CollectionParams>;
131
- /**
132
- * Peek inside the collection
133
- * @param {Object} params - The parameters for the query.
134
- * @param {PositiveInteger} [params.limit] - Optional number of results to return (default is 10).
135
- * @returns {Promise<GetResponse>} A promise that resolves to the query results.
136
- * @throws {Error} If there is an issue executing the query.
137
- *
138
- * @example
139
- * ```typescript
140
- * const results = await collection.peek({
141
- * limit: 10
142
- * });
143
- * ```
144
- */
145
- peek(options?: PeekParams): Promise<GetResponse>;
146
- /**
147
- * Deletes items from the collection.
148
- * @param {Object} params - The parameters for deleting items from the collection.
149
- * @param {ID | IDs} [params.ids] - Optional ID or array of IDs of items to delete.
150
- * @param {Where} [params.where] - Optional query condition to filter items to delete based on metadata values.
151
- * @param {WhereDocument} [params.whereDocument] - Optional query condition to filter items to delete based on document content.
152
- * @returns {Promise<string[]>} A promise that resolves to the IDs of the deleted items.
153
- * @throws {Error} If there is an issue deleting items from the collection.
154
- *
155
- * @example
156
- * ```typescript
157
- * const results = await collection.delete({
158
- * ids: "some_id",
159
- * where: {"name": {"$eq": "John Doe"}},
160
- * whereDocument: {"$contains":"search_string"}
161
- * });
162
- * ```
163
- */
164
- delete(options?: DeleteParams): Promise<void>;
1
+ import { IncludeEnum, Metadata } from 'chromadb';
2
+ export type ID = string;
3
+ export type Embedding = number[];
4
+ export type Embeddings = Embedding[];
5
+ export interface GetResponse {
6
+ ids: ID[];
7
+ embeddings: Embeddings | null;
8
+ documents: (Document | null)[];
9
+ metadatas: (Metadata | null)[];
10
+ included: IncludeEnum[];
165
11
  }
166
- interface BaseGetParams {
167
- ids?: ID | IDs;
168
- where?: Where;
169
- limit?: number;
170
- offset?: number;
171
- include?: IncludeEnum[];
172
- whereDocument?: WhereDocument;
173
- }
174
- export type WhereWithPrompt = Where & {
12
+ export type WhereWithPrompt = WhereDocument & {
175
13
  $prompt?: string;
176
14
  };
177
- export {};
15
+ export interface WhereDocument {
16
+ $contains?: string;
17
+ $not_contains?: string;
18
+ $matches?: string;
19
+ $not_matches?: string;
20
+ $regex?: string;
21
+ $not_regex?: string;
22
+ $and?: WhereDocument[];
23
+ $or?: WhereDocument[];
24
+ }
@@ -0,0 +1,4 @@
1
+ declare const chromaDbAssert: {
2
+ embeddingFieldsForCollectionEqual(collection: string, fields: string[]): void;
3
+ };
4
+ export default chromaDbAssert;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const schema_1 = require("@sprucelabs/schema");
7
+ const test_utils_1 = require("@sprucelabs/test-utils");
8
+ const ChromaDatabase_1 = __importDefault(require("./ChromaDatabase"));
9
+ const chromaDbAssert = {
10
+ embeddingFieldsForCollectionEqual(collection, fields) {
11
+ (0, schema_1.assertOptions)({
12
+ collection,
13
+ fields,
14
+ }, ['collection', 'fields']);
15
+ const actual = ChromaDatabase_1.default.getEmbeddingsFields()?.[collection];
16
+ test_utils_1.assert.isTruthy(actual, `I could not find any embedding fields for the collection called ${collection}`);
17
+ test_utils_1.assert.isEqualDeep(actual, fields, `The embedding fields for the collection did not match.`);
18
+ },
19
+ };
20
+ exports.default = chromaDbAssert;
@@ -1,14 +1,19 @@
1
1
  import { CreateOptions, Database, DatabaseInternalOptions, Index, IndexWithFilter, QueryOptions } from '@sprucelabs/data-stores';
2
+ import { OllamaEmbeddingFunction } from '@chroma-core/ollama';
2
3
  export default class ChromaDatabase implements Database {
4
+ static Class?: new (connectionString: string) => Database;
5
+ static EmbeddingFunction: typeof OllamaEmbeddingFunction;
6
+ private static embeddingFields?;
3
7
  private connectionString;
4
8
  private client;
5
9
  private _isConnected;
6
10
  private embeddings;
7
11
  private collections;
8
- private static embeddingFields?;
9
12
  constructor(connectionString: string);
13
+ static Database(connectionString: string): ChromaDatabase | Database;
10
14
  static setEmbeddingsFields(collectionName: string, fields: string[]): void;
11
15
  static clearEmbeddingsFields(): void;
16
+ static getEmbeddingsFields(): Record<string, string[]> | undefined;
12
17
  syncUniqueIndexes(_collectionName: string, _indexes: Index[]): Promise<void>;
13
18
  syncIndexes(_collectionName: string, _indexes: Index[]): Promise<void>;
14
19
  dropIndex(_collectionName: string, _index: Index): Promise<void>;
@@ -21,16 +21,18 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  import { DataStoresError, generateId, } from '@sprucelabs/data-stores';
22
22
  import { assertOptions, flattenValues, expandValues } from '@sprucelabs/schema';
23
23
  import { NULL_PLACEHOLDER } from '@sprucelabs/test-utils';
24
- import { ChromaClient, OllamaEmbeddingFunction, } from 'chromadb';
24
+ import { OllamaEmbeddingFunction } from '@chroma-core/ollama';
25
+ import { ChromaClient, } from 'chromadb';
25
26
  import SpruceError from './errors/SpruceError.js';
26
- export default class ChromaDatabase {
27
+ class ChromaDatabase {
27
28
  constructor(connectionString) {
29
+ var _a;
28
30
  this._isConnected = false;
29
31
  this.collections = {};
30
32
  assertOptions({ connectionString }, ['connectionString']);
31
- this.embeddings = new OllamaEmbeddingFunction({
32
- model: 'llama3.2',
33
- url: 'http://localhost:11434/api/embeddings',
33
+ this.embeddings = new ChromaDatabase.EmbeddingFunction({
34
+ model: (_a = process.env.CHROMA_EMBEDDING_MODEL) !== null && _a !== void 0 ? _a : 'llama3.2',
35
+ url: 'http://localhost:11434',
34
36
  });
35
37
  if (!connectionString.startsWith('chroma://')) {
36
38
  throw new DataStoresError({
@@ -39,6 +41,10 @@ export default class ChromaDatabase {
39
41
  }
40
42
  this.connectionString = connectionString.replace('chroma://', 'http://');
41
43
  }
44
+ static Database(connectionString) {
45
+ var _a;
46
+ return new ((_a = this.Class) !== null && _a !== void 0 ? _a : this)(connectionString);
47
+ }
42
48
  static setEmbeddingsFields(collectionName, fields) {
43
49
  if (!this.embeddingFields) {
44
50
  this.embeddingFields = {};
@@ -48,6 +54,9 @@ export default class ChromaDatabase {
48
54
  static clearEmbeddingsFields() {
49
55
  delete this.embeddingFields;
50
56
  }
57
+ static getEmbeddingsFields() {
58
+ return this.embeddingFields;
59
+ }
51
60
  syncUniqueIndexes(_collectionName, _indexes) {
52
61
  return __awaiter(this, void 0, void 0, function* () {
53
62
  throw new SpruceError({
@@ -227,14 +236,19 @@ export default class ChromaDatabase {
227
236
  return __awaiter(this, void 0, void 0, function* () {
228
237
  let { ids, where, skipIds } = this.buildQuery(query);
229
238
  let matches;
230
- const { limit, includeFields } = options !== null && options !== void 0 ? options : {};
239
+ let { limit, includeFields } = options !== null && options !== void 0 ? options : {};
231
240
  const col = yield this.getCollection(collection);
241
+ if (!limit && (where === null || where === void 0 ? void 0 : where.$prompt)) {
242
+ limit = 10;
243
+ }
232
244
  if (where === null || where === void 0 ? void 0 : where.$prompt) {
233
245
  const { $prompt } = where, rest = __rest(where, ["$prompt"]);
234
246
  const queryResults = yield col.query({
235
247
  queryTexts: [$prompt],
236
- nResults: 1,
237
- where: Object.keys(rest).length > 0 ? rest : undefined,
248
+ nResults: limit,
249
+ where: (Object.keys(rest).length > 0
250
+ ? rest
251
+ : undefined),
238
252
  });
239
253
  matches = {
240
254
  ids: queryResults.ids[0],
@@ -245,7 +259,7 @@ export default class ChromaDatabase {
245
259
  matches = yield col.get({
246
260
  ids,
247
261
  include: ['metadatas'],
248
- where,
262
+ where: where,
249
263
  limit: limit == 0 ? 1 : limit,
250
264
  });
251
265
  }
@@ -298,7 +312,6 @@ export default class ChromaDatabase {
298
312
  where = rest;
299
313
  }
300
314
  if ((where === null || where === void 0 ? void 0 : where.$or) && where.$or.length === 1) {
301
- //@ts-ignore
302
315
  where = where.$or[0];
303
316
  }
304
317
  if (where) {
@@ -398,6 +411,9 @@ export default class ChromaDatabase {
398
411
  delete(collection, query) {
399
412
  return __awaiter(this, void 0, void 0, function* () {
400
413
  const matches = yield this.find(collection, query);
414
+ if (matches.length === 0) {
415
+ return 0;
416
+ }
401
417
  const col = yield this.getCollection(collection);
402
418
  yield col.delete({
403
419
  ids: matches.map((m) => m.id),
@@ -443,3 +459,5 @@ export default class ChromaDatabase {
443
459
  });
444
460
  }
445
461
  }
462
+ ChromaDatabase.EmbeddingFunction = OllamaEmbeddingFunction;
463
+ export default ChromaDatabase;
@@ -0,0 +1,8 @@
1
+ import { NeDbDatabase } from '@sprucelabs/data-stores';
2
+ export default class MockChromaDatabase extends NeDbDatabase {
3
+ private connectionString;
4
+ constructor(connectionString: string);
5
+ assertConnectionStringEquals(connectionString: string): void;
6
+ connect(): Promise<void>;
7
+ assertIsConnected(): void;
8
+ }
@@ -0,0 +1,31 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { NeDbDatabase } from '@sprucelabs/data-stores';
11
+ import { assert } from '@sprucelabs/test-utils';
12
+ export default class MockChromaDatabase extends NeDbDatabase {
13
+ constructor(connectionString) {
14
+ super();
15
+ this.connectionString = connectionString;
16
+ }
17
+ assertConnectionStringEquals(connectionString) {
18
+ assert.isEqual(this.connectionString, connectionString, 'The connection string you passed to your ChromaDb does not equal what I expected!');
19
+ }
20
+ connect() {
21
+ const _super = Object.create(null, {
22
+ connect: { get: () => super.connect }
23
+ });
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ yield _super.connect.call(this);
26
+ });
27
+ }
28
+ assertIsConnected() {
29
+ assert.isTrue(this.isConnected(), 'Database is not connected! Try calling db.connect()');
30
+ }
31
+ }