@tstdl/base 0.93.123 → 0.93.126
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/genkit/tests/multi-region.test.js +6 -6
- package/ai/index.d.ts +2 -6
- package/ai/index.js +2 -6
- package/ai/parser/index.d.ts +1 -0
- package/ai/parser/index.js +1 -0
- package/ai/parser/parser.d.ts +12 -0
- package/ai/parser/parser.js +28 -0
- package/ai/prompts/build.d.ts +21 -0
- package/ai/prompts/build.js +25 -0
- package/ai/prompts/index.d.ts +2 -0
- package/ai/prompts/index.js +2 -0
- package/ai/prompts/instructions-formatter.d.ts +9 -22
- package/ai/prompts/instructions-formatter.js +20 -7
- package/ai/prompts/instructions.js +1 -1
- package/ai/prompts/steering.d.ts +27 -0
- package/ai/prompts/steering.js +54 -0
- package/ai/tests/instructions-formatter.test.js +115 -0
- package/ai/tests/steering.test.js +37 -0
- package/application/application.d.ts +2 -1
- package/application/application.js +3 -0
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -5
- package/authentication/tests/authentication-ancillary.service.test.js +1 -1
- package/authentication/tests/authentication.api-controller.test.js +3 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
- package/authentication/tests/authentication.client-service.test.js +1 -1
- package/authentication/tests/authentication.service.test.js +1 -1
- package/authentication/tests/subject.service.test.js +1 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +1 -1
- package/document-management/api/document-management.api.d.ts +16 -16
- package/document-management/api/document-management.api.js +12 -12
- package/document-management/models/ai-configuration.d.ts +59 -0
- package/document-management/models/ai-configuration.js +1 -0
- package/document-management/models/document-assignment-scope.model.js +2 -4
- package/document-management/models/document-assignment-task.model.js +2 -4
- package/document-management/models/document-collection-assignment.model.js +2 -4
- package/document-management/models/document-collection.model.js +2 -3
- package/document-management/models/document-content.model.d.ts +6 -0
- package/document-management/models/document-content.model.js +32 -0
- package/document-management/models/document-property-value.model.js +1 -2
- package/document-management/models/document-request-collection-assignment.model.js +2 -4
- package/document-management/models/document-request.model.js +2 -4
- package/document-management/models/document-tag-assignment.model.js +2 -3
- package/document-management/models/document-validation-execution-related-document.model.js +2 -4
- package/document-management/models/document-validation-execution.model.js +2 -5
- package/document-management/models/document-workflow.model.d.ts +2 -1
- package/document-management/models/document-workflow.model.js +4 -5
- package/document-management/models/document.model.js +2 -3
- package/document-management/models/index.d.ts +2 -0
- package/document-management/models/index.js +2 -0
- package/document-management/server/api/document-management.api.d.ts +7 -7
- package/document-management/server/api/document-management.api.js +9 -9
- package/document-management/server/configure.d.ts +4 -1
- package/document-management/server/configure.js +9 -4
- package/document-management/server/drizzle/{0000_silly_chimera.sql → 0000_curious_nighthawk.sql} +8 -28
- package/document-management/server/drizzle/meta/0000_snapshot.json +14 -286
- package/document-management/server/drizzle/meta/_journal.json +2 -2
- package/document-management/server/module.d.ts +2 -0
- package/document-management/server/module.js +1 -0
- package/document-management/server/schemas.d.ts +2 -1
- package/document-management/server/services/document-file.service.d.ts +6 -6
- package/document-management/server/services/document-file.service.js +7 -81
- package/document-management/server/services/document-management-ai-provider.service.d.ts +66 -0
- package/document-management/server/services/document-management-ai-provider.service.js +2 -0
- package/document-management/server/services/document-management-ai.service.d.ts +44 -7
- package/document-management/server/services/document-management-ai.service.js +332 -329
- package/document-management/server/services/document-validation.service.d.ts +1 -1
- package/document-management/server/services/document-workflow.service.d.ts +4 -3
- package/document-management/server/services/document-workflow.service.js +26 -9
- package/document-management/server/services/document.service.d.ts +7 -3
- package/document-management/server/services/document.service.js +13 -4
- package/document-management/server/services/index.d.ts +1 -0
- package/document-management/server/services/index.js +1 -0
- package/document-management/server/validators/ai-validation-executor.d.ts +419 -12
- package/document-management/server/validators/ai-validation-executor.js +51 -46
- package/document-management/server/validators/single-document-validation-executor.d.ts +1 -3
- package/document-management/server/validators/single-document-validation-executor.js +2 -4
- package/document-management/service-models/document.service-model.d.ts +3 -3
- package/document-management/service-models/document.service-model.js +1 -1
- package/document-management/tests/ai-config-hierarchy.test.d.ts +1 -0
- package/document-management/tests/ai-config-hierarchy.test.js +64 -0
- package/document-management/tests/ai-config-integration.test.d.ts +1 -0
- package/document-management/tests/ai-config-integration.test.js +125 -0
- package/document-management/tests/ai-config-merge.test.d.ts +1 -0
- package/document-management/tests/ai-config-merge.test.js +38 -0
- package/document-management/tests/document-management-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-management-ai-overrides.test.js +64 -0
- package/document-management/tests/document-management-core.test.js +6 -6
- package/document-management/tests/document-management.api.test.js +5 -5
- package/document-management/tests/document-statistics.service.test.js +10 -6
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-validation-ai-overrides.test.js +85 -0
- package/document-management/tests/document.service.test.js +15 -11
- package/document-management/tests/enum-helpers.test.js +5 -5
- package/examples/document-management/ai-provider.d.ts +20 -0
- package/examples/document-management/ai-provider.js +74 -0
- package/examples/document-management/main.js +9 -6
- package/examples/injector/graph-example.d.ts +1 -0
- package/examples/injector/graph-example.js +340 -0
- package/injector/decorators.d.ts +4 -4
- package/injector/decorators.js +5 -6
- package/injector/forward-ref.d.ts +15 -0
- package/injector/forward-ref.js +20 -0
- package/injector/graph.d.ts +113 -0
- package/injector/graph.js +631 -0
- package/injector/index.d.ts +2 -0
- package/injector/index.js +2 -0
- package/injector/inject.d.ts +15 -15
- package/injector/injector.d.ts +101 -13
- package/injector/injector.js +103 -59
- package/injector/resolve-chain.d.ts +20 -6
- package/injector/resolve-chain.js +39 -14
- package/injector/tests/advanced.test.d.ts +1 -0
- package/injector/tests/advanced.test.js +116 -0
- package/injector/tests/async-init.test.d.ts +1 -0
- package/injector/tests/async-init.test.js +77 -0
- package/injector/tests/basic.test.d.ts +1 -0
- package/injector/tests/basic.test.js +114 -0
- package/injector/tests/hierarchical.test.d.ts +1 -0
- package/injector/tests/hierarchical.test.js +59 -0
- package/injector/tests/lifecycles.test.d.ts +1 -0
- package/injector/tests/lifecycles.test.js +109 -0
- package/injector/token.d.ts +2 -1
- package/injector/token.js +4 -1
- package/injector/type-info.d.ts +1 -5
- package/injector/types.d.ts +4 -10
- package/logger/tests/pretty-print.test.d.ts +1 -0
- package/logger/{formatters → tests}/pretty-print.test.js +1 -1
- package/logger/transports/console.d.ts +3 -2
- package/logger/transports/console.js +4 -3
- package/notification/api/notification.api.d.ts +26 -6
- package/notification/api/notification.api.js +15 -4
- package/notification/client/notification-client.d.ts +6 -0
- package/notification/client/notification-client.js +13 -3
- package/notification/models/in-app-notification.model.d.ts +9 -3
- package/notification/models/in-app-notification.model.js +32 -11
- package/notification/models/notification-log.model.js +2 -3
- package/notification/server/api/notification.api-controller.d.ts +1 -0
- package/notification/server/api/notification.api-controller.js +7 -1
- package/notification/server/drizzle/{0000_oval_rage.sql → 0000_wise_pyro.sql} +22 -4
- package/notification/server/drizzle/meta/0000_snapshot.json +249 -37
- package/notification/server/drizzle/meta/_journal.json +2 -2
- package/notification/server/module.d.ts +5 -0
- package/notification/server/module.js +6 -1
- package/notification/server/providers/in-app-channel-provider.js +1 -0
- package/notification/server/schemas.d.ts +3 -2
- package/notification/server/schemas.js +3 -2
- package/notification/server/services/notification.service.d.ts +11 -6
- package/notification/server/services/notification.service.js +138 -42
- package/notification/tests/notification-api.test.js +16 -6
- package/notification/tests/notification-client.test.d.ts +1 -0
- package/notification/tests/{unit/notification-client.test.js → notification-client.test.js} +5 -5
- package/notification/tests/notification-flow.test.js +45 -7
- package/notification/tests/notification-sse.service.test.js +1 -1
- package/notification/tests/notification-type.service.test.js +1 -1
- package/object-storage/s3/s3.object-storage.js +3 -0
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +1 -1
- package/orm/server/drizzle/schema-converter.js +5 -3
- package/orm/tests/repository-attributes.test.js +10 -17
- package/orm/tests/repository-cti-mapping.test.js +2 -2
- package/orm/tests/repository-cti-soft-delete.test.js +1 -1
- package/orm/tests/repository-cti.test.js +19 -33
- package/orm/tests/repository-extra-coverage.test.js +1 -1
- package/orm/tests/repository-search.test.js +5 -2
- package/orm/tests/schema-converter.test.js +1 -0
- package/orm/tests/transaction-safety.test.js +1 -1
- package/package.json +7 -9
- package/rate-limit/tests/postgres-rate-limiter.test.js +6 -16
- package/renderer/d2.d.ts +77 -0
- package/renderer/d2.js +68 -0
- package/renderer/graphviz.d.ts +47 -0
- package/renderer/graphviz.js +58 -0
- package/renderer/index.d.ts +4 -0
- package/renderer/index.js +4 -0
- package/renderer/typst.d.ts +57 -0
- package/renderer/typst.js +62 -0
- package/rpc/adapters/readable-stream.adapter.d.ts +3 -0
- package/rpc/adapters/readable-stream.adapter.js +5 -1
- package/rpc/rpc.js +28 -3
- package/rpc/tests/rpc.integration.test.js +3 -1
- package/schema/schemas/nullable.js +1 -1
- package/task-queue/task-queue.d.ts +2 -0
- package/task-queue/task-queue.js +6 -2
- package/task-queue/tests/complex.test.js +1 -1
- package/task-queue/tests/dependencies.test.js +3 -3
- package/task-queue/tests/extensive-dependencies.test.js +1 -1
- package/task-queue/tests/queue.test.js +1 -1
- package/task-queue/tests/worker.test.js +4 -7
- package/test5.js +52 -8
- package/{unit-test → testing}/integration-setup.d.ts +1 -0
- package/{unit-test → testing}/integration-setup.js +13 -0
- package/utils/base64.d.ts +7 -0
- package/utils/base64.js +10 -1
- package/utils/noop.d.ts +7 -1
- package/utils/noop.js +7 -1
- package/ai/ai-file.service.d.ts +0 -57
- package/ai/ai-file.service.js +0 -233
- package/ai/ai-session.d.ts +0 -38
- package/ai/ai-session.js +0 -50
- package/ai/ai.service.d.ts +0 -126
- package/ai/ai.service.js +0 -481
- package/ai/functions.d.ts +0 -9
- package/ai/functions.js +0 -38
- package/ai/module.d.ts +0 -26
- package/ai/module.js +0 -25
- package/ai/types.d.ts +0 -229
- package/ai/types.js +0 -33
- package/latex/index.d.ts +0 -1
- package/latex/index.js +0 -1
- package/typst/index.d.ts +0 -1
- package/typst/index.js +0 -1
- package/typst/render.d.ts +0 -23
- package/typst/render.js +0 -32
- /package/{logger/formatters/pretty-print.test.d.ts → ai/tests/instructions-formatter.test.d.ts} +0 -0
- /package/{notification/tests/unit/notification-client.test.d.ts → ai/tests/steering.test.d.ts} +0 -0
- /package/{latex/render.d.ts → renderer/latex.d.ts} +0 -0
- /package/{latex/render.js → renderer/latex.js} +0 -0
- /package/{unit-test → testing}/index.d.ts +0 -0
- /package/{unit-test → testing}/index.js +0 -0
package/ai/ai.service.js
DELETED
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var _a;
|
|
8
|
-
var AiService_1;
|
|
9
|
-
import { ApiError, FinishReason, FunctionCallingConfigMode as GoogleFunctionCallingMode, GoogleGenAI } from '@google/genai';
|
|
10
|
-
import { match } from 'ts-pattern';
|
|
11
|
-
import { CancellationSignal } from '../cancellation/index.js';
|
|
12
|
-
import { NotSupportedError } from '../errors/not-supported.error.js';
|
|
13
|
-
import { Singleton } from '../injector/decorators.js';
|
|
14
|
-
import { inject, injectArgument } from '../injector/inject.js';
|
|
15
|
-
import { Logger } from '../logger/logger.js';
|
|
16
|
-
import { DeferredPromise } from '../promise/deferred-promise.js';
|
|
17
|
-
import { LazyPromise } from '../promise/lazy-promise.js';
|
|
18
|
-
import { convertToOpenApiSchema } from '../schema/converters/open-api-converter.js';
|
|
19
|
-
import { Schema } from '../schema/index.js';
|
|
20
|
-
import { toArray } from '../utils/array/array.js';
|
|
21
|
-
import { mapAsync } from '../utils/async-iterable-helpers/map.js';
|
|
22
|
-
import { toArrayAsync } from '../utils/async-iterable-helpers/to-array.js';
|
|
23
|
-
import { backoffGenerator } from '../utils/backoff.js';
|
|
24
|
-
import { lazyObject } from '../utils/object/lazy-property.js';
|
|
25
|
-
import { hasOwnProperty, objectEntries } from '../utils/object/object.js';
|
|
26
|
-
import { assertDefinedPass, isDefined, isError, isInstanceOf, isNotNull, isNull, isUndefined } from '../utils/type-guards.js';
|
|
27
|
-
import { resolveValueOrAsyncProvider } from '../utils/value-or-provider.js';
|
|
28
|
-
import { AiFileService } from './ai-file.service.js';
|
|
29
|
-
import { AiSession } from './ai-session.js';
|
|
30
|
-
import { AiModuleOptions } from './module.js';
|
|
31
|
-
import { isSchemaFunctionDeclarationWithHandler } from './types.js';
|
|
32
|
-
const functionCallingModeMap = {
|
|
33
|
-
auto: GoogleFunctionCallingMode.AUTO,
|
|
34
|
-
force: GoogleFunctionCallingMode.ANY,
|
|
35
|
-
none: GoogleFunctionCallingMode.NONE,
|
|
36
|
-
};
|
|
37
|
-
let generationCounter = 0;
|
|
38
|
-
/**
|
|
39
|
-
* A service for interacting with Google's Generative AI models (Gemini).
|
|
40
|
-
*
|
|
41
|
-
* This service provides methods for content generation, function calling, and file processing,
|
|
42
|
-
* supporting both standard Google AI and Vertex AI endpoints.
|
|
43
|
-
*/
|
|
44
|
-
let AiService = AiService_1 = class AiService {
|
|
45
|
-
#options = injectArgument(this, { optional: true }) ?? inject(AiModuleOptions);
|
|
46
|
-
#fileService = inject(AiFileService, this.#options);
|
|
47
|
-
#logger = inject(Logger, AiService_1.name);
|
|
48
|
-
#cancellationSignal = inject(CancellationSignal);
|
|
49
|
-
#genAI = new GoogleGenAI({
|
|
50
|
-
vertexai: isDefined(this.#options.vertex?.project),
|
|
51
|
-
project: this.#options.vertex?.project,
|
|
52
|
-
location: this.#options.vertex?.location,
|
|
53
|
-
googleAuthOptions: isDefined(this.#options.vertex?.project) ? { apiKey: this.#options.apiKey, keyFile: this.#options.keyFile } : undefined,
|
|
54
|
-
apiKey: isUndefined(this.#options.vertex?.project) ? assertDefinedPass(this.#options.apiKey, 'Api key not defined') : undefined,
|
|
55
|
-
});
|
|
56
|
-
#maxOutputTokensCache = new Map();
|
|
57
|
-
#backoffOptions = {
|
|
58
|
-
cancellationSignal: this.#cancellationSignal,
|
|
59
|
-
strategy: 'exponential',
|
|
60
|
-
initialDelay: 5000,
|
|
61
|
-
increase: 1.5,
|
|
62
|
-
jitter: 0.2,
|
|
63
|
-
maximumDelay: 30000,
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* The default AI model to use for requests if not specified otherwise.
|
|
67
|
-
*/
|
|
68
|
-
defaultModel = this.#options.defaultModel ?? 'gemini-2.5-flash-lite';
|
|
69
|
-
/**
|
|
70
|
-
* Creates a new {@link AiSession} for managing conversational history.
|
|
71
|
-
*/
|
|
72
|
-
createSession() {
|
|
73
|
-
return new AiSession(this);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Processes a single file for use in AI requests by uploading it and making it available to the model.
|
|
77
|
-
* @param fileInput The file to process.
|
|
78
|
-
* @returns A promise that resolves to a {@link FileContentPart} which can be included in a generation request.
|
|
79
|
-
*/
|
|
80
|
-
async processFile(fileInput) {
|
|
81
|
-
return await this.#fileService.processFile(fileInput);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Processes multiple files in parallel for use in AI requests.
|
|
85
|
-
* @param fileInputs The files to process.
|
|
86
|
-
* @returns A promise that resolves to an array of {@link FileContentPart}s which can be included in generation requests.
|
|
87
|
-
*/
|
|
88
|
-
async processFiles(fileInputs) {
|
|
89
|
-
return await this.#fileService.processFiles(fileInputs);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Creates a file content part from a previously processed file ID.
|
|
93
|
-
* This does not re-upload the file.
|
|
94
|
-
* @param id The ID of the file, obtained from {@link AiFileService.processFile} or {@link AiFileService.processFiles}.
|
|
95
|
-
* @returns A {@link FileContentPart} for use in a generation request.
|
|
96
|
-
*/
|
|
97
|
-
getFileById(id) {
|
|
98
|
-
return { file: id };
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* A high-level method to prompt the model to call one or more functions.
|
|
102
|
-
* This method sends the request and parses the model's response to identify function calls.
|
|
103
|
-
* If the function declaration includes a handler, it will be executed automatically.
|
|
104
|
-
* @param options The options for the function call request.
|
|
105
|
-
* @returns A promise that resolves to a {@link SpecializedGenerationResult} containing the function call results.
|
|
106
|
-
*/
|
|
107
|
-
async callFunctions(options) {
|
|
108
|
-
const generation = await this.generate({
|
|
109
|
-
model: options.model,
|
|
110
|
-
generationOptions: {
|
|
111
|
-
temperature: 0.5,
|
|
112
|
-
...options,
|
|
113
|
-
},
|
|
114
|
-
systemInstruction: options.systemInstruction,
|
|
115
|
-
functions: options.functions,
|
|
116
|
-
functionCallingMode: options.functionCallingMode ?? 'force',
|
|
117
|
-
contents: options.contents,
|
|
118
|
-
});
|
|
119
|
-
const result = [];
|
|
120
|
-
for (const call of generation.functionCalls) {
|
|
121
|
-
const fn = assertDefinedPass(options.functions[call.name], 'Function in response not declared.');
|
|
122
|
-
const parametersSchema = await resolveValueOrAsyncProvider(fn.parameters);
|
|
123
|
-
const parameters = isDefined(parametersSchema) ? parametersSchema.parse(call.parameters) : call.parameters;
|
|
124
|
-
const handlerResult = isSchemaFunctionDeclarationWithHandler(fn) ? await fn.handler(parameters) : undefined;
|
|
125
|
-
result.push({
|
|
126
|
-
functionName: call.name,
|
|
127
|
-
parameters: parameters,
|
|
128
|
-
handlerResult: handlerResult,
|
|
129
|
-
getFunctionResultContentPart: () => ({ functionResult: { name: call.name, value: handlerResult } }),
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
result,
|
|
134
|
-
raw: generation,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* A streaming version of `callFunctions`.
|
|
139
|
-
* Yields function call results as they are received from the model.
|
|
140
|
-
* If function declarations include handlers, they are executed as soon as a complete function call is parsed.
|
|
141
|
-
* @param options The options for the function call request.
|
|
142
|
-
* @returns A {@link SpecializedGenerationResultGenerator} that yields function call results.
|
|
143
|
-
*/
|
|
144
|
-
callFunctionsStream(options) {
|
|
145
|
-
const itemsPromise = new DeferredPromise();
|
|
146
|
-
const generator = this._callFunctionsStream(options, itemsPromise);
|
|
147
|
-
generator.raw = new LazyPromise(async () => {
|
|
148
|
-
const items = await itemsPromise;
|
|
149
|
-
return mergeGenerationStreamItems(items);
|
|
150
|
-
});
|
|
151
|
-
return generator;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Generates content from the model based on a request.
|
|
155
|
-
* This method waits for the full response from the model. For streaming, use {@link generateStream}.
|
|
156
|
-
* @param request The generation request.
|
|
157
|
-
* @returns A promise that resolves to the complete {@link GenerationResult}.
|
|
158
|
-
*/
|
|
159
|
-
async generate(request) {
|
|
160
|
-
const items = await toArrayAsync(this.generateStream(request));
|
|
161
|
-
return mergeGenerationStreamItems(items, request.generationSchema);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Generates content as a stream.
|
|
165
|
-
* Yields partial generation results as they are received from the model.
|
|
166
|
-
* @param request The generation request.
|
|
167
|
-
* @returns An `AsyncGenerator` that yields {@link GenerationResult} chunks.
|
|
168
|
-
*/
|
|
169
|
-
async *generateStream(request) {
|
|
170
|
-
const generationNumber = ++generationCounter;
|
|
171
|
-
const googleFunctionDeclarations = isDefined(request.functions) ? await this.convertFunctions(request.functions) : undefined;
|
|
172
|
-
const config = {
|
|
173
|
-
systemInstruction: request.systemInstruction,
|
|
174
|
-
temperature: request.generationOptions?.temperature,
|
|
175
|
-
topP: request.generationOptions?.topP,
|
|
176
|
-
topK: request.generationOptions?.topK,
|
|
177
|
-
presencePenalty: request.generationOptions?.presencePenalty,
|
|
178
|
-
frequencyPenalty: request.generationOptions?.frequencyPenalty,
|
|
179
|
-
responseMimeType: isDefined(request.generationSchema) ? 'application/json' : undefined,
|
|
180
|
-
responseSchema: isDefined(request.generationSchema) ? convertToOpenApiSchema(request.generationSchema) : undefined,
|
|
181
|
-
safetySettings: [],
|
|
182
|
-
tools: (isDefined(googleFunctionDeclarations) && (googleFunctionDeclarations.length > 0)) ? [{ functionDeclarations: googleFunctionDeclarations }] : undefined,
|
|
183
|
-
toolConfig: isDefined(request.functionCallingMode)
|
|
184
|
-
? { functionCallingConfig: { mode: functionCallingModeMap[request.functionCallingMode] } }
|
|
185
|
-
: undefined,
|
|
186
|
-
thinkingConfig: {
|
|
187
|
-
thinkingBudget: request.generationOptions?.thinkingBudget,
|
|
188
|
-
},
|
|
189
|
-
};
|
|
190
|
-
const model = this.mapModel(request.model);
|
|
191
|
-
const maxModelTokens = await this.getModelOutputTokenLimit(model);
|
|
192
|
-
const maxTotalOutputTokens = request.generationOptions?.maxOutputTokens ?? maxModelTokens ?? 65535;
|
|
193
|
-
const inputContent = this.convertContents(request.contents);
|
|
194
|
-
let iterations = 0;
|
|
195
|
-
let totalPromptTokens = 0;
|
|
196
|
-
let totalCachedTokens = 0;
|
|
197
|
-
let totalThoughtsTokens = 0;
|
|
198
|
-
let totalOutputTokens = 0;
|
|
199
|
-
let totalToolsTokens = 0;
|
|
200
|
-
while (totalOutputTokens < maxTotalOutputTokens) {
|
|
201
|
-
let generation;
|
|
202
|
-
let triesLeft = 10;
|
|
203
|
-
for await (const backoff of backoffGenerator(this.#backoffOptions)) {
|
|
204
|
-
try {
|
|
205
|
-
this.#logger.verbose(`[C:${generationNumber}] [I:${iterations + 1}] Generating...`);
|
|
206
|
-
generation = await this.#genAI.models.generateContentStream({
|
|
207
|
-
model,
|
|
208
|
-
config: {
|
|
209
|
-
...config,
|
|
210
|
-
maxOutputTokens: Math.min(1000000, maxTotalOutputTokens - totalOutputTokens),
|
|
211
|
-
},
|
|
212
|
-
contents: inputContent,
|
|
213
|
-
});
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
triesLeft -= 1;
|
|
218
|
-
if ((triesLeft > 0) && isInstanceOf(error, ApiError) && ((error.status == 429) || (error.status == 503))) {
|
|
219
|
-
this.#logger.verbose(`Retrying after transient error: ${error.message}`);
|
|
220
|
-
backoff();
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
throw error; // Non-retryable error
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
iterations++;
|
|
227
|
-
let lastUsageMetadata;
|
|
228
|
-
let candidate;
|
|
229
|
-
for await (const generationResponse of generation) {
|
|
230
|
-
candidate = generationResponse.candidates?.at(0);
|
|
231
|
-
const rawContent = candidate?.content;
|
|
232
|
-
if (isUndefined(candidate)) {
|
|
233
|
-
throw new Error('No candidate returned.');
|
|
234
|
-
}
|
|
235
|
-
if (isUndefined(rawContent)) {
|
|
236
|
-
throw new Error('No content returned.');
|
|
237
|
-
}
|
|
238
|
-
inputContent.push(rawContent);
|
|
239
|
-
const { cachedContentTokenCount = 0, candidatesTokenCount = 0, promptTokenCount = 0, thoughtsTokenCount = 0, toolUsePromptTokenCount = 0, totalTokenCount = 0, } = generationResponse.usageMetadata ?? {};
|
|
240
|
-
lastUsageMetadata = generationResponse.usageMetadata;
|
|
241
|
-
const content = this.convertGoogleContent(rawContent);
|
|
242
|
-
let text;
|
|
243
|
-
let functionCallParts;
|
|
244
|
-
const result = {
|
|
245
|
-
content,
|
|
246
|
-
get text() {
|
|
247
|
-
if (isUndefined(text)) {
|
|
248
|
-
const textParts = content.parts.filter((part) => hasOwnProperty(part, 'text')).map((part) => part.text);
|
|
249
|
-
text = (textParts.length > 0) ? textParts.join('') : null;
|
|
250
|
-
}
|
|
251
|
-
return text;
|
|
252
|
-
},
|
|
253
|
-
get json() {
|
|
254
|
-
throw new NotSupportedError('JSON not supported in streamed items. Use mergeGenerationStreamItems to combine all streamed items.');
|
|
255
|
-
},
|
|
256
|
-
get functionCalls() {
|
|
257
|
-
if (isUndefined(functionCallParts)) {
|
|
258
|
-
functionCallParts = content.parts.filter((part) => hasOwnProperty(part, 'functionCall')).map((part) => part.functionCall);
|
|
259
|
-
}
|
|
260
|
-
return functionCallParts;
|
|
261
|
-
},
|
|
262
|
-
finishReason: candidate.finishReason == FinishReason.MAX_TOKENS
|
|
263
|
-
? 'maxTokens'
|
|
264
|
-
: candidate.finishReason == FinishReason.STOP
|
|
265
|
-
? 'stop'
|
|
266
|
-
: 'unknown',
|
|
267
|
-
usage: {
|
|
268
|
-
iterations,
|
|
269
|
-
cached: totalCachedTokens + cachedContentTokenCount,
|
|
270
|
-
prompt: totalPromptTokens + promptTokenCount,
|
|
271
|
-
thoughts: totalThoughtsTokens + thoughtsTokenCount,
|
|
272
|
-
output: totalOutputTokens + candidatesTokenCount,
|
|
273
|
-
tools: totalToolsTokens + toolUsePromptTokenCount,
|
|
274
|
-
total: totalTokenCount,
|
|
275
|
-
},
|
|
276
|
-
};
|
|
277
|
-
yield result;
|
|
278
|
-
}
|
|
279
|
-
totalCachedTokens += lastUsageMetadata?.cachedContentTokenCount ?? 0;
|
|
280
|
-
totalPromptTokens += lastUsageMetadata?.promptTokenCount ?? 0;
|
|
281
|
-
totalThoughtsTokens += lastUsageMetadata?.thoughtsTokenCount ?? 0;
|
|
282
|
-
totalOutputTokens += lastUsageMetadata?.responseTokenCount ?? 0;
|
|
283
|
-
totalToolsTokens += lastUsageMetadata?.toolUsePromptTokenCount ?? 0;
|
|
284
|
-
if (candidate?.finishReason != FinishReason.MAX_TOKENS) {
|
|
285
|
-
break;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
async *_callFunctionsStream(options, itemsPromise) {
|
|
290
|
-
const generationStream = this.generateStream({
|
|
291
|
-
model: options.model,
|
|
292
|
-
generationOptions: {
|
|
293
|
-
temperature: 0.5,
|
|
294
|
-
...options,
|
|
295
|
-
},
|
|
296
|
-
systemInstruction: options.systemInstruction,
|
|
297
|
-
functions: options.functions,
|
|
298
|
-
functionCallingMode: options.functionCallingMode ?? 'force',
|
|
299
|
-
contents: options.contents,
|
|
300
|
-
});
|
|
301
|
-
const items = [];
|
|
302
|
-
for await (const generation of generationStream) {
|
|
303
|
-
items.push(generation);
|
|
304
|
-
for (const call of generation.functionCalls) {
|
|
305
|
-
const fn = assertDefinedPass(options.functions[call.name], 'Function in response not declared.');
|
|
306
|
-
const parametersSchema = await resolveValueOrAsyncProvider(fn.parameters);
|
|
307
|
-
const parameters = isDefined(parametersSchema) ? parametersSchema.parse(call.parameters, { coerce: true }) : call.parameters;
|
|
308
|
-
const handlerResult = isSchemaFunctionDeclarationWithHandler(fn) ? await fn.handler(parameters) : undefined;
|
|
309
|
-
yield {
|
|
310
|
-
functionName: call.name,
|
|
311
|
-
parameters: parameters,
|
|
312
|
-
handlerResult: handlerResult,
|
|
313
|
-
getFunctionResultContentPart: () => ({ functionResult: { name: call.name, value: handlerResult } }),
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
itemsPromise.resolve(items);
|
|
318
|
-
}
|
|
319
|
-
async getModelOutputTokenLimit(model) {
|
|
320
|
-
const existingValue = this.#maxOutputTokensCache.get(model);
|
|
321
|
-
if (isDefined(existingValue)) {
|
|
322
|
-
return await existingValue;
|
|
323
|
-
}
|
|
324
|
-
const promise = this._getModelOutputTokenLimit(model);
|
|
325
|
-
this.#maxOutputTokensCache.set(model, promise);
|
|
326
|
-
promise
|
|
327
|
-
.then((limit) => this.#maxOutputTokensCache.set(model, limit))
|
|
328
|
-
.catch(() => this.#maxOutputTokensCache.delete(model));
|
|
329
|
-
return await promise;
|
|
330
|
-
}
|
|
331
|
-
async _getModelOutputTokenLimit(model) {
|
|
332
|
-
let modelInfo;
|
|
333
|
-
let triesLeft = 10;
|
|
334
|
-
for await (const backoff of backoffGenerator(this.#backoffOptions)) {
|
|
335
|
-
try {
|
|
336
|
-
modelInfo = await this.#genAI.models.get({ model });
|
|
337
|
-
break;
|
|
338
|
-
}
|
|
339
|
-
catch (error) {
|
|
340
|
-
triesLeft -= 1;
|
|
341
|
-
if ((triesLeft > 0) && isError(error) && (error.message.includes('429 Too Many Requests') || error.message.includes('503 Service Unavailable'))) {
|
|
342
|
-
this.#logger.verbose(`Could not get model info for ${model} due to a transient error (${error.message}). Retrying...`);
|
|
343
|
-
backoff();
|
|
344
|
-
continue;
|
|
345
|
-
}
|
|
346
|
-
throw error;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
if (isUndefined(modelInfo.outputTokenLimit)) {
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
|
-
return modelInfo.outputTokenLimit;
|
|
353
|
-
}
|
|
354
|
-
convertContents(contents) {
|
|
355
|
-
return toArray(contents).map((content) => this.convertContent(content));
|
|
356
|
-
}
|
|
357
|
-
convertContent(content) {
|
|
358
|
-
return {
|
|
359
|
-
role: content.role,
|
|
360
|
-
parts: content.parts.map((part) => {
|
|
361
|
-
if (hasOwnProperty(part, 'text')) {
|
|
362
|
-
return { text: part.text };
|
|
363
|
-
}
|
|
364
|
-
if (hasOwnProperty(part, 'file')) {
|
|
365
|
-
const file = assertDefinedPass(this.#fileService.getFileById(part.file), `File ${part.file} not found.`);
|
|
366
|
-
return { fileData: { fileUri: file.uri, mimeType: file.mimeType } };
|
|
367
|
-
}
|
|
368
|
-
if (hasOwnProperty(part, 'functionResult')) {
|
|
369
|
-
return { functionResponse: { name: part.functionResult.name, response: part.functionResult.value } };
|
|
370
|
-
}
|
|
371
|
-
if (hasOwnProperty(part, 'functionCall')) {
|
|
372
|
-
return { functionCall: { name: part.functionCall.name, args: part.functionCall.parameters } };
|
|
373
|
-
}
|
|
374
|
-
throw new NotSupportedError('Unsupported content part.');
|
|
375
|
-
}),
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
async convertFunctions(functions) {
|
|
379
|
-
const mapped = mapAsync(objectEntries(functions), async ([name, declaration]) => {
|
|
380
|
-
const enabled = await resolveValueOrAsyncProvider(declaration.enabled);
|
|
381
|
-
if (enabled == false) {
|
|
382
|
-
return undefined;
|
|
383
|
-
}
|
|
384
|
-
const parametersSchema = await resolveValueOrAsyncProvider(declaration.parameters);
|
|
385
|
-
return {
|
|
386
|
-
name,
|
|
387
|
-
description: declaration.description,
|
|
388
|
-
parameters: isDefined(parametersSchema) ? convertToOpenApiSchema(parametersSchema) : undefined,
|
|
389
|
-
};
|
|
390
|
-
});
|
|
391
|
-
const functionsArray = await toArrayAsync(mapped);
|
|
392
|
-
return functionsArray.filter(isDefined);
|
|
393
|
-
}
|
|
394
|
-
convertGoogleContent(content) {
|
|
395
|
-
return {
|
|
396
|
-
role: content.role,
|
|
397
|
-
parts: isUndefined(content.parts)
|
|
398
|
-
? []
|
|
399
|
-
: content.parts
|
|
400
|
-
.map((part) => {
|
|
401
|
-
if (isDefined(part.text)) {
|
|
402
|
-
if (part.text.length == 0) {
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
return { text: part.text };
|
|
406
|
-
}
|
|
407
|
-
if (isDefined(part.fileData)) {
|
|
408
|
-
const file = assertDefinedPass(this.#fileService.getFileByUri(assertDefinedPass(part.fileData.fileUri, 'Missing file uri')), 'File not found.');
|
|
409
|
-
return { file: file.id };
|
|
410
|
-
}
|
|
411
|
-
if (isDefined(part.functionResponse)) {
|
|
412
|
-
return { functionResult: { name: assertDefinedPass(part.functionResponse.name, 'Missing function name'), value: part.functionResponse.response } };
|
|
413
|
-
}
|
|
414
|
-
if (isDefined(part.functionCall)) {
|
|
415
|
-
return { functionCall: { name: assertDefinedPass(part.functionCall.name, 'Missing function name'), parameters: part.functionCall.args } };
|
|
416
|
-
}
|
|
417
|
-
throw new NotSupportedError('Unsupported content part.');
|
|
418
|
-
})
|
|
419
|
-
.filter(isNotNull),
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
mapModel(model) {
|
|
423
|
-
return match(model)
|
|
424
|
-
.with('small', () => 'gemini-2.5-flash-lite')
|
|
425
|
-
.with('medium', () => 'gemini-2.5-flash')
|
|
426
|
-
.with('large', () => 'gemini-2.5-pro')
|
|
427
|
-
.otherwise(() => model ?? this.defaultModel);
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
AiService = AiService_1 = __decorate([
|
|
431
|
-
Singleton()
|
|
432
|
-
], AiService);
|
|
433
|
-
export { AiService };
|
|
434
|
-
/**
|
|
435
|
-
* Merges an array of streaming generation results into a single, consolidated result.
|
|
436
|
-
* This is useful for combining the chunks from a streaming response into a final object.
|
|
437
|
-
* @param items The array of {@link GenerationResult} items from a stream.
|
|
438
|
-
* @param schema An optional schema to parse the merged JSON output.
|
|
439
|
-
* @returns A single, merged {@link GenerationResult}.
|
|
440
|
-
*/
|
|
441
|
-
export function mergeGenerationStreamItems(items, schema) {
|
|
442
|
-
if (items.length == 0) {
|
|
443
|
-
return {
|
|
444
|
-
content: { role: 'model', parts: [] },
|
|
445
|
-
text: null,
|
|
446
|
-
json: undefined,
|
|
447
|
-
functionCalls: [],
|
|
448
|
-
finishReason: 'unknown',
|
|
449
|
-
usage: { iterations: 0, cached: 0, prompt: 0, thoughts: 0, output: 0, tools: 0, total: 0 },
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
const parts = items.flatMap((item) => item.content.parts);
|
|
453
|
-
return lazyObject({
|
|
454
|
-
content: { value: { role: 'model', parts } },
|
|
455
|
-
text() {
|
|
456
|
-
const textParts = parts.filter((part) => hasOwnProperty(part, 'text')).map((part) => part.text);
|
|
457
|
-
return (textParts.length > 0) ? textParts.join('') : null;
|
|
458
|
-
},
|
|
459
|
-
json() {
|
|
460
|
-
if (isUndefined(schema)) {
|
|
461
|
-
return undefined;
|
|
462
|
-
}
|
|
463
|
-
if (isNull(this.text)) {
|
|
464
|
-
throw new Error('No text to parse available.');
|
|
465
|
-
}
|
|
466
|
-
let parsed;
|
|
467
|
-
try {
|
|
468
|
-
parsed = JSON.parse(this.text);
|
|
469
|
-
}
|
|
470
|
-
catch (error) {
|
|
471
|
-
throw new SyntaxError(`Failed to parse model output as JSON. Raw text: "${this.text}"`, { cause: error });
|
|
472
|
-
}
|
|
473
|
-
return Schema.parse(schema, parsed, { coerce: true });
|
|
474
|
-
},
|
|
475
|
-
functionCalls() {
|
|
476
|
-
return parts.filter((part) => hasOwnProperty(part, 'functionCall')).map((part) => part.functionCall);
|
|
477
|
-
},
|
|
478
|
-
finishReason: { value: items.at(-1).finishReason },
|
|
479
|
-
usage: { value: items.at(-1).usage },
|
|
480
|
-
});
|
|
481
|
-
}
|
package/ai/functions.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { FunctionDeclaration } from '@google/genai';
|
|
2
|
-
import type { AbstractConstructor } from '../types/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Extracts Google AI function declarations from a class decorated with schema information.
|
|
5
|
-
* It iterates over the properties of the class schema and converts `FunctionSchema` instances
|
|
6
|
-
* into the format required by the Google Generative AI API.
|
|
7
|
-
* @param type The constructor of the class to extract function declarations from.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getFunctionDeclarations(type: AbstractConstructor): FunctionDeclaration[];
|
package/ai/functions.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { convertToOpenApiSchema } from '../schema/converters/open-api-converter.js';
|
|
2
|
-
import { FunctionSchema, getObjectSchema, object } from '../schema/index.js';
|
|
3
|
-
import { fromEntries, objectEntries } from '../utils/object/object.js';
|
|
4
|
-
import { isNotNull, isNull, isString } from '../utils/type-guards.js';
|
|
5
|
-
/**
|
|
6
|
-
* Extracts Google AI function declarations from a class decorated with schema information.
|
|
7
|
-
* It iterates over the properties of the class schema and converts `FunctionSchema` instances
|
|
8
|
-
* into the format required by the Google Generative AI API.
|
|
9
|
-
* @param type The constructor of the class to extract function declarations from.
|
|
10
|
-
*/
|
|
11
|
-
export function getFunctionDeclarations(type) {
|
|
12
|
-
const objectSchema = getObjectSchema(type);
|
|
13
|
-
return objectEntries(objectSchema.properties)
|
|
14
|
-
.map(([key, schema]) => {
|
|
15
|
-
if (!(schema instanceof FunctionSchema)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return {
|
|
19
|
-
name: `${type.name}.${key}`,
|
|
20
|
-
description: schema.description ?? undefined,
|
|
21
|
-
parameters: isNull(schema.parameterSchemas)
|
|
22
|
-
? undefined
|
|
23
|
-
: getFunctionDeclarationParameters(schema),
|
|
24
|
-
};
|
|
25
|
-
})
|
|
26
|
-
.filter(isNotNull);
|
|
27
|
-
}
|
|
28
|
-
function getFunctionDeclarationParameters(functionSchema) {
|
|
29
|
-
const entries = functionSchema.parameterSchemas.map((schema, index) => {
|
|
30
|
-
const parameterName = functionSchema.parameterNames[index];
|
|
31
|
-
if (!isString(parameterName)) {
|
|
32
|
-
throw new Error(`Parameter ${index} requires a name.`);
|
|
33
|
-
}
|
|
34
|
-
return [parameterName, schema];
|
|
35
|
-
});
|
|
36
|
-
const parametersSchema = object(fromEntries(entries));
|
|
37
|
-
return convertToOpenApiSchema(parametersSchema);
|
|
38
|
-
}
|
package/ai/module.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { AiModel } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Options for configuring the AI Module.
|
|
4
|
-
*/
|
|
5
|
-
export declare class AiModuleOptions {
|
|
6
|
-
/** Google AI API key. */
|
|
7
|
-
apiKey?: string;
|
|
8
|
-
/** Path to the Google Cloud credentials file. */
|
|
9
|
-
keyFile?: string;
|
|
10
|
-
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
11
|
-
vertex?: {
|
|
12
|
-
project: string;
|
|
13
|
-
location: string;
|
|
14
|
-
bucket?: string;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* The default model to use for generation requests.
|
|
18
|
-
* @default 'small'
|
|
19
|
-
*/
|
|
20
|
-
defaultModel?: AiModel;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Configures the {@link AiService}.
|
|
24
|
-
* @param options The configuration options for the AI services.
|
|
25
|
-
*/
|
|
26
|
-
export declare function configureAiService(options: AiModuleOptions): void;
|
package/ai/module.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Injector } from '../injector/injector.js';
|
|
2
|
-
/**
|
|
3
|
-
* Options for configuring the AI Module.
|
|
4
|
-
*/
|
|
5
|
-
export class AiModuleOptions {
|
|
6
|
-
/** Google AI API key. */
|
|
7
|
-
apiKey;
|
|
8
|
-
/** Path to the Google Cloud credentials file. */
|
|
9
|
-
keyFile;
|
|
10
|
-
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
11
|
-
vertex;
|
|
12
|
-
/**
|
|
13
|
-
* The default model to use for generation requests.
|
|
14
|
-
* @default 'small'
|
|
15
|
-
*/
|
|
16
|
-
defaultModel;
|
|
17
|
-
}
|
|
18
|
-
;
|
|
19
|
-
/**
|
|
20
|
-
* Configures the {@link AiService}.
|
|
21
|
-
* @param options The configuration options for the AI services.
|
|
22
|
-
*/
|
|
23
|
-
export function configureAiService(options) {
|
|
24
|
-
Injector.register(AiModuleOptions, { useValue: options });
|
|
25
|
-
}
|