@instant.dev/vectors 0.1.0 → 0.1.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.
package/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ dist: jammy
2
+ language: node_js
3
+ node_js:
4
+ - "20.6.1"
5
+ env: NODE_ENV=test
package/README.md CHANGED
@@ -12,9 +12,9 @@ However, this API only allows for a maximum of 8,191 tokens per request:
12
12
  about 32,764 characters.
13
13
 
14
14
  **Solution:** `@instant.dev/vectors` provides a simple `VectorManager` utility that performs
15
- automatic, efficient batch creation of vectors via APIs. It will automatically collect
15
+ automatic, efficient batch creation of vectors. It will automatically collect
16
16
  vector creation requests over a 100ms (configurable) timeframe and batch them to minimize
17
- vector creation requests.
17
+ web requests.
18
18
 
19
19
  It is most useful in web server contexts where multiple user requests may be
20
20
  creating vectors at the same time. If you rely on the same `VectorManager` instance
@@ -55,9 +55,9 @@ const Vectors = new VectorManager();
55
55
 
56
56
  ## Usage
57
57
 
58
- Once you've imported and instantiated the package, you can use it like so.
58
+ Once you've imported and instantiated the package, it's easy to use.
59
59
 
60
- Set a batch engine:
60
+ ### Set a batch engine
61
61
 
62
62
  ```javascript
63
63
  // values will automatically be batched appropriately
@@ -70,13 +70,15 @@ Vectors.setEngine(async (values) => {
70
70
  });
71
71
  ```
72
72
 
73
- Create a single vector:
73
+ ### Create a vector
74
74
 
75
75
  ```javascript
76
76
  let vector = await Vectors.create(`Something to vectorize!`);
77
77
  ```
78
78
 
79
- Create multiple vectors, will automatically batch:
79
+ ### Create multiple vectors
80
+
81
+ Manually manage vector creation:
80
82
 
81
83
  ```javascript
82
84
  const myStrings = [
@@ -89,7 +91,7 @@ const myStrings = [
89
91
  let vectors = await Promise.all(myStrings.map(str => Vectors.create(str)));
90
92
  ```
91
93
 
92
- Create multiple vectors with `batchCreate` utility:
94
+ Or create multiple vectors easily with the `batchCreate` utility:
93
95
 
94
96
  ```javascript
95
97
  const myStrings = [
@@ -102,7 +104,21 @@ const myStrings = [
102
104
  let vectors = await Vectors.batchCreate(myStrings);
103
105
  ```
104
106
 
105
- # Acknowledgements
107
+ ## Configuration
108
+
109
+ You can configure the following parameters:
110
+
111
+ ```javascript
112
+ const Vectors = new VectorManager();
113
+
114
+ // these are the defaults
115
+ Vectors.maximumBatchSize = 7168 * 4; // maximum size of a batch - for OpenAI, 4 tokens per word, estimated
116
+ Vectors.maximumParallelRequests = 10; // 10 web requests simultaneously max
117
+ Vectors.fastQueueTime = 10; // time to wait if no other entries are added
118
+ Vectors.waitQueueTime = 100; // time to wait to collect entries if 1+ entries are added
119
+ ```
120
+
121
+ ## Acknowledgements
106
122
 
107
123
  Special thank you to [Scott Gamble](https://x.com/threesided) who helps run all
108
124
  of the front-of-house work for instant.dev 💜!
@@ -83,18 +83,29 @@ class VectorManager {
83
83
  let i = 0;
84
84
  while (batches.length) {
85
85
  const parallelBatches = batches.splice(0, this.maximumParallelRequests);
86
- const parallelVectors = await Promise.all(parallelBatches.map(strValues => this.vectorizeValues(strValues)));
87
- parallelVectors.forEach((vectors, j) => {
88
- vectors = Array.isArray(vectors)
89
- ? vectors
90
- : [];
91
- parallelBatches[j].forEach((str, k) => {
92
- if (vectors[k]) {
93
- this._results.set(queue[i++], vectors[k]);
94
- } else {
95
- this._results.set(queue[i++], -1);
96
- }
97
- });
86
+ const parallelVectors = await Promise.allSettled(parallelBatches.map(strValues => this.vectorizeValues(strValues)));
87
+ parallelVectors.forEach((result, j) => {
88
+ if (result.status === 'rejected') {
89
+ parallelBatches[j].forEach((str, k) => {
90
+ let reason = result.reason;
91
+ if (!(reason instanceof Error)) {
92
+ reason = new Error(reason);
93
+ }
94
+ this._results.set(queue[i++], reason);
95
+ });
96
+ } else {
97
+ let vectors = result.value;
98
+ vectors = Array.isArray(vectors)
99
+ ? vectors
100
+ : [];
101
+ parallelBatches[j].forEach((str, k) => {
102
+ if (vectors[k]) {
103
+ this._results.set(queue[i++], vectors[k]);
104
+ } else {
105
+ this._results.set(queue[i++], -1);
106
+ }
107
+ });
108
+ }
98
109
  });
99
110
  }
100
111
  return true;
@@ -165,7 +176,9 @@ class VectorManager {
165
176
  await this.__sleep__(10);
166
177
  }
167
178
  this._results.delete(item);
168
- if (!Array.isArray(result)) {
179
+ if (result instanceof Error) {
180
+ throw result;
181
+ } else if (!Array.isArray(result)) {
169
182
  throw new Error(
170
183
  `Could not vectorize: vector engine did not return a valid vector for input "${value}"`
171
184
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instant.dev/vectors",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Utility for batch creating vectors via API",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -50,6 +50,27 @@ module.exports = (InstantORM, Databases) => {
50
50
 
51
51
  });
52
52
 
53
+ it('Should throw error when vector engine throws error', async () => {
54
+
55
+ const testPhrase = `I am extremely happy`;
56
+
57
+ Vectors.setEngine(async (values) => {
58
+ throw new Error(`Not good!`);
59
+ });
60
+
61
+ let vector;
62
+
63
+ try {
64
+ vector = await Vectors.create(testPhrase);
65
+ } catch (e) {
66
+ error = e;
67
+ }
68
+
69
+ expect(error).to.exist;
70
+ expect(error.message).to.equal('Not good!');
71
+
72
+ });
73
+
53
74
  it('Should succeed at vectorizing when vector engine is set properly', async () => {
54
75
 
55
76
  const testPhrase = `I am extremely happy`;