@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.
@@ -1,8 +1,8 @@
1
1
  import '../polyfills.js';
2
- import { afterResolve, Resolvable, type resolveArgumentType } from '../injector/interfaces.js';
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
  }
@@ -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({ apiKey: this.#options.apiKey }) : undefined;
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.#bucket)) {
150
- const [file] = await this.#bucket.upload(path, { destination: id, contentType: mimeType });
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;
@@ -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: string;
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.92.36",
3
+ "version": "0.92.38",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"