@tstdl/base 0.93.170 → 0.93.171
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/document-management/models/ai-configuration.d.ts +4 -0
- package/document-management/server/services/document-management-ai.service.d.ts +1 -1
- package/document-management/server/services/document-management-ai.service.js +28 -16
- package/examples/document-management/ai-provider.d.ts +1 -0
- package/examples/document-management/ai-provider.js +5 -4
- package/examples/document-management/main.js +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ModelReference } from 'genkit';
|
|
2
2
|
import type { Instructions } from '../../ai/prompts/instructions-formatter.js';
|
|
3
3
|
import type { DocumentWorkflowStep } from './document-workflow.model.js';
|
|
4
|
+
import type { GeminiModelConfig } from '../../ai/index.js';
|
|
4
5
|
export type InstructionStrategy = 'replace' | 'append';
|
|
6
|
+
export type DocumentManagementThinkingLevel = NonNullable<GeminiModelConfig['thinkingConfig']>['thinkingLevel'];
|
|
5
7
|
export type InstructionOverride = string | {
|
|
6
8
|
/**
|
|
7
9
|
* Simple way: Provide a specific format pattern.
|
|
@@ -20,6 +22,8 @@ export type InstructionOverride = string | {
|
|
|
20
22
|
export type AiConfiguration = {
|
|
21
23
|
/** The model to use. */
|
|
22
24
|
model?: ModelReference<any>;
|
|
25
|
+
/** The thinking level to use for thinking models. */
|
|
26
|
+
thinkingLevel?: DocumentManagementThinkingLevel;
|
|
23
27
|
/** The language to use for AI outputs. */
|
|
24
28
|
language?: string;
|
|
25
29
|
/** Prompt overrides. */
|
|
@@ -2,7 +2,7 @@ import { type TstdlGenkitGenerationOptions } from '../../../ai/genkit/index.js';
|
|
|
2
2
|
import { type PromptBuilder } from '../../../ai/prompts/index.js';
|
|
3
3
|
import { type SchemaTestable } from '../../../schema/index.js';
|
|
4
4
|
import type { ObjectLiteral } from '../../../types/types.js';
|
|
5
|
-
import type
|
|
5
|
+
import { type ModelReference } from 'genkit';
|
|
6
6
|
import type { AiConfiguration, DocumentPropertyDataType, InstructionOverride } from '../../models/index.js';
|
|
7
7
|
import { Document, DocumentWorkflowStep } from '../../models/index.js';
|
|
8
8
|
import { type AiConfigurationResolveDataMap } from './document-management-ai-provider.service.js';
|
|
@@ -19,8 +19,8 @@ import { distinct } from '../../../utils/array/index.js';
|
|
|
19
19
|
import { numericDateToDateTime, tryDateObjectToNumericDate } from '../../../utils/date-time.js';
|
|
20
20
|
import { fromEntries, hasOwnProperty, objectEntries, objectKeys } from '../../../utils/object/object.js';
|
|
21
21
|
import { assertDefined, assertDefinedPass, assertNotNull, isDefined, isNotNull, isNotNullOrUndefined, isNull, isString, isUndefined } from '../../../utils/type-guards.js';
|
|
22
|
+
import { GenkitError } from 'genkit';
|
|
22
23
|
import { Document, DocumentProperty, DocumentRequestState, DocumentType, DocumentTypeProperty, DocumentWorkflowStep } from '../../models/index.js';
|
|
23
|
-
import { DocumentManagementConfiguration } from '../module.js';
|
|
24
24
|
import { documentCategory, documentRequest, documentRequestCollectionAssignment, documentType } from '../schemas.js';
|
|
25
25
|
import { DocumentCategoryTypeService } from './document-category-type.service.js';
|
|
26
26
|
import { DocumentCollectionService } from './document-collection.service.js';
|
|
@@ -41,7 +41,6 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
41
41
|
#documentCategoryTypeService = inject(DocumentCategoryTypeService);
|
|
42
42
|
#documentFileService = inject(DocumentFileService);
|
|
43
43
|
#documentPropertyService = inject(DocumentPropertyService);
|
|
44
|
-
#documentManagementConfiguration = inject(DocumentManagementConfiguration, undefined, { optional: true });
|
|
45
44
|
#aiProvider = inject(DocumentManagementAiProviderService, undefined, { optional: true });
|
|
46
45
|
#documentPropertyRepository = injectRepository(DocumentProperty);
|
|
47
46
|
#documentRepository = injectRepository(Document);
|
|
@@ -83,7 +82,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
83
82
|
promptBuilder,
|
|
84
83
|
schema,
|
|
85
84
|
document,
|
|
86
|
-
config: { maxOutputTokens:
|
|
85
|
+
config: { maxOutputTokens: 1024 },
|
|
87
86
|
aiConfig,
|
|
88
87
|
});
|
|
89
88
|
const typeId = typeLabelEntries.find((entry) => entry.label == result.documentType)?.id;
|
|
@@ -149,7 +148,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
149
148
|
data: { existingTags: tagLabels },
|
|
150
149
|
schema: generationSchema,
|
|
151
150
|
document,
|
|
152
|
-
config: { maxOutputTokens:
|
|
151
|
+
config: { maxOutputTokens: 4096 },
|
|
153
152
|
aiConfig,
|
|
154
153
|
});
|
|
155
154
|
const filteredDocumentTags = extraction.documentTags.filter((tag) => (tag != extraction.documentTitle) && (tag != extraction.documentSubtitle));
|
|
@@ -207,7 +206,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
207
206
|
promptBuilder: createAssignCollectionPrompt(),
|
|
208
207
|
data: { document: documentData, documentProperties: fromEntries(propertyEntries), collections },
|
|
209
208
|
schema: assignCollectionSchema,
|
|
210
|
-
config: { maxOutputTokens:
|
|
209
|
+
config: { maxOutputTokens: 2048 },
|
|
211
210
|
});
|
|
212
211
|
return result.collectionIds;
|
|
213
212
|
}
|
|
@@ -253,13 +252,15 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
253
252
|
promptBuilder: createAssignRequestPrompt(),
|
|
254
253
|
data: { document: documentData, documentProperties: fromEntries(propertyEntries), requests },
|
|
255
254
|
schema: assignRequestSchema,
|
|
256
|
-
config: { maxOutputTokens:
|
|
255
|
+
config: { maxOutputTokens: 1024 },
|
|
257
256
|
});
|
|
258
257
|
return result.requestId;
|
|
259
258
|
}
|
|
260
259
|
async runAi(tenantId, step, stepData, options) {
|
|
261
260
|
const config = options.aiConfig ?? await this.resolveAiConfiguration(tenantId, step, stepData);
|
|
262
261
|
const model = config.model ?? options.defaultModel;
|
|
262
|
+
const thinkingLevel = config.thinkingLevel ?? 'LOW';
|
|
263
|
+
const configuredModel = isString(model) ? model : model.withConfig({ thinkingConfig: { thinkingLevel } });
|
|
263
264
|
const builder = options.promptBuilder;
|
|
264
265
|
if (isDefined(config.language)) {
|
|
265
266
|
builder.addInstructions({ 'Output Language': languagePrompt(config.language) });
|
|
@@ -282,17 +283,26 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
282
283
|
if (isDefined(options.document)) {
|
|
283
284
|
builder.addMedia(await this.#documentFileService.getContent(options.document), options.document.mimeType);
|
|
284
285
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
286
|
+
try {
|
|
287
|
+
const result = await this.#genkit.generate(genkitGenerationOptions({
|
|
288
|
+
model: configuredModel,
|
|
289
|
+
config: options.config,
|
|
290
|
+
output: { schema: options.schema },
|
|
291
|
+
system: builder.buildSystemPrompt(),
|
|
292
|
+
prompt: builder.buildUserPrompt(),
|
|
293
|
+
}));
|
|
294
|
+
this.#logger.trace(`AI result for ${step} ${options.targetId ?? ''}: usage=${JSON.stringify(result.usage)}, finishReason=${result.finishReason}`);
|
|
295
|
+
if (isNull(result.output)) {
|
|
296
|
+
throw new Error(`AI returned null output for ${step} ${options.targetId ?? ''}. Finish reason: ${result.finishReason}`);
|
|
297
|
+
}
|
|
298
|
+
return result.output;
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
if (error instanceof GenkitError) {
|
|
302
|
+
this.#logger.error(`AI ${step} ${options.targetId ?? ''} failed: status=${error.status}, message=${error.originalMessage}, details=${JSON.stringify(error.detail)}`);
|
|
303
|
+
}
|
|
304
|
+
throw error;
|
|
294
305
|
}
|
|
295
|
-
return result.output;
|
|
296
306
|
}
|
|
297
307
|
async resolveAiConfiguration(tenantId, step, data) {
|
|
298
308
|
const globalConfig = await this.#aiProvider?.getGlobalConfiguration(tenantId);
|
|
@@ -312,6 +322,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
312
322
|
stepConfig,
|
|
313
323
|
].filter(isDefined);
|
|
314
324
|
const model = mergeMostSpecific(configs, 'model');
|
|
325
|
+
const thinkingLevel = mergeMostSpecific(configs, 'thinkingLevel');
|
|
315
326
|
const language = mergeMostSpecific(configs, 'language');
|
|
316
327
|
const systemAddition = resolveAdditions(configs.map((c) => c.prompt?.systemAddition));
|
|
317
328
|
const userAddition = resolveAdditions(configs.map((c) => c.prompt?.userAddition));
|
|
@@ -321,6 +332,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
321
332
|
const classification = mergeMostSpecific(configs, 'classification');
|
|
322
333
|
return {
|
|
323
334
|
model,
|
|
335
|
+
thinkingLevel,
|
|
324
336
|
language,
|
|
325
337
|
prompt: {
|
|
326
338
|
systemAddition,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AiConfiguration, DocumentManagementAiConfiguration, DocumentWorkflowStep } from '../../document-management/index.js';
|
|
2
2
|
import { DocumentManagementAiProviderService, type AiConfigurationResolveDataMap } from '../../document-management/server/index.js';
|
|
3
3
|
export declare class ExampleAiProviderService extends DocumentManagementAiProviderService {
|
|
4
|
+
#private;
|
|
4
5
|
/**
|
|
5
6
|
* Providing global defaults for the entire Document Management module.
|
|
6
7
|
*/
|
|
@@ -9,6 +9,7 @@ import { fewShotPrompt, stylePrompt } from '../../ai/prompts/index.js';
|
|
|
9
9
|
import { DocumentManagementAiProviderService } from '../../document-management/server/index.js';
|
|
10
10
|
import { Singleton } from '../../injector/index.js';
|
|
11
11
|
let ExampleAiProviderService = class ExampleAiProviderService extends DocumentManagementAiProviderService {
|
|
12
|
+
#model = injectModel('gemini-3.1-flash-lite-preview').withConfig({ thinkingConfig: { thinkingLevel: 'LOW' } });
|
|
12
13
|
/**
|
|
13
14
|
* Providing global defaults for the entire Document Management module.
|
|
14
15
|
*/
|
|
@@ -16,9 +17,9 @@ let ExampleAiProviderService = class ExampleAiProviderService extends DocumentMa
|
|
|
16
17
|
return {
|
|
17
18
|
defaults: {
|
|
18
19
|
language: 'German', // Steer all AI outputs to German
|
|
19
|
-
model:
|
|
20
|
+
model: this.#model,
|
|
20
21
|
prompt: {
|
|
21
|
-
|
|
22
|
+
// systemAddition: 'Additional global instructions for all AI steps.',
|
|
22
23
|
},
|
|
23
24
|
},
|
|
24
25
|
};
|
|
@@ -32,9 +33,9 @@ let ExampleAiProviderService = class ExampleAiProviderService extends DocumentMa
|
|
|
32
33
|
getClassificationConfiguration() {
|
|
33
34
|
return {
|
|
34
35
|
// Use a faster/cheaper model for classification
|
|
35
|
-
model:
|
|
36
|
+
model: this.#model,
|
|
36
37
|
prompt: {
|
|
37
|
-
systemAddition: 'For classification, focus strictly on
|
|
38
|
+
systemAddition: 'For classification, focus strictly on document content.',
|
|
38
39
|
},
|
|
39
40
|
};
|
|
40
41
|
}
|
|
@@ -49,7 +49,7 @@ const config = {
|
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
s3: {
|
|
52
|
-
endpoint: string('S3_ENDPOINT', 'http://localhost:
|
|
52
|
+
endpoint: string('S3_ENDPOINT', 'http://localhost:19552'),
|
|
53
53
|
accessKey: string('S3_ACCESS_KEY', 'tstdl-dev'),
|
|
54
54
|
secretKey: string('S3_SECRET_KEY', 'tstdl-dev'),
|
|
55
55
|
bucket: string('S3_BUCKET', undefined),
|