triangle-utils 1.4.87 → 1.4.89
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/src/UtilsS3.js +42 -36
- package/dist/src/UtilsS3Vectors.d.ts +17 -12
- package/dist/src/UtilsS3Vectors.js +152 -62
- package/dist/src/f.js +15 -8
- package/package.json +1 -1
- package/src/UtilsS3.ts +44 -38
- package/src/UtilsS3Vectors.ts +164 -67
- package/src/UtilsXAI.ts +1 -1
- package/src/f.ts +17 -12
package/dist/src/UtilsS3.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { S3, NoSuchKey, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
2
2
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
3
3
|
import { Readable } from "stream";
|
|
4
|
-
function
|
|
4
|
+
function get_s3_input(s3_id) {
|
|
5
5
|
const [bucket, path] = (s3_id.match(/^s3\:\/\/([^\/]+)\/([^$]+)$/) || []).slice(1, 3);
|
|
6
6
|
if (bucket === undefined || path === undefined) {
|
|
7
7
|
return undefined;
|
|
@@ -14,12 +14,12 @@ export class UtilsS3 {
|
|
|
14
14
|
this.s3 = new S3({ region: region });
|
|
15
15
|
}
|
|
16
16
|
async get_headers(s3_id) {
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
17
|
+
const s3_input = get_s3_input(s3_id);
|
|
18
|
+
if (s3_input === undefined) {
|
|
19
19
|
return undefined;
|
|
20
20
|
}
|
|
21
21
|
try {
|
|
22
|
-
const headers = await this.s3.headObject(
|
|
22
|
+
const headers = await this.s3.headObject(s3_input);
|
|
23
23
|
return {
|
|
24
24
|
size: headers.ContentLength,
|
|
25
25
|
...headers
|
|
@@ -30,12 +30,12 @@ export class UtilsS3 {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async get(s3_id, encoding = "utf-8") {
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
33
|
+
const s3_input = get_s3_input(s3_id);
|
|
34
|
+
if (s3_input === undefined) {
|
|
35
35
|
return undefined;
|
|
36
36
|
}
|
|
37
37
|
try {
|
|
38
|
-
const response = await this.s3.getObject(
|
|
38
|
+
const response = await this.s3.getObject(s3_input);
|
|
39
39
|
const body = response.Body;
|
|
40
40
|
if (body === undefined) {
|
|
41
41
|
return undefined;
|
|
@@ -51,12 +51,12 @@ export class UtilsS3 {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
async get_buffer(s3_id) {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
54
|
+
const s3_input = get_s3_input(s3_id);
|
|
55
|
+
if (s3_input === undefined) {
|
|
56
56
|
return undefined;
|
|
57
57
|
}
|
|
58
58
|
try {
|
|
59
|
-
const response = await this.s3.getObject(
|
|
59
|
+
const response = await this.s3.getObject(s3_input);
|
|
60
60
|
const body = response.Body;
|
|
61
61
|
if (body === undefined) {
|
|
62
62
|
return undefined;
|
|
@@ -72,12 +72,12 @@ export class UtilsS3 {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
async get_stream(s3_id) {
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
75
|
+
const s3_input = get_s3_input(s3_id);
|
|
76
|
+
if (s3_input === undefined) {
|
|
77
77
|
return undefined;
|
|
78
78
|
}
|
|
79
79
|
try {
|
|
80
|
-
const response = await this.s3.getObject(
|
|
80
|
+
const response = await this.s3.getObject(s3_input);
|
|
81
81
|
const body = response.Body;
|
|
82
82
|
if (body === undefined) {
|
|
83
83
|
return undefined;
|
|
@@ -96,28 +96,34 @@ export class UtilsS3 {
|
|
|
96
96
|
}
|
|
97
97
|
async query_prefix(s3_id_prefix, options = {}) {
|
|
98
98
|
const compile = options.compile !== undefined ? options.compile : false;
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
99
|
+
const s3_input = get_s3_input(s3_id_prefix);
|
|
100
|
+
if (s3_input === undefined) {
|
|
101
101
|
return [];
|
|
102
102
|
}
|
|
103
103
|
const s3_ids = [];
|
|
104
104
|
let last_token = undefined;
|
|
105
105
|
while (true) {
|
|
106
|
-
const
|
|
107
|
-
Bucket:
|
|
106
|
+
const request = {
|
|
107
|
+
Bucket: s3_input.Bucket,
|
|
108
108
|
Delimiter: "/",
|
|
109
|
-
Prefix:
|
|
109
|
+
Prefix: s3_input.Key,
|
|
110
110
|
ContinuationToken: last_token
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
const new_s3_ids = response.Contents
|
|
111
|
+
};
|
|
112
|
+
const response = await this.s3.listObjectsV2(request);
|
|
113
|
+
const new_s3_ids = (response.Contents || [])
|
|
116
114
|
.map(content => content.Key)
|
|
117
115
|
.filter(key => key !== undefined)
|
|
118
116
|
.filter(key => key.substring(key.length - 1) !== "/")
|
|
119
|
-
.map(key => "s3://" +
|
|
117
|
+
.map(key => "s3://" + s3_input.Bucket + "/" + key);
|
|
120
118
|
s3_ids.push(...new_s3_ids);
|
|
119
|
+
const sub_s3_id_prefixes = (response.CommonPrefixes || [])
|
|
120
|
+
.map(prefix => prefix.Prefix)
|
|
121
|
+
.filter(prefix => prefix !== undefined)
|
|
122
|
+
.map(prefix => "s3://" + s3_input.Bucket + "/" + prefix);
|
|
123
|
+
for (const sub_s3_id_prefix of sub_s3_id_prefixes) {
|
|
124
|
+
const new_sub_s3_ids = await this.query_prefix(sub_s3_id_prefix);
|
|
125
|
+
s3_ids.push(...new_sub_s3_ids);
|
|
126
|
+
}
|
|
121
127
|
if (response.NextContinuationToken === undefined || !compile) {
|
|
122
128
|
return s3_ids;
|
|
123
129
|
}
|
|
@@ -130,42 +136,42 @@ export class UtilsS3 {
|
|
|
130
136
|
if (headers !== undefined) {
|
|
131
137
|
return undefined;
|
|
132
138
|
}
|
|
133
|
-
const
|
|
134
|
-
if (
|
|
139
|
+
const s3_input = get_s3_input(s3_id);
|
|
140
|
+
if (s3_input === undefined) {
|
|
135
141
|
return undefined;
|
|
136
142
|
}
|
|
137
143
|
return await this.s3.putObject({
|
|
138
|
-
...
|
|
144
|
+
...s3_input,
|
|
139
145
|
Body: content,
|
|
140
146
|
ContentType: content_type
|
|
141
147
|
});
|
|
142
148
|
}
|
|
143
149
|
async delete(s3_id) {
|
|
144
|
-
const
|
|
145
|
-
if (
|
|
150
|
+
const s3_input = get_s3_input(s3_id);
|
|
151
|
+
if (s3_input === undefined) {
|
|
146
152
|
return undefined;
|
|
147
153
|
}
|
|
148
|
-
await this.s3.deleteObject(
|
|
154
|
+
await this.s3.deleteObject(s3_input);
|
|
149
155
|
}
|
|
150
156
|
async get_download_url(s3_id) {
|
|
151
157
|
const headers = await this.get_headers(s3_id);
|
|
152
158
|
if (headers === undefined) {
|
|
153
159
|
return undefined;
|
|
154
160
|
}
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
161
|
+
const s3_input = get_s3_input(s3_id);
|
|
162
|
+
if (s3_input === undefined) {
|
|
157
163
|
return undefined;
|
|
158
164
|
}
|
|
159
|
-
const command = new GetObjectCommand(
|
|
165
|
+
const command = new GetObjectCommand(s3_input);
|
|
160
166
|
const url = await getSignedUrl(this.s3, command);
|
|
161
167
|
return url;
|
|
162
168
|
}
|
|
163
169
|
async get_upload_url(s3_id) {
|
|
164
|
-
const
|
|
165
|
-
if (
|
|
170
|
+
const s3_input = get_s3_input(s3_id);
|
|
171
|
+
if (s3_input === undefined) {
|
|
166
172
|
return undefined;
|
|
167
173
|
}
|
|
168
|
-
const command = new PutObjectCommand(
|
|
174
|
+
const command = new PutObjectCommand(s3_input);
|
|
169
175
|
const url = await getSignedUrl(this.s3, command);
|
|
170
176
|
return url;
|
|
171
177
|
}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export declare class S3Vector {
|
|
2
|
+
readonly s3_vector_id: string;
|
|
3
|
+
readonly coordinates: number[];
|
|
4
|
+
readonly headers: Record<string, any>;
|
|
5
|
+
constructor(s3_vector: S3Vector);
|
|
6
|
+
static is(s3_vector: any): s3_vector is S3Vector;
|
|
5
7
|
}
|
|
6
8
|
export declare class UtilsS3Vectors {
|
|
7
9
|
private readonly s3vectors;
|
|
8
10
|
constructor(region: string);
|
|
9
|
-
scan(
|
|
10
|
-
get(
|
|
11
|
-
batch_get(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
delete(
|
|
15
|
-
batch_delete(
|
|
16
|
-
query(
|
|
11
|
+
scan(s3_vector_id_prefix: string): Promise<string[]>;
|
|
12
|
+
get(s3_vector_id: string): Promise<S3Vector | undefined>;
|
|
13
|
+
batch_get(s3_vector_ids: string[]): Promise<(S3Vector | undefined)[]>;
|
|
14
|
+
put(s3_vector: S3Vector): Promise<void>;
|
|
15
|
+
batch_put(s3_vectors: S3Vector[]): Promise<void>;
|
|
16
|
+
delete(s3_vector_id: string): Promise<void>;
|
|
17
|
+
batch_delete(s3_vector_ids: string[]): Promise<void>;
|
|
18
|
+
query(s3_vector_id_prefix: string, coordinates: number[], num_vectors: number, filters?: Record<string, any> | undefined): Promise<{
|
|
19
|
+
s3_vector_id: string;
|
|
20
|
+
distance: number;
|
|
21
|
+
}[]>;
|
|
17
22
|
}
|
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
import { S3Vectors } from "@aws-sdk/client-s3vectors";
|
|
2
|
+
export class S3Vector {
|
|
3
|
+
s3_vector_id;
|
|
4
|
+
coordinates;
|
|
5
|
+
headers;
|
|
6
|
+
constructor(s3_vector) {
|
|
7
|
+
if (!S3Vector.is(s3_vector)) {
|
|
8
|
+
throw Error("Invalid input.");
|
|
9
|
+
}
|
|
10
|
+
this.s3_vector_id = s3_vector.s3_vector_id;
|
|
11
|
+
this.coordinates = s3_vector.coordinates;
|
|
12
|
+
this.headers = s3_vector.headers;
|
|
13
|
+
}
|
|
14
|
+
static is(s3_vector) {
|
|
15
|
+
return (s3_vector !== undefined &&
|
|
16
|
+
typeof s3_vector.s3_vector_id === "string" &&
|
|
17
|
+
Array.isArray(s3_vector.coordinates) && s3_vector.coordinates.every((coordinate) => typeof coordinate === "number") &&
|
|
18
|
+
typeof s3_vector.headers === "object" && Object.keys(s3_vector.headers).every((header_id) => typeof header_id === "string"));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function get_s3vectors_input(s3_vector_id) {
|
|
22
|
+
const [s3_vector_bucket_name, s3_vector_index_name, s3_vector_key] = (s3_vector_id.match(/^s3vectors:\/\/([^\/]+)\/([^\/]+)\/([^$]*)$/) || []).slice(1, 4);
|
|
23
|
+
if (s3_vector_bucket_name === undefined || s3_vector_index_name === undefined || s3_vector_key === undefined) {
|
|
24
|
+
throw Error("Bad s3_vector_id: " + s3_vector_id);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
s3_vector_bucket_name: s3_vector_bucket_name,
|
|
28
|
+
s3_vector_index_name: s3_vector_index_name,
|
|
29
|
+
s3_vector_key: s3_vector_key
|
|
30
|
+
};
|
|
31
|
+
}
|
|
2
32
|
export class UtilsS3Vectors {
|
|
3
33
|
s3vectors;
|
|
4
34
|
constructor(region) {
|
|
5
35
|
this.s3vectors = new S3Vectors({ region: region });
|
|
6
36
|
}
|
|
7
|
-
async scan(
|
|
8
|
-
const
|
|
37
|
+
async scan(s3_vector_id_prefix) {
|
|
38
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = get_s3vectors_input(s3_vector_id_prefix);
|
|
39
|
+
const s3_vector_ids = [];
|
|
9
40
|
let next_token = undefined;
|
|
10
41
|
while (true) {
|
|
11
42
|
const request = {
|
|
12
|
-
vectorBucketName:
|
|
13
|
-
indexName:
|
|
43
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
44
|
+
indexName: s3_vector_index_name,
|
|
14
45
|
maxResults: 1000,
|
|
15
46
|
nextToken: next_token
|
|
16
47
|
};
|
|
@@ -18,38 +49,54 @@ export class UtilsS3Vectors {
|
|
|
18
49
|
if (response === undefined || response.vectors === undefined) {
|
|
19
50
|
return [];
|
|
20
51
|
}
|
|
21
|
-
|
|
52
|
+
s3_vector_ids.push(...response.vectors
|
|
53
|
+
.map(vector => vector.key)
|
|
54
|
+
.filter(s3_vector_key => s3_vector_key !== undefined)
|
|
55
|
+
.map(s3_vector_key => "s3vectors://" + s3_vector_bucket_name + "/" + s3_vector_index_name + "/" + s3_vector_key));
|
|
22
56
|
next_token = response.nextToken;
|
|
23
57
|
if (next_token === undefined) {
|
|
24
|
-
return
|
|
58
|
+
return s3_vector_ids;
|
|
25
59
|
}
|
|
26
60
|
}
|
|
27
61
|
}
|
|
28
|
-
async get(
|
|
62
|
+
async get(s3_vector_id) {
|
|
63
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector_id);
|
|
29
64
|
const response = await this.s3vectors.getVectors({
|
|
30
|
-
vectorBucketName:
|
|
31
|
-
indexName:
|
|
32
|
-
keys: [
|
|
65
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
66
|
+
indexName: s3_vector_index_name,
|
|
67
|
+
keys: [s3_vector_key],
|
|
33
68
|
returnData: true,
|
|
34
69
|
returnMetadata: true
|
|
35
70
|
});
|
|
36
71
|
const vector = response.vectors?.[0];
|
|
37
|
-
if (vector === undefined
|
|
72
|
+
if (vector === undefined) {
|
|
38
73
|
return undefined;
|
|
39
74
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
const coordinates = vector.data?.float32;
|
|
76
|
+
const headers = vector.metadata;
|
|
77
|
+
const s3_vector = {
|
|
78
|
+
s3_vector_id: s3_vector_id,
|
|
79
|
+
coordinates: coordinates,
|
|
80
|
+
headers: headers
|
|
44
81
|
};
|
|
82
|
+
if (!S3Vector.is(s3_vector)) {
|
|
83
|
+
console.log("Bad S3Vector:", s3_vector);
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return s3_vector;
|
|
45
87
|
}
|
|
46
|
-
async batch_get(
|
|
47
|
-
const
|
|
48
|
-
|
|
88
|
+
async batch_get(s3_vector_ids) {
|
|
89
|
+
const s3vectors_inputs = s3_vector_ids.map(get_s3vectors_input);
|
|
90
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0];
|
|
91
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const s3_vectors = [];
|
|
95
|
+
for (let i = 0; i < s3vectors_inputs.length; i += 100) {
|
|
49
96
|
const new_vectors = await this.s3vectors.getVectors({
|
|
50
|
-
vectorBucketName:
|
|
51
|
-
indexName:
|
|
52
|
-
keys:
|
|
97
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
98
|
+
indexName: s3_vector_index_name,
|
|
99
|
+
keys: s3vectors_inputs.slice(i, i + 100).map(s3vectors_input => s3vectors_input.s3_vector_key),
|
|
53
100
|
returnData: true,
|
|
54
101
|
returnMetadata: true
|
|
55
102
|
})
|
|
@@ -57,75 +104,118 @@ export class UtilsS3Vectors {
|
|
|
57
104
|
if (new_vectors === undefined) {
|
|
58
105
|
return [];
|
|
59
106
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
107
|
+
const new_s3_vectors = [];
|
|
108
|
+
for (const new_vector of new_vectors) {
|
|
109
|
+
const s3_vector_key = new_vector.key;
|
|
110
|
+
const coordinates = new_vector.data?.float32;
|
|
111
|
+
const headers = new_vector.metadata;
|
|
112
|
+
const new_s3_vector = {
|
|
113
|
+
s3_vector_id: "s3vectors://" + s3_vector_bucket_name + "/" + s3_vector_index_name + "/" + s3_vector_key,
|
|
114
|
+
coordinates: coordinates,
|
|
115
|
+
headers: headers
|
|
116
|
+
};
|
|
117
|
+
if (!S3Vector.is(new_s3_vector)) {
|
|
118
|
+
console.log("Bad S3Vector:", new_s3_vector);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
new_s3_vectors.push(new_s3_vector);
|
|
122
|
+
}
|
|
123
|
+
const new_s3_vectors_by_s3_vector_id = Object.fromEntries(new_s3_vectors.map(new_s3_vector => [new_s3_vector.s3_vector_id, new_s3_vector]));
|
|
124
|
+
s3_vectors.push(...s3_vector_ids.slice(i, i + 100).map(s3_vector_id => new_s3_vectors_by_s3_vector_id[s3_vector_id]));
|
|
70
125
|
}
|
|
71
|
-
return
|
|
126
|
+
return s3_vectors;
|
|
72
127
|
}
|
|
73
|
-
async
|
|
128
|
+
async put(s3_vector) {
|
|
129
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector.s3_vector_id);
|
|
74
130
|
await this.s3vectors.putVectors({
|
|
75
|
-
vectorBucketName:
|
|
76
|
-
indexName:
|
|
131
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
132
|
+
indexName: s3_vector_index_name,
|
|
77
133
|
vectors: [{
|
|
78
|
-
key:
|
|
134
|
+
key: s3_vector_key,
|
|
79
135
|
data: {
|
|
80
|
-
float32:
|
|
136
|
+
float32: s3_vector.coordinates
|
|
81
137
|
},
|
|
82
|
-
metadata:
|
|
138
|
+
metadata: s3_vector.headers
|
|
83
139
|
}]
|
|
84
140
|
});
|
|
85
141
|
}
|
|
86
|
-
async
|
|
87
|
-
|
|
142
|
+
async batch_put(s3_vectors) {
|
|
143
|
+
const s3vectors_inputs = s3_vectors.map(s3_vector => get_s3vectors_input(s3_vector.s3_vector_id));
|
|
144
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0];
|
|
145
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
for (let i = 0; i < s3_vectors.length; i += 100) {
|
|
88
149
|
await this.s3vectors.putVectors({
|
|
89
|
-
vectorBucketName:
|
|
90
|
-
indexName:
|
|
91
|
-
vectors:
|
|
92
|
-
key:
|
|
150
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
151
|
+
indexName: s3_vector_index_name,
|
|
152
|
+
vectors: s3_vectors.slice(i, i + 100).map(s3_vector => ({
|
|
153
|
+
key: get_s3vectors_input(s3_vector.s3_vector_id).s3_vector_key,
|
|
93
154
|
data: {
|
|
94
|
-
float32:
|
|
155
|
+
float32: s3_vector.coordinates
|
|
95
156
|
},
|
|
96
|
-
metadata:
|
|
157
|
+
metadata: s3_vector.headers
|
|
97
158
|
}))
|
|
98
159
|
});
|
|
99
160
|
}
|
|
100
161
|
}
|
|
101
|
-
async delete(
|
|
162
|
+
async delete(s3_vector_id) {
|
|
163
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector_id);
|
|
102
164
|
await this.s3vectors.deleteVectors({
|
|
103
|
-
vectorBucketName:
|
|
104
|
-
indexName:
|
|
105
|
-
keys: [
|
|
165
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
166
|
+
indexName: s3_vector_index_name,
|
|
167
|
+
keys: [s3_vector_key]
|
|
106
168
|
});
|
|
107
169
|
}
|
|
108
|
-
async batch_delete(
|
|
109
|
-
|
|
170
|
+
async batch_delete(s3_vector_ids) {
|
|
171
|
+
const s3vectors_inputs = s3_vector_ids.map(get_s3vectors_input);
|
|
172
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0];
|
|
173
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
for (let i = 0; i < s3vectors_inputs.length; i += 100) {
|
|
110
177
|
await this.s3vectors.deleteVectors({
|
|
111
|
-
vectorBucketName:
|
|
112
|
-
indexName:
|
|
113
|
-
keys:
|
|
178
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
179
|
+
indexName: s3_vector_index_name,
|
|
180
|
+
keys: s3vectors_inputs.slice(i, i + 100).map(s3vectors_input => s3vectors_input.s3_vector_key)
|
|
114
181
|
});
|
|
115
182
|
}
|
|
116
183
|
}
|
|
117
|
-
async query(
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
184
|
+
async query(s3_vector_id_prefix, coordinates, num_vectors, filters = undefined) {
|
|
185
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = get_s3vectors_input(s3_vector_id_prefix);
|
|
186
|
+
const new_vectors = await this.s3vectors.queryVectors({
|
|
187
|
+
vectorBucketName: s3_vector_bucket_name,
|
|
188
|
+
indexName: s3_vector_index_name,
|
|
121
189
|
queryVector: {
|
|
122
|
-
float32:
|
|
190
|
+
float32: coordinates
|
|
123
191
|
},
|
|
124
192
|
topK: num_vectors,
|
|
125
193
|
returnDistance: true,
|
|
126
194
|
returnMetadata: true,
|
|
127
195
|
filter: filters
|
|
128
|
-
})
|
|
129
|
-
|
|
196
|
+
})
|
|
197
|
+
.then(response => response.vectors);
|
|
198
|
+
if (new_vectors === undefined) {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
const results = [];
|
|
202
|
+
for (const new_vector of new_vectors) {
|
|
203
|
+
const s3_vector_key = new_vector.key;
|
|
204
|
+
if (s3_vector_key === undefined) {
|
|
205
|
+
console.log("Bad s3_vector_key:", s3_vector_key);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const s3_vector_id = s3_vector_id_prefix + "/" + s3_vector_key;
|
|
209
|
+
const distance = new_vector.distance;
|
|
210
|
+
if (distance === undefined) {
|
|
211
|
+
console.log("Bad distance:", distance);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
results.push({
|
|
215
|
+
s3_vector_id: s3_vector_id,
|
|
216
|
+
distance: distance
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return results;
|
|
130
220
|
}
|
|
131
221
|
}
|
package/dist/src/f.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SecretsManager } from "@aws-sdk/client-secrets-manager";
|
|
2
2
|
import { TriangleUtils } from "./index.js";
|
|
3
3
|
console.log("Starting triangle-utils!");
|
|
4
|
-
const secret_name = "
|
|
4
|
+
const secret_name = "global_config";
|
|
5
5
|
const secrets_manager = new SecretsManager({ region: "us-east-1" });
|
|
6
6
|
const secret = await secrets_manager.getSecretValue({
|
|
7
7
|
SecretId: secret_name
|
|
@@ -15,6 +15,9 @@ const config = {
|
|
|
15
15
|
};
|
|
16
16
|
console.log(config);
|
|
17
17
|
const utils = new TriangleUtils(config);
|
|
18
|
+
const raw_s3_id_prefix = config.s3_scout + "/raw_scout_documents/57523929653b604e/";
|
|
19
|
+
const raw_s3_ids = await utils.s3.query_prefix(raw_s3_id_prefix, { compile: true });
|
|
20
|
+
console.log(raw_s3_ids);
|
|
18
21
|
// const text = await utils.xai.grok_simple_query("grok-4.3", "Find the X username corresponding to the candidate of the committee \"Darializa for Congress\"", {
|
|
19
22
|
// print_usage : true,
|
|
20
23
|
// json_format : {
|
|
@@ -218,10 +221,14 @@ const utils = new TriangleUtils(config);
|
|
|
218
221
|
// console.log(results)
|
|
219
222
|
// const f = await utils.dynamodb.query_range("federal_election_donations:donor_address_state_id.federal_election_committee_id-receipt_date-federal_election_donation_id", { donor_address_state_id : "NH", federal_election_committee_id : "C00694323" }, { receipt_date : ["2021", "2023"] }, { compile : false })
|
|
220
223
|
// console.log(f)
|
|
221
|
-
console.log("YERP")
|
|
222
|
-
const response = await utils.bedrock.claude_converse(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
// console.log("YERP")
|
|
225
|
+
// const response = await utils.bedrock.claude_converse(
|
|
226
|
+
// "anthropic.claude-opus-4-8",
|
|
227
|
+
// [
|
|
228
|
+
// { role : "user", text : "Hi" }
|
|
229
|
+
// ],
|
|
230
|
+
// {
|
|
231
|
+
// print_usage : true
|
|
232
|
+
// }
|
|
233
|
+
// )
|
|
234
|
+
// console.log(response)
|
package/package.json
CHANGED
package/src/UtilsS3.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { S3, NoSuchKey, GetObjectCommand, PutObjectCommand, ListObjectsV2CommandOutput } from "@aws-sdk/client-s3"
|
|
1
|
+
import { S3, NoSuchKey, GetObjectCommand, PutObjectCommand, ListObjectsV2CommandOutput, ListObjectsV2CommandInput } from "@aws-sdk/client-s3"
|
|
2
2
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
|
|
3
3
|
import { Readable } from "stream"
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
interface S3Input {
|
|
6
6
|
Bucket : string,
|
|
7
7
|
Key : string
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
function
|
|
10
|
+
function get_s3_input(s3_id : string) : S3Input | undefined {
|
|
11
11
|
const [bucket, path] = (s3_id.match(/^s3\:\/\/([^\/]+)\/([^$]+)$/) || []).slice(1, 3)
|
|
12
12
|
if (bucket === undefined || path === undefined) {
|
|
13
13
|
return undefined
|
|
@@ -24,12 +24,12 @@ export class UtilsS3 {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async get_headers(s3_id : string) {
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
27
|
+
const s3_input = get_s3_input(s3_id)
|
|
28
|
+
if (s3_input === undefined) {
|
|
29
29
|
return undefined
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
|
-
const headers = await this.s3.headObject(
|
|
32
|
+
const headers = await this.s3.headObject(s3_input)
|
|
33
33
|
return {
|
|
34
34
|
size : headers.ContentLength,
|
|
35
35
|
...headers
|
|
@@ -40,12 +40,12 @@ export class UtilsS3 {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
async get(s3_id : string, encoding : string = "utf-8") : Promise<string | undefined> {
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
43
|
+
const s3_input = get_s3_input(s3_id)
|
|
44
|
+
if (s3_input === undefined) {
|
|
45
45
|
return undefined
|
|
46
46
|
}
|
|
47
47
|
try {
|
|
48
|
-
const response = await this.s3.getObject(
|
|
48
|
+
const response = await this.s3.getObject(s3_input)
|
|
49
49
|
const body = response.Body
|
|
50
50
|
if (body === undefined) {
|
|
51
51
|
return undefined
|
|
@@ -61,12 +61,12 @@ export class UtilsS3 {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
async get_buffer(s3_id : string) : Promise<Buffer | undefined> {
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
64
|
+
const s3_input = get_s3_input(s3_id)
|
|
65
|
+
if (s3_input === undefined) {
|
|
66
66
|
return undefined
|
|
67
67
|
}
|
|
68
68
|
try {
|
|
69
|
-
const response = await this.s3.getObject(
|
|
69
|
+
const response = await this.s3.getObject(s3_input)
|
|
70
70
|
const body = response.Body
|
|
71
71
|
if (body === undefined) {
|
|
72
72
|
return undefined
|
|
@@ -82,12 +82,12 @@ export class UtilsS3 {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
async get_stream(s3_id : string) : Promise<Readable | undefined> {
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
85
|
+
const s3_input = get_s3_input(s3_id)
|
|
86
|
+
if (s3_input === undefined) {
|
|
87
87
|
return undefined
|
|
88
88
|
}
|
|
89
89
|
try {
|
|
90
|
-
const response = await this.s3.getObject(
|
|
90
|
+
const response = await this.s3.getObject(s3_input)
|
|
91
91
|
const body = response.Body
|
|
92
92
|
if (body === undefined) {
|
|
93
93
|
return undefined
|
|
@@ -106,28 +106,34 @@ export class UtilsS3 {
|
|
|
106
106
|
|
|
107
107
|
async query_prefix(s3_id_prefix : string, options : { compile? : boolean } = {}) {
|
|
108
108
|
const compile = options.compile !== undefined ? options.compile : false
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
109
|
+
const s3_input = get_s3_input(s3_id_prefix)
|
|
110
|
+
if (s3_input === undefined) {
|
|
111
111
|
return []
|
|
112
112
|
}
|
|
113
|
-
const s3_ids = []
|
|
113
|
+
const s3_ids : string[] = []
|
|
114
114
|
let last_token : string | undefined = undefined
|
|
115
115
|
while (true) {
|
|
116
|
-
const
|
|
117
|
-
Bucket :
|
|
116
|
+
const request : ListObjectsV2CommandInput = {
|
|
117
|
+
Bucket : s3_input.Bucket,
|
|
118
118
|
Delimiter : "/",
|
|
119
|
-
Prefix :
|
|
119
|
+
Prefix : s3_input.Key,
|
|
120
120
|
ContinuationToken : last_token
|
|
121
|
-
})
|
|
122
|
-
if (response.Contents === undefined) {
|
|
123
|
-
return []
|
|
124
121
|
}
|
|
125
|
-
const
|
|
122
|
+
const response : ListObjectsV2CommandOutput = await this.s3.listObjectsV2(request)
|
|
123
|
+
const new_s3_ids = (response.Contents || [])
|
|
126
124
|
.map(content => content.Key)
|
|
127
125
|
.filter(key => key !== undefined)
|
|
128
126
|
.filter(key => key.substring(key.length - 1) !== "/")
|
|
129
|
-
.map(key => "s3://" +
|
|
127
|
+
.map(key => "s3://" + s3_input.Bucket + "/" + key)
|
|
130
128
|
s3_ids.push(...new_s3_ids)
|
|
129
|
+
const sub_s3_id_prefixes = (response.CommonPrefixes || [])
|
|
130
|
+
.map(prefix => prefix.Prefix)
|
|
131
|
+
.filter(prefix => prefix !== undefined)
|
|
132
|
+
.map(prefix => "s3://" + s3_input.Bucket + "/" + prefix)
|
|
133
|
+
for (const sub_s3_id_prefix of sub_s3_id_prefixes) {
|
|
134
|
+
const new_sub_s3_ids = await this.query_prefix(sub_s3_id_prefix)
|
|
135
|
+
s3_ids.push(...new_sub_s3_ids)
|
|
136
|
+
}
|
|
131
137
|
if (response.NextContinuationToken === undefined || !compile) {
|
|
132
138
|
return s3_ids
|
|
133
139
|
}
|
|
@@ -144,23 +150,23 @@ export class UtilsS3 {
|
|
|
144
150
|
if (headers !== undefined) {
|
|
145
151
|
return undefined
|
|
146
152
|
}
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
153
|
+
const s3_input = get_s3_input(s3_id)
|
|
154
|
+
if (s3_input === undefined) {
|
|
149
155
|
return undefined
|
|
150
156
|
}
|
|
151
157
|
return await this.s3.putObject({
|
|
152
|
-
...
|
|
158
|
+
...s3_input,
|
|
153
159
|
Body : content,
|
|
154
160
|
ContentType : content_type
|
|
155
161
|
})
|
|
156
162
|
}
|
|
157
163
|
|
|
158
164
|
async delete(s3_id : string) : Promise<void>{
|
|
159
|
-
const
|
|
160
|
-
if (
|
|
165
|
+
const s3_input = get_s3_input(s3_id)
|
|
166
|
+
if (s3_input === undefined) {
|
|
161
167
|
return undefined
|
|
162
168
|
}
|
|
163
|
-
await this.s3.deleteObject(
|
|
169
|
+
await this.s3.deleteObject(s3_input)
|
|
164
170
|
}
|
|
165
171
|
|
|
166
172
|
async get_download_url(s3_id : string) : Promise<string | undefined> {
|
|
@@ -168,21 +174,21 @@ export class UtilsS3 {
|
|
|
168
174
|
if (headers === undefined) {
|
|
169
175
|
return undefined
|
|
170
176
|
}
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
177
|
+
const s3_input = get_s3_input(s3_id)
|
|
178
|
+
if (s3_input === undefined) {
|
|
173
179
|
return undefined
|
|
174
180
|
}
|
|
175
|
-
const command = new GetObjectCommand(
|
|
181
|
+
const command = new GetObjectCommand(s3_input)
|
|
176
182
|
const url = await getSignedUrl(this.s3, command)
|
|
177
183
|
return url
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
async get_upload_url(s3_id : string) : Promise<string | undefined> {
|
|
181
|
-
const
|
|
182
|
-
if (
|
|
187
|
+
const s3_input = get_s3_input(s3_id)
|
|
188
|
+
if (s3_input === undefined) {
|
|
183
189
|
return undefined
|
|
184
190
|
}
|
|
185
|
-
const command = new PutObjectCommand(
|
|
191
|
+
const command = new PutObjectCommand(s3_input)
|
|
186
192
|
const url = await getSignedUrl(this.s3, command)
|
|
187
193
|
return url
|
|
188
194
|
}
|
package/src/UtilsS3Vectors.ts
CHANGED
|
@@ -1,9 +1,45 @@
|
|
|
1
1
|
import { ListVectorsCommandInput, S3Vectors } from "@aws-sdk/client-s3vectors"
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export class S3Vector {
|
|
4
|
+
readonly s3_vector_id : string
|
|
5
|
+
readonly coordinates : number[]
|
|
6
|
+
readonly headers : Record<string, any>
|
|
7
|
+
|
|
8
|
+
constructor(s3_vector : S3Vector) {
|
|
9
|
+
if (!S3Vector.is(s3_vector)) {
|
|
10
|
+
throw Error("Invalid input.")
|
|
11
|
+
}
|
|
12
|
+
this.s3_vector_id = s3_vector.s3_vector_id
|
|
13
|
+
this.coordinates = s3_vector.coordinates
|
|
14
|
+
this.headers = s3_vector.headers
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static is(s3_vector : any) : s3_vector is S3Vector {
|
|
18
|
+
return (
|
|
19
|
+
s3_vector !== undefined &&
|
|
20
|
+
typeof s3_vector.s3_vector_id === "string" &&
|
|
21
|
+
Array.isArray(s3_vector.coordinates) && s3_vector.coordinates.every((coordinate : any) => typeof coordinate === "number") &&
|
|
22
|
+
typeof s3_vector.headers === "object" && Object.keys(s3_vector.headers).every((header_id : any) => typeof header_id === "string")
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface S3VectorsInput {
|
|
28
|
+
s3_vector_bucket_name : string,
|
|
29
|
+
s3_vector_index_name : string,
|
|
30
|
+
s3_vector_key : string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function get_s3vectors_input(s3_vector_id : string) : S3VectorsInput {
|
|
34
|
+
const [s3_vector_bucket_name, s3_vector_index_name, s3_vector_key] = (s3_vector_id.match(/^s3vectors:\/\/([^\/]+)\/([^\/]+)\/([^$]*)$/) || []).slice(1, 4)
|
|
35
|
+
if (s3_vector_bucket_name === undefined || s3_vector_index_name === undefined || s3_vector_key === undefined) {
|
|
36
|
+
throw Error("Bad s3_vector_id: " + s3_vector_id)
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
s3_vector_bucket_name : s3_vector_bucket_name,
|
|
40
|
+
s3_vector_index_name : s3_vector_index_name,
|
|
41
|
+
s3_vector_key : s3_vector_key
|
|
42
|
+
}
|
|
7
43
|
}
|
|
8
44
|
|
|
9
45
|
export class UtilsS3Vectors {
|
|
@@ -14,13 +50,14 @@ export class UtilsS3Vectors {
|
|
|
14
50
|
this.s3vectors = new S3Vectors({ region : region })
|
|
15
51
|
}
|
|
16
52
|
|
|
17
|
-
async scan(
|
|
18
|
-
const
|
|
53
|
+
async scan(s3_vector_id_prefix : string) : Promise<string[]> {
|
|
54
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = get_s3vectors_input(s3_vector_id_prefix)
|
|
55
|
+
const s3_vector_ids : string[] = []
|
|
19
56
|
let next_token : string | undefined = undefined
|
|
20
57
|
while (true) {
|
|
21
58
|
const request : ListVectorsCommandInput = {
|
|
22
|
-
vectorBucketName :
|
|
23
|
-
indexName :
|
|
59
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
60
|
+
indexName : s3_vector_index_name,
|
|
24
61
|
maxResults : 1000,
|
|
25
62
|
nextToken : next_token
|
|
26
63
|
}
|
|
@@ -28,40 +65,58 @@ export class UtilsS3Vectors {
|
|
|
28
65
|
if (response === undefined || response.vectors === undefined) {
|
|
29
66
|
return []
|
|
30
67
|
}
|
|
31
|
-
|
|
68
|
+
s3_vector_ids.push(
|
|
69
|
+
...response.vectors
|
|
70
|
+
.map(vector => vector.key)
|
|
71
|
+
.filter(s3_vector_key => s3_vector_key !== undefined)
|
|
72
|
+
.map(s3_vector_key => "s3vectors://" + s3_vector_bucket_name + "/" + s3_vector_index_name + "/" + s3_vector_key)
|
|
73
|
+
)
|
|
32
74
|
next_token = response.nextToken
|
|
33
75
|
if (next_token === undefined) {
|
|
34
|
-
return
|
|
76
|
+
return s3_vector_ids
|
|
35
77
|
}
|
|
36
78
|
}
|
|
37
79
|
}
|
|
38
80
|
|
|
39
|
-
async get(
|
|
81
|
+
async get(s3_vector_id : string) : Promise<S3Vector | undefined> {
|
|
82
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector_id)
|
|
40
83
|
const response = await this.s3vectors.getVectors({
|
|
41
|
-
vectorBucketName :
|
|
42
|
-
indexName :
|
|
43
|
-
keys : [
|
|
84
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
85
|
+
indexName : s3_vector_index_name,
|
|
86
|
+
keys : [s3_vector_key],
|
|
44
87
|
returnData : true,
|
|
45
88
|
returnMetadata : true
|
|
46
89
|
})
|
|
47
90
|
const vector = response.vectors?.[0]
|
|
48
|
-
if (vector === undefined
|
|
91
|
+
if (vector === undefined) {
|
|
49
92
|
return undefined
|
|
50
93
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
94
|
+
const coordinates : any = vector.data?.float32
|
|
95
|
+
const headers : any = vector.metadata
|
|
96
|
+
const s3_vector : S3Vector = {
|
|
97
|
+
s3_vector_id : s3_vector_id,
|
|
98
|
+
coordinates : coordinates,
|
|
99
|
+
headers : headers
|
|
100
|
+
}
|
|
101
|
+
if (!S3Vector.is(s3_vector)) {
|
|
102
|
+
console.log("Bad S3Vector:", s3_vector)
|
|
103
|
+
return undefined
|
|
55
104
|
}
|
|
105
|
+
return s3_vector
|
|
56
106
|
}
|
|
57
107
|
|
|
58
|
-
async batch_get(
|
|
59
|
-
const
|
|
60
|
-
|
|
108
|
+
async batch_get(s3_vector_ids : string[]) {
|
|
109
|
+
const s3vectors_inputs : S3VectorsInput[] = s3_vector_ids.map(get_s3vectors_input)
|
|
110
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0]
|
|
111
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
112
|
+
return []
|
|
113
|
+
}
|
|
114
|
+
const s3_vectors : (S3Vector | undefined)[] = []
|
|
115
|
+
for (let i = 0; i < s3vectors_inputs.length; i += 100) {
|
|
61
116
|
const new_vectors = await this.s3vectors.getVectors({
|
|
62
|
-
vectorBucketName :
|
|
63
|
-
indexName :
|
|
64
|
-
keys :
|
|
117
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
118
|
+
indexName : s3_vector_index_name,
|
|
119
|
+
keys : s3vectors_inputs.slice(i, i + 100).map(s3vectors_input => s3vectors_input.s3_vector_key),
|
|
65
120
|
returnData : true,
|
|
66
121
|
returnMetadata : true
|
|
67
122
|
})
|
|
@@ -69,83 +124,125 @@ export class UtilsS3Vectors {
|
|
|
69
124
|
if (new_vectors === undefined) {
|
|
70
125
|
return []
|
|
71
126
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
127
|
+
const new_s3_vectors : S3Vector[] = []
|
|
128
|
+
for (const new_vector of new_vectors) {
|
|
129
|
+
const s3_vector_key : any = new_vector.key
|
|
130
|
+
const coordinates : any = new_vector.data?.float32
|
|
131
|
+
const headers : any = new_vector.metadata
|
|
132
|
+
const new_s3_vector : S3Vector | undefined = {
|
|
133
|
+
s3_vector_id : "s3vectors://" + s3_vector_bucket_name + "/" + s3_vector_index_name + "/" + s3_vector_key,
|
|
134
|
+
coordinates : coordinates,
|
|
135
|
+
headers : headers
|
|
136
|
+
}
|
|
137
|
+
if (!S3Vector.is(new_s3_vector)) {
|
|
138
|
+
console.log("Bad S3Vector:", new_s3_vector)
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
new_s3_vectors.push(new_s3_vector)
|
|
142
|
+
}
|
|
143
|
+
const new_s3_vectors_by_s3_vector_id = Object.fromEntries(new_s3_vectors.map(new_s3_vector => [new_s3_vector.s3_vector_id, new_s3_vector]))
|
|
144
|
+
s3_vectors.push(...s3_vector_ids.slice(i, i + 100).map(s3_vector_id => new_s3_vectors_by_s3_vector_id[s3_vector_id]))
|
|
83
145
|
}
|
|
84
|
-
return
|
|
146
|
+
return s3_vectors
|
|
85
147
|
}
|
|
86
148
|
|
|
87
|
-
async
|
|
149
|
+
async put(s3_vector : S3Vector) : Promise<void> {
|
|
150
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector.s3_vector_id)
|
|
88
151
|
await this.s3vectors.putVectors({
|
|
89
|
-
vectorBucketName :
|
|
90
|
-
indexName :
|
|
152
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
153
|
+
indexName : s3_vector_index_name,
|
|
91
154
|
vectors : [{
|
|
92
|
-
key :
|
|
155
|
+
key : s3_vector_key,
|
|
93
156
|
data : {
|
|
94
|
-
float32 :
|
|
157
|
+
float32 : s3_vector.coordinates
|
|
95
158
|
},
|
|
96
|
-
metadata :
|
|
159
|
+
metadata : s3_vector.headers
|
|
97
160
|
}]
|
|
98
161
|
})
|
|
99
162
|
}
|
|
100
163
|
|
|
101
|
-
async
|
|
102
|
-
|
|
164
|
+
async batch_put(s3_vectors : S3Vector[]) : Promise<void> {
|
|
165
|
+
const s3vectors_inputs : S3VectorsInput[] = s3_vectors.map(s3_vector => get_s3vectors_input(s3_vector.s3_vector_id))
|
|
166
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0]
|
|
167
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
168
|
+
return undefined
|
|
169
|
+
}
|
|
170
|
+
for (let i = 0; i < s3_vectors.length; i += 100) {
|
|
103
171
|
await this.s3vectors.putVectors({
|
|
104
|
-
vectorBucketName :
|
|
105
|
-
indexName :
|
|
106
|
-
vectors :
|
|
107
|
-
key :
|
|
172
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
173
|
+
indexName : s3_vector_index_name,
|
|
174
|
+
vectors : s3_vectors.slice(i, i + 100).map(s3_vector => ({
|
|
175
|
+
key : get_s3vectors_input(s3_vector.s3_vector_id).s3_vector_key,
|
|
108
176
|
data : {
|
|
109
|
-
float32 :
|
|
177
|
+
float32 : s3_vector.coordinates
|
|
110
178
|
},
|
|
111
|
-
metadata :
|
|
179
|
+
metadata : s3_vector.headers
|
|
112
180
|
}))
|
|
113
181
|
})
|
|
114
182
|
|
|
115
183
|
}
|
|
116
184
|
}
|
|
117
185
|
|
|
118
|
-
async delete(
|
|
186
|
+
async delete(s3_vector_id : string) : Promise<void> {
|
|
187
|
+
const { s3_vector_bucket_name, s3_vector_index_name, s3_vector_key } = get_s3vectors_input(s3_vector_id)
|
|
119
188
|
await this.s3vectors.deleteVectors({
|
|
120
|
-
vectorBucketName :
|
|
121
|
-
indexName :
|
|
122
|
-
keys : [
|
|
189
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
190
|
+
indexName : s3_vector_index_name,
|
|
191
|
+
keys : [s3_vector_key]
|
|
123
192
|
})
|
|
124
193
|
}
|
|
125
194
|
|
|
126
|
-
async batch_delete(
|
|
127
|
-
|
|
195
|
+
async batch_delete(s3_vector_ids : string[]) : Promise<void> {
|
|
196
|
+
const s3vectors_inputs : S3VectorsInput[] = s3_vector_ids.map(get_s3vectors_input)
|
|
197
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = s3vectors_inputs[0]
|
|
198
|
+
if (!s3vectors_inputs.every(s3vectors_input => s3vectors_input.s3_vector_bucket_name === s3_vector_bucket_name && s3vectors_input.s3_vector_index_name === s3_vector_index_name)) {
|
|
199
|
+
return undefined
|
|
200
|
+
}
|
|
201
|
+
for (let i = 0; i < s3vectors_inputs.length; i += 100) {
|
|
128
202
|
await this.s3vectors.deleteVectors({
|
|
129
|
-
vectorBucketName :
|
|
130
|
-
indexName :
|
|
131
|
-
keys :
|
|
203
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
204
|
+
indexName : s3_vector_index_name,
|
|
205
|
+
keys : s3vectors_inputs.slice(i, i + 100).map(s3vectors_input => s3vectors_input.s3_vector_key)
|
|
132
206
|
})
|
|
133
207
|
}
|
|
134
208
|
}
|
|
135
209
|
|
|
136
|
-
async query(
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
210
|
+
async query(s3_vector_id_prefix : string, coordinates : number[], num_vectors : number, filters : Record<string, any> | undefined = undefined) {
|
|
211
|
+
const { s3_vector_bucket_name, s3_vector_index_name } = get_s3vectors_input(s3_vector_id_prefix)
|
|
212
|
+
const new_vectors = await this.s3vectors.queryVectors({
|
|
213
|
+
vectorBucketName : s3_vector_bucket_name,
|
|
214
|
+
indexName : s3_vector_index_name,
|
|
140
215
|
queryVector : {
|
|
141
|
-
float32 :
|
|
216
|
+
float32 : coordinates
|
|
142
217
|
},
|
|
143
|
-
topK : num_vectors,
|
|
218
|
+
topK : num_vectors,
|
|
144
219
|
returnDistance : true,
|
|
145
220
|
returnMetadata : true,
|
|
146
221
|
filter : filters
|
|
147
222
|
})
|
|
148
|
-
|
|
223
|
+
.then(response => response.vectors)
|
|
224
|
+
if (new_vectors === undefined) {
|
|
225
|
+
return []
|
|
226
|
+
}
|
|
227
|
+
const results : { s3_vector_id : string, distance : number }[] = []
|
|
228
|
+
for (const new_vector of new_vectors) {
|
|
229
|
+
const s3_vector_key = new_vector.key
|
|
230
|
+
if (s3_vector_key === undefined) {
|
|
231
|
+
console.log("Bad s3_vector_key:", s3_vector_key)
|
|
232
|
+
continue
|
|
233
|
+
}
|
|
234
|
+
const s3_vector_id = s3_vector_id_prefix + "/" + s3_vector_key
|
|
235
|
+
const distance = new_vector.distance
|
|
236
|
+
if (distance === undefined) {
|
|
237
|
+
console.log("Bad distance:", distance)
|
|
238
|
+
continue
|
|
239
|
+
}
|
|
240
|
+
results.push({
|
|
241
|
+
s3_vector_id : s3_vector_id,
|
|
242
|
+
distance : distance
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
return results
|
|
149
246
|
}
|
|
150
247
|
|
|
151
248
|
}
|
package/src/UtilsXAI.ts
CHANGED
|
@@ -90,7 +90,7 @@ export class UtilsXAI {
|
|
|
90
90
|
"Authorization" : "Bearer " + this.xai_api_key
|
|
91
91
|
}
|
|
92
92
|
})
|
|
93
|
-
const output = await response.json()
|
|
93
|
+
const output : any = await response.json()
|
|
94
94
|
if (options.print_usage !== undefined && options.print_usage) {
|
|
95
95
|
console.log(output.usage)
|
|
96
96
|
}
|
package/src/f.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { TriangleUtils } from "."
|
|
|
3
3
|
|
|
4
4
|
console.log("Starting triangle-utils!")
|
|
5
5
|
|
|
6
|
-
const secret_name = "
|
|
6
|
+
const secret_name = "global_config"
|
|
7
7
|
|
|
8
8
|
const secrets_manager = new SecretsManager({ region: "us-east-1" })
|
|
9
9
|
|
|
@@ -24,6 +24,11 @@ console.log(config)
|
|
|
24
24
|
|
|
25
25
|
const utils = new TriangleUtils(config)
|
|
26
26
|
|
|
27
|
+
const raw_s3_id_prefix = config.s3_scout + "/raw_scout_documents/57523929653b604e/"
|
|
28
|
+
const raw_s3_ids = await utils.s3.query_prefix(raw_s3_id_prefix, { compile : true })
|
|
29
|
+
|
|
30
|
+
console.log(raw_s3_ids)
|
|
31
|
+
|
|
27
32
|
// const text = await utils.xai.grok_simple_query("grok-4.3", "Find the X username corresponding to the candidate of the committee \"Darializa for Congress\"", {
|
|
28
33
|
// print_usage : true,
|
|
29
34
|
// json_format : {
|
|
@@ -253,14 +258,14 @@ const utils = new TriangleUtils(config)
|
|
|
253
258
|
// const f = await utils.dynamodb.query_range("federal_election_donations:donor_address_state_id.federal_election_committee_id-receipt_date-federal_election_donation_id", { donor_address_state_id : "NH", federal_election_committee_id : "C00694323" }, { receipt_date : ["2021", "2023"] }, { compile : false })
|
|
254
259
|
|
|
255
260
|
// console.log(f)
|
|
256
|
-
console.log("YERP")
|
|
257
|
-
const response = await utils.bedrock.claude_converse(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
)
|
|
266
|
-
console.log(response)
|
|
261
|
+
// console.log("YERP")
|
|
262
|
+
// const response = await utils.bedrock.claude_converse(
|
|
263
|
+
// "anthropic.claude-opus-4-8",
|
|
264
|
+
// [
|
|
265
|
+
// { role : "user", text : "Hi" }
|
|
266
|
+
// ],
|
|
267
|
+
// {
|
|
268
|
+
// print_usage : true
|
|
269
|
+
// }
|
|
270
|
+
// )
|
|
271
|
+
// console.log(response)
|