@tstdl/base 0.92.36 → 0.92.38
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/ai/ai-file.service.d.ts +3 -3
- package/ai/ai-file.service.js +28 -22
- package/ai/ai.service.d.ts +2 -1
- package/ai/ai.service.js +3 -2
- package/package.json +1 -1
package/ai/ai-file.service.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import '../polyfills.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Resolvable, type resolveArgumentType } from '../injector/interfaces.js';
|
|
3
3
|
import { AiServiceOptions } from './ai.service.js';
|
|
4
4
|
import { FileContentPart, FileInput } from './types.js';
|
|
5
|
-
export type AiFileServiceOptions = Pick<AiServiceOptions, 'apiKey' | 'vertex'>;
|
|
5
|
+
export type AiFileServiceOptions = Pick<AiServiceOptions, 'apiKey' | 'keyFile' | 'vertex'>;
|
|
6
6
|
export type AiFileServiceArgument = AiFileServiceOptions;
|
|
7
7
|
type File = {
|
|
8
8
|
id: string;
|
|
@@ -13,7 +13,6 @@ type File = {
|
|
|
13
13
|
export declare class AiFileService implements Resolvable<AiFileServiceArgument> {
|
|
14
14
|
#private;
|
|
15
15
|
readonly [resolveArgumentType]: AiFileServiceArgument;
|
|
16
|
-
[afterResolve](): Promise<void>;
|
|
17
16
|
processFile(fileInput: FileInput): Promise<FileContentPart>;
|
|
18
17
|
processFiles(fileInputs: FileInput[]): Promise<FileContentPart[]>;
|
|
19
18
|
getFileById(id: string): File | undefined;
|
|
@@ -21,6 +20,7 @@ export declare class AiFileService implements Resolvable<AiFileServiceArgument>
|
|
|
21
20
|
private getFile;
|
|
22
21
|
private getFiles;
|
|
23
22
|
private uploadFile;
|
|
23
|
+
private getBucket;
|
|
24
24
|
private waitForFileActive;
|
|
25
25
|
private waitForFilesActive;
|
|
26
26
|
}
|
package/ai/ai-file.service.js
CHANGED
|
@@ -66,7 +66,6 @@ import { AsyncEnumerable } from '../enumerable/async-enumerable.js';
|
|
|
66
66
|
import { DetailsError } from '../errors/details.error.js';
|
|
67
67
|
import { Singleton } from '../injector/decorators.js';
|
|
68
68
|
import { inject, injectArgument } from '../injector/inject.js';
|
|
69
|
-
import { afterResolve } from '../injector/interfaces.js';
|
|
70
69
|
import { Logger } from '../logger/logger.js';
|
|
71
70
|
import { createArray } from '../utils/array/array.js';
|
|
72
71
|
import { formatBytes } from '../utils/format.js';
|
|
@@ -76,29 +75,12 @@ import { assertDefinedPass, isBlob, isDefined, isUndefined } from '../utils/type
|
|
|
76
75
|
import { millisecondsPerSecond } from '../utils/units.js';
|
|
77
76
|
let AiFileService = class AiFileService {
|
|
78
77
|
#options = injectArgument(this);
|
|
79
|
-
#fileManager = isUndefined(this.#options.vertex) ? new GoogleAIFileManager(this.#options.apiKey) : undefined;
|
|
80
|
-
#storage = isDefined(this.#options.vertex) ? new Storage({
|
|
78
|
+
#fileManager = isUndefined(this.#options.vertex) ? new GoogleAIFileManager(assertDefinedPass(this.#options.apiKey, 'Api key not defined')) : undefined;
|
|
79
|
+
#storage = isDefined(this.#options.vertex) ? new Storage({ keyFile: assertDefinedPass(this.#options.keyFile, 'Key file not defined'), projectId: this.#options.vertex.project }) : undefined;
|
|
81
80
|
#fileMap = new Map();
|
|
82
81
|
#fileUriMap = new Map();
|
|
83
82
|
#logger = inject(Logger, 'AiFileService');
|
|
84
83
|
#bucket;
|
|
85
|
-
async [afterResolve]() {
|
|
86
|
-
if (isDefined(this.#options.vertex)) {
|
|
87
|
-
const bucketName = assertDefinedPass(this.#options.vertex.bucket, 'Bucket not specified');
|
|
88
|
-
const [exists] = await this.#storage.bucket(bucketName).exists();
|
|
89
|
-
if (!exists) {
|
|
90
|
-
const [bucket] = await this.#storage.createBucket(bucketName, {
|
|
91
|
-
lifecycle: {
|
|
92
|
-
rule: [{
|
|
93
|
-
action: { type: 'Delete' },
|
|
94
|
-
condition: { age: 1 }
|
|
95
|
-
}]
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
this.#bucket = bucket;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
84
|
async processFile(fileInput) {
|
|
103
85
|
const file = await this.getFile(fileInput);
|
|
104
86
|
this.#fileMap.set(file.id, file);
|
|
@@ -146,8 +128,9 @@ let AiFileService = class AiFileService {
|
|
|
146
128
|
}
|
|
147
129
|
const fileSize = isBlob(fileInput) ? fileInput.size : (await stat(path)).size;
|
|
148
130
|
this.#logger.verbose(`Uploading file "${id}" (${formatBytes(fileSize)})...`);
|
|
149
|
-
if (isDefined(this.#
|
|
150
|
-
const
|
|
131
|
+
if (isDefined(this.#storage)) {
|
|
132
|
+
const bucket = await this.getBucket();
|
|
133
|
+
const [file] = await bucket.upload(path, { destination: id, contentType: mimeType });
|
|
151
134
|
return {
|
|
152
135
|
id,
|
|
153
136
|
name: id,
|
|
@@ -173,6 +156,29 @@ let AiFileService = class AiFileService {
|
|
|
173
156
|
await result_1;
|
|
174
157
|
}
|
|
175
158
|
}
|
|
159
|
+
async getBucket() {
|
|
160
|
+
if (isUndefined(this.#options.vertex)) {
|
|
161
|
+
throw new Error('Not using Vertex');
|
|
162
|
+
}
|
|
163
|
+
if (isDefined(this.#bucket)) {
|
|
164
|
+
return this.#bucket;
|
|
165
|
+
}
|
|
166
|
+
const bucketName = assertDefinedPass(this.#options.vertex.bucket, 'Bucket not specified');
|
|
167
|
+
const [exists] = await this.#storage.bucket(bucketName).exists();
|
|
168
|
+
if (!exists) {
|
|
169
|
+
const [bucket] = await this.#storage.createBucket(bucketName, {
|
|
170
|
+
location: this.#options.vertex.location,
|
|
171
|
+
lifecycle: {
|
|
172
|
+
rule: [{
|
|
173
|
+
action: { type: 'Delete' },
|
|
174
|
+
condition: { age: 1 }
|
|
175
|
+
}]
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
this.#bucket = bucket;
|
|
179
|
+
}
|
|
180
|
+
return this.#bucket;
|
|
181
|
+
}
|
|
176
182
|
async waitForFileActive(file) {
|
|
177
183
|
if (isUndefined(this.#fileManager)) {
|
|
178
184
|
return;
|
package/ai/ai.service.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ export type SpecializedGenerationResultGenerator<T> = AsyncGenerator<T> & {
|
|
|
11
11
|
raw: Promise<GenerationResult>;
|
|
12
12
|
};
|
|
13
13
|
export declare class AiServiceOptions {
|
|
14
|
-
apiKey
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
keyFile?: string;
|
|
15
16
|
vertex?: {
|
|
16
17
|
project: string;
|
|
17
18
|
location: string;
|
package/ai/ai.service.js
CHANGED
|
@@ -24,6 +24,7 @@ import { AiSession } from './ai-session.js';
|
|
|
24
24
|
import { isSchemaFunctionDeclarationWithHandler } from './types.js';
|
|
25
25
|
export class AiServiceOptions {
|
|
26
26
|
apiKey;
|
|
27
|
+
keyFile;
|
|
27
28
|
vertex;
|
|
28
29
|
defaultModel;
|
|
29
30
|
}
|
|
@@ -37,8 +38,8 @@ let AiService = class AiService {
|
|
|
37
38
|
#options = injectArgument(this, { optional: true }) ?? inject(AiServiceOptions);
|
|
38
39
|
#fileService = inject(AiFileService, this.#options);
|
|
39
40
|
#genAI = (isDefined(this.#options.vertex)
|
|
40
|
-
? new VertexAI({ project: this.#options.vertex.project, location: this.#options.vertex.location, googleAuthOptions: { apiKey: this.#options.apiKey } })
|
|
41
|
-
: new GoogleGenerativeAI(this.#options.apiKey));
|
|
41
|
+
? new VertexAI({ project: this.#options.vertex.project, location: this.#options.vertex.location, googleAuthOptions: { apiKey: this.#options.apiKey, keyFile: this.#options.keyFile } })
|
|
42
|
+
: new GoogleGenerativeAI(assertDefinedPass(this.#options.apiKey, 'Api key not defined')));
|
|
42
43
|
defaultModel = this.#options.defaultModel ?? 'gemini-2.0-flash-exp';
|
|
43
44
|
createSession() {
|
|
44
45
|
return new AiSession(this);
|