@carlonicora/nestjs-neo4jsonapi 2.3.1 → 2.4.0
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/agents/common/usage-attribution.d.ts +218 -0
- package/dist/agents/common/usage-attribution.d.ts.map +1 -0
- package/dist/agents/common/usage-attribution.js +235 -0
- package/dist/agents/common/usage-attribution.js.map +1 -0
- package/dist/agents/community.summariser/services/community.summariser.service.d.ts.map +1 -1
- package/dist/agents/community.summariser/services/community.summariser.service.js +13 -1
- package/dist/agents/community.summariser/services/community.summariser.service.js.map +1 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts +24 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts.map +1 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.js +32 -0
- package/dist/agents/contextualiser/contexts/contextualiser.context.js.map +1 -1
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts +7 -0
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts.map +1 -1
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.js +5 -0
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.js.map +1 -1
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/chunk.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js +15 -0
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js +11 -0
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/rational.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/rational.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/rational.node.service.js.map +1 -1
- package/dist/agents/contextualiser/services/contextualiser.service.d.ts +7 -0
- package/dist/agents/contextualiser/services/contextualiser.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/services/contextualiser.service.js +17 -5
- package/dist/agents/contextualiser/services/contextualiser.service.js.map +1 -1
- package/dist/agents/drift/contexts/drift.context.d.ts +25 -1
- package/dist/agents/drift/contexts/drift.context.d.ts.map +1 -1
- package/dist/agents/drift/contexts/drift.context.js +32 -0
- package/dist/agents/drift/contexts/drift.context.js.map +1 -1
- package/dist/agents/drift/nodes/followup.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/followup.node.service.js +4 -0
- package/dist/agents/drift/nodes/followup.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/hyde.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/hyde.node.service.js +9 -1
- package/dist/agents/drift/nodes/hyde.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/primer.answer.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/primer.answer.node.service.js +4 -0
- package/dist/agents/drift/nodes/primer.answer.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/synthesis.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/synthesis.node.service.js +4 -0
- package/dist/agents/drift/nodes/synthesis.node.service.js.map +1 -1
- package/dist/agents/drift/services/drift.search.service.d.ts +9 -0
- package/dist/agents/drift/services/drift.search.service.d.ts.map +1 -1
- package/dist/agents/drift/services/drift.search.service.js +22 -5
- package/dist/agents/drift/services/drift.search.service.js.map +1 -1
- package/dist/agents/graph/services/graph.search.service.d.ts.map +1 -1
- package/dist/agents/graph/services/graph.search.service.js +10 -1
- package/dist/agents/graph/services/graph.search.service.js.map +1 -1
- package/dist/agents/graph/tools/tool.factory.d.ts +6 -0
- package/dist/agents/graph/tools/tool.factory.d.ts.map +1 -1
- package/dist/agents/graph/tools/tool.factory.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/operator/contexts/operator.context.d.ts +37 -1
- package/dist/agents/operator/contexts/operator.context.d.ts.map +1 -1
- package/dist/agents/operator/contexts/operator.context.js +8 -0
- package/dist/agents/operator/contexts/operator.context.js.map +1 -1
- package/dist/agents/operator/interfaces/operator.tool.interface.d.ts +8 -0
- package/dist/agents/operator/interfaces/operator.tool.interface.d.ts.map +1 -1
- package/dist/agents/operator/interfaces/operator.tool.interface.js.map +1 -1
- package/dist/agents/operator/services/operator.service.d.ts +8 -0
- package/dist/agents/operator/services/operator.service.d.ts.map +1 -1
- package/dist/agents/operator/services/operator.service.js +29 -0
- package/dist/agents/operator/services/operator.service.js.map +1 -1
- package/dist/agents/operator/tools/operator.tool.registry.d.ts.map +1 -1
- package/dist/agents/operator/tools/operator.tool.registry.js +2 -1
- package/dist/agents/operator/tools/operator.tool.registry.js.map +1 -1
- package/dist/agents/operator/tools/search-communities.tool.d.ts +8 -2
- package/dist/agents/operator/tools/search-communities.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-communities.tool.js +16 -4
- package/dist/agents/operator/tools/search-communities.tool.js.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.js +5 -0
- package/dist/agents/operator/tools/search-documents.tool.js.map +1 -1
- package/dist/agents/responder/contexts/responder.context.d.ts +31 -0
- package/dist/agents/responder/contexts/responder.context.d.ts.map +1 -1
- package/dist/agents/responder/contexts/responder.context.js +8 -0
- package/dist/agents/responder/contexts/responder.context.js.map +1 -1
- package/dist/agents/responder/factories/responder.context.factory.d.ts +4 -0
- package/dist/agents/responder/factories/responder.context.factory.d.ts.map +1 -1
- package/dist/agents/responder/factories/responder.context.factory.js +2 -0
- package/dist/agents/responder/factories/responder.context.factory.js.map +1 -1
- package/dist/agents/responder/nodes/graph.node.service.d.ts +6 -0
- package/dist/agents/responder/nodes/graph.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/graph.node.service.js +20 -0
- package/dist/agents/responder/nodes/graph.node.service.js.map +1 -1
- package/dist/agents/responder/nodes/planner.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/planner.node.service.js +9 -0
- package/dist/agents/responder/nodes/planner.node.service.js.map +1 -1
- package/dist/agents/responder/nodes/responder.answer.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/responder.answer.node.service.js +9 -0
- package/dist/agents/responder/nodes/responder.answer.node.service.js.map +1 -1
- package/dist/agents/responder/services/responder.service.d.ts +16 -0
- package/dist/agents/responder/services/responder.service.d.ts.map +1 -1
- package/dist/agents/responder/services/responder.service.js +29 -5
- package/dist/agents/responder/services/responder.service.js.map +1 -1
- package/dist/agents/summariser/services/summariser.service.d.ts +7 -0
- package/dist/agents/summariser/services/summariser.service.d.ts.map +1 -1
- package/dist/agents/summariser/services/summariser.service.js +15 -3
- package/dist/agents/summariser/services/summariser.service.js.map +1 -1
- package/dist/common/helpers/index.d.ts +1 -0
- package/dist/common/helpers/index.d.ts.map +1 -1
- package/dist/common/helpers/index.js +1 -0
- package/dist/common/helpers/index.js.map +1 -1
- package/dist/common/helpers/map-with-concurrency.d.ts +23 -0
- package/dist/common/helpers/map-with-concurrency.d.ts.map +1 -0
- package/dist/common/helpers/map-with-concurrency.js +60 -0
- package/dist/common/helpers/map-with-concurrency.js.map +1 -0
- package/dist/common/tokens.d.ts +2 -1
- package/dist/common/tokens.d.ts.map +1 -1
- package/dist/common/tokens.js +2 -1
- package/dist/common/tokens.js.map +1 -1
- package/dist/config/base.config.d.ts +19 -0
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +30 -3
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/interfaces/config.ai.interface.d.ts +10 -1
- package/dist/config/interfaces/config.ai.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.chunk.queues.interface.d.ts +13 -0
- package/dist/config/interfaces/config.chunk.queues.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.credits.interface.d.ts +1 -1
- package/dist/core/llm/services/audio.llm.service.d.ts +70 -1
- package/dist/core/llm/services/audio.llm.service.d.ts.map +1 -1
- package/dist/core/llm/services/audio.llm.service.js +118 -3
- package/dist/core/llm/services/audio.llm.service.js.map +1 -1
- package/dist/core/llm/services/document-ai.service.d.ts +6 -0
- package/dist/core/llm/services/document-ai.service.d.ts.map +1 -1
- package/dist/core/llm/services/document-ai.service.js +1 -0
- package/dist/core/llm/services/document-ai.service.js.map +1 -1
- package/dist/core/llm/services/embedder.service.d.ts +105 -0
- package/dist/core/llm/services/embedder.service.d.ts.map +1 -1
- package/dist/core/llm/services/embedder.service.js +237 -7
- package/dist/core/llm/services/embedder.service.js.map +1 -1
- package/dist/core/llm/services/llm.service.d.ts +103 -6
- package/dist/core/llm/services/llm.service.d.ts.map +1 -1
- package/dist/core/llm/services/llm.service.js +570 -148
- package/dist/core/llm/services/llm.service.js.map +1 -1
- package/dist/core/llm/services/model.service.d.ts +25 -0
- package/dist/core/llm/services/model.service.d.ts.map +1 -1
- package/dist/core/llm/services/model.service.js +76 -4
- package/dist/core/llm/services/model.service.js.map +1 -1
- package/dist/core/llm/utils/repair-truncated-json.d.ts +29 -0
- package/dist/core/llm/utils/repair-truncated-json.d.ts.map +1 -0
- package/dist/core/llm/utils/repair-truncated-json.js +111 -0
- package/dist/core/llm/utils/repair-truncated-json.js.map +1 -0
- package/dist/foundations/assistant/services/assistant.service.d.ts.map +1 -1
- package/dist/foundations/assistant/services/assistant.service.js +12 -0
- package/dist/foundations/assistant/services/assistant.service.js.map +1 -1
- package/dist/foundations/atomicfact/services/atomicfact.service.d.ts +7 -0
- package/dist/foundations/atomicfact/services/atomicfact.service.d.ts.map +1 -1
- package/dist/foundations/atomicfact/services/atomicfact.service.js +6 -0
- package/dist/foundations/atomicfact/services/atomicfact.service.js.map +1 -1
- package/dist/foundations/chunk/processors/chunk.processor.d.ts.map +1 -1
- package/dist/foundations/chunk/processors/chunk.processor.js +7 -1
- package/dist/foundations/chunk/processors/chunk.processor.js.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts +90 -2
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.js +205 -31
- package/dist/foundations/chunk/repositories/chunk.repository.js.map +1 -1
- package/dist/foundations/chunk/services/chunk.service.d.ts.map +1 -1
- package/dist/foundations/chunk/services/chunk.service.js +50 -1
- package/dist/foundations/chunk/services/chunk.service.js.map +1 -1
- package/dist/foundations/chunker/chunker.module.d.ts.map +1 -1
- package/dist/foundations/chunker/chunker.module.js +4 -1
- package/dist/foundations/chunker/chunker.module.js.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.d.ts +57 -1
- package/dist/foundations/chunker/services/chunker.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.js +207 -16
- package/dist/foundations/chunker/services/chunker.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/pdf.service.d.ts +42 -1
- package/dist/foundations/chunker/services/types/pdf.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/pdf.service.js +111 -22
- package/dist/foundations/chunker/services/types/pdf.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/semanticsplitter.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/semanticsplitter.service.js +24 -3
- package/dist/foundations/chunker/services/types/semanticsplitter.service.js.map +1 -1
- package/dist/foundations/company/repositories/company.repository.d.ts +1 -1
- package/dist/foundations/company/repositories/company.repository.d.ts.map +1 -1
- package/dist/foundations/company/repositories/company.repository.js +31 -14
- package/dist/foundations/company/repositories/company.repository.js.map +1 -1
- package/dist/foundations/how-to/processors/how-to.processor.d.ts.map +1 -1
- package/dist/foundations/how-to/processors/how-to.processor.js +20 -7
- package/dist/foundations/how-to/processors/how-to.processor.js.map +1 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts +25 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts.map +1 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.js +38 -2
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.js.map +1 -1
- package/dist/foundations/keyconcept/services/keyconcept.service.d.ts +5 -0
- package/dist/foundations/keyconcept/services/keyconcept.service.d.ts.map +1 -1
- package/dist/foundations/keyconcept/services/keyconcept.service.js +4 -0
- package/dist/foundations/keyconcept/services/keyconcept.service.js.map +1 -1
- package/dist/foundations/tokenusage/entities/tokenusage.js +1 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts +4 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts.map +1 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.js +3 -0
- package/dist/foundations/tokenusage/enums/tokenusage.type.js.map +1 -1
- package/dist/foundations/tokenusage/repositories/tokenusage.admin.repository.js +3 -3
- package/dist/foundations/tokenusage/repositories/tokenusage.repository.js +2 -2
- package/dist/foundations/tokenusage/services/tokenusage.service.d.ts +6 -1
- package/dist/foundations/tokenusage/services/tokenusage.service.d.ts.map +1 -1
- package/dist/foundations/tokenusage/services/tokenusage.service.js +7 -2
- package/dist/foundations/tokenusage/services/tokenusage.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,16 @@ const tokens_1 = require("../../../common/tokens");
|
|
|
21
21
|
const tokenusage_type_1 = require("../../../foundations/tokenusage/enums/tokenusage.type");
|
|
22
22
|
const tokenusage_service_1 = require("../../../foundations/tokenusage/services/tokenusage.service");
|
|
23
23
|
const model_service_1 = require("../../llm/services/model.service");
|
|
24
|
+
/**
|
|
25
|
+
* Ceiling for ONE embedding input. The provider hard cap is 8192 tokens
|
|
26
|
+
* (`400 Invalid 'input[0]': maximum input length is 8192 tokens` from
|
|
27
|
+
* text-embedding-3-large — a real run lost a whole document to it), so this
|
|
28
|
+
* sits below it: the buffer absorbs the chars-per-token fallback heuristic
|
|
29
|
+
* being slightly optimistic for models tiktoken does not know.
|
|
30
|
+
*/
|
|
31
|
+
const MAX_EMBED_INPUT_TOKENS = 8000;
|
|
32
|
+
/** Cut points are snapped to whitespace so slices break between words. */
|
|
33
|
+
const WHITESPACE = /\s/;
|
|
24
34
|
let EmbedderService = EmbedderService_1 = class EmbedderService {
|
|
25
35
|
constructor(modelService, config, tokenUsageService, tokenUsageRecorder) {
|
|
26
36
|
this.modelService = modelService;
|
|
@@ -30,14 +40,149 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
|
|
|
30
40
|
this.logger = new common_1.Logger(EmbedderService_1.name);
|
|
31
41
|
}
|
|
32
42
|
async vectoriseText(params) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
try {
|
|
44
|
+
const result = await this.embedGuarded(params.text, params.attribution);
|
|
45
|
+
await this.persistUsage([params.text], params.attribution);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
await this.persistUsageOnFailure([params.text], params.attribution, error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
async vectoriseTextBatch(texts, attribution) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
try {
|
|
55
|
+
const sliced = texts.map((text) => this.splitByTokenBudget(text));
|
|
56
|
+
const withinBudget = [];
|
|
57
|
+
const oversized = [];
|
|
58
|
+
sliced.forEach((slices, index) => (slices.length === 1 ? withinBudget : oversized).push(index));
|
|
59
|
+
const result = new Array(texts.length);
|
|
60
|
+
// The texts that fit still travel as ONE provider batch, in input order —
|
|
61
|
+
// batching is why vectoriseTextBatch exists (chunk.repository.ts:405).
|
|
62
|
+
if (withinBudget.length > 0) {
|
|
63
|
+
const vectors = await this.modelService.getEmbedder().embedDocuments(withinBudget.map((index) => texts[index]));
|
|
64
|
+
withinBudget.forEach((index, position) => (result[index] = vectors[position]));
|
|
65
|
+
}
|
|
66
|
+
for (const index of oversized) {
|
|
67
|
+
this.warnOversizedInput(texts[index], sliced[index].length, attribution);
|
|
68
|
+
result[index] = this.meanPool(await this.embedSlices(sliced[index]));
|
|
69
|
+
}
|
|
70
|
+
await this.persistUsage(texts, attribution);
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
await this.persistUsageOnFailure(texts, attribution, error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Embeds ONE text, slicing it first when it exceeds the provider's per-input
|
|
80
|
+
* cap: every slice goes through the same (rate-limited) embedder and the
|
|
81
|
+
* slice vectors are mean-pooled, so the caller always gets exactly one vector
|
|
82
|
+
* for one text and no oversized request ever reaches the provider.
|
|
83
|
+
*/
|
|
84
|
+
async embedGuarded(text, attribution) {
|
|
85
|
+
const slices = this.splitByTokenBudget(text);
|
|
86
|
+
if (slices.length === 1)
|
|
87
|
+
return this.modelService.getEmbedder().embedQuery(text);
|
|
88
|
+
this.warnOversizedInput(text, slices.length, attribution);
|
|
89
|
+
return this.meanPool(await this.embedSlices(slices));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Sequential on purpose: it mirrors RateLimitedEmbedder.embedDocuments, which
|
|
93
|
+
* walks its sub-batches one at a time (rate-limited-embedder.ts:77) so a
|
|
94
|
+
* single large input never raids the shared token bucket in one burst.
|
|
95
|
+
*/
|
|
96
|
+
async embedSlices(slices) {
|
|
97
|
+
const vectors = [];
|
|
98
|
+
for (const slice of slices)
|
|
99
|
+
vectors.push(await this.modelService.getEmbedder().embedQuery(slice));
|
|
100
|
+
return vectors;
|
|
101
|
+
}
|
|
102
|
+
warnOversizedInput(text, sliceCount, attribution) {
|
|
103
|
+
const owner = attribution?.relationshipType
|
|
104
|
+
? `${attribution.relationshipType} ${attribution.relationshipId}`
|
|
105
|
+
: "unattributed";
|
|
106
|
+
this.logger.warn(`Embedding input exceeds ${MAX_EMBED_INPUT_TOKENS} tokens ` +
|
|
107
|
+
`(${this.countText(text)} tokens, ${text.length} chars) — embedding ${sliceCount} slices ` +
|
|
108
|
+
`and mean-pooling [${owner}]`);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Slices `text` into pieces that each measure at most MAX_EMBED_INPUT_TOKENS
|
|
112
|
+
* with the SAME tokenizer used for billing. A text that already fits is
|
|
113
|
+
* returned as-is (single element), and the slices always concatenate back to
|
|
114
|
+
* the original text — nothing is dropped.
|
|
115
|
+
*/
|
|
116
|
+
splitByTokenBudget(text) {
|
|
117
|
+
const total = this.countText(text);
|
|
118
|
+
if (total <= MAX_EMBED_INPUT_TOKENS)
|
|
119
|
+
return [text];
|
|
120
|
+
// One measurement of the whole text yields its chars-per-token density,
|
|
121
|
+
// which is only the FIRST GUESS for each cut; every candidate is then
|
|
122
|
+
// measured, so a denser-than-average stretch cannot produce an oversized
|
|
123
|
+
// slice.
|
|
124
|
+
const charsPerToken = text.length / total;
|
|
125
|
+
const slices = [];
|
|
126
|
+
let rest = text;
|
|
127
|
+
while (rest.length > 0) {
|
|
128
|
+
if (this.countText(rest) <= MAX_EMBED_INPUT_TOKENS) {
|
|
129
|
+
slices.push(rest);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const head = this.takeBudgetedHead(rest, charsPerToken);
|
|
133
|
+
slices.push(head);
|
|
134
|
+
rest = rest.slice(head.length);
|
|
135
|
+
}
|
|
136
|
+
return slices;
|
|
137
|
+
}
|
|
138
|
+
/** Longest measured-within-budget prefix of `text` (never empty). */
|
|
139
|
+
takeBudgetedHead(text, charsPerToken) {
|
|
140
|
+
const guess = Math.floor(MAX_EMBED_INPUT_TOKENS * charsPerToken * 0.95);
|
|
141
|
+
let length = Math.max(1, Math.min(text.length - 1, guess));
|
|
142
|
+
for (;;) {
|
|
143
|
+
const candidate = this.snapToWordBoundary(text, length);
|
|
144
|
+
if (this.countText(candidate) <= MAX_EMBED_INPUT_TOKENS)
|
|
145
|
+
return candidate;
|
|
146
|
+
const shorter = Math.floor(length * 0.9);
|
|
147
|
+
// Guarantees progress: the caller consumes head.length characters.
|
|
148
|
+
if (shorter < 1)
|
|
149
|
+
return text.slice(0, 1);
|
|
150
|
+
length = shorter;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Pulls the cut back to the nearest whitespace within the last fifth of the
|
|
155
|
+
* window, so slices break between words. A stretch with no whitespace at all
|
|
156
|
+
* (a long unbroken blob) is cut mid-word rather than left oversized.
|
|
157
|
+
*/
|
|
158
|
+
snapToWordBoundary(text, length) {
|
|
159
|
+
if (length >= text.length)
|
|
160
|
+
return text;
|
|
161
|
+
const earliest = Math.floor(length * 0.8);
|
|
162
|
+
for (let i = length; i > earliest; i--) {
|
|
163
|
+
if (WHITESPACE.test(text[i]))
|
|
164
|
+
return text.slice(0, i);
|
|
165
|
+
}
|
|
166
|
+
return text.slice(0, length);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Element-wise mean of the slice vectors, L2-normalized: the standard
|
|
170
|
+
* long-input reduction. Normalising keeps the pooled vector comparable with
|
|
171
|
+
* single-call vectors under cosine similarity, which is what every Neo4j
|
|
172
|
+
* vector index in this package searches with.
|
|
173
|
+
*/
|
|
174
|
+
meanPool(vectors) {
|
|
175
|
+
const dimensions = vectors[0].length;
|
|
176
|
+
const mean = new Array(dimensions).fill(0);
|
|
177
|
+
for (const vector of vectors) {
|
|
178
|
+
for (let i = 0; i < dimensions; i++)
|
|
179
|
+
mean[i] += vector[i];
|
|
180
|
+
}
|
|
181
|
+
for (let i = 0; i < dimensions; i++)
|
|
182
|
+
mean[i] /= vectors.length;
|
|
183
|
+
const norm = Math.sqrt(mean.reduce((sum, value) => sum + value * value, 0));
|
|
184
|
+
// A zero vector (the MOCK_AI embedder returns those) has no direction to normalise.
|
|
185
|
+
return norm > 0 ? mean.map((value) => value / norm) : mean;
|
|
41
186
|
}
|
|
42
187
|
/**
|
|
43
188
|
* Embedding providers return vectors only — no usage figures — so tokens are
|
|
@@ -49,7 +194,9 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
|
|
|
49
194
|
* opt-in exactly like LLMService.persistUsage, floor-exempt (applyMinimum
|
|
50
195
|
* false): sub-cent embedding calls must never floor to 0.1 credits.
|
|
51
196
|
*/
|
|
52
|
-
async persistUsage(texts, attribution
|
|
197
|
+
async persistUsage(texts, attribution,
|
|
198
|
+
/** Failure path only: a zero-token operation records nothing. See {@link persistUsageOnFailure}. */
|
|
199
|
+
skipWhenZeroTokens = false) {
|
|
53
200
|
if (!attribution?.relationshipId || !attribution?.relationshipType)
|
|
54
201
|
return;
|
|
55
202
|
const embedderConfig = this.config.get("ai")?.embedder;
|
|
@@ -61,6 +208,8 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
|
|
|
61
208
|
return;
|
|
62
209
|
try {
|
|
63
210
|
const tokens = this.countTokens(texts, embedderConfig);
|
|
211
|
+
if (skipWhenZeroTokens && tokens === 0)
|
|
212
|
+
return;
|
|
64
213
|
await recorder.recordTokenUsage({
|
|
65
214
|
tokens: { input: tokens, output: 0 },
|
|
66
215
|
type: attribution.tokenUsageType ?? tokenusage_type_1.TokenUsageType.Embedding,
|
|
@@ -74,6 +223,87 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
|
|
|
74
223
|
this.logger.warn(`Embedding usage persistence failed — continuing: ${String(err)}`);
|
|
75
224
|
}
|
|
76
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Records what a FAILED embedding call already burned — but ONLY when the
|
|
228
|
+
* rejection is evidence the provider actually did work.
|
|
229
|
+
*
|
|
230
|
+
* A failure is not automatically a free call: a batch that dies on the
|
|
231
|
+
* provider's LAST internal sub-batch has still been charged for every chunk
|
|
232
|
+
* the provider served, and `RateLimitedEmbedder` surfaces that as a single
|
|
233
|
+
* rejection. Recording nothing there understates real spend.
|
|
234
|
+
*
|
|
235
|
+
* BUT the counts here are computed LOCALLY with tiktoken, never read off a
|
|
236
|
+
* provider response, so they exist even when the provider was never reached.
|
|
237
|
+
* Billing every rejection would therefore charge the customer for OUR
|
|
238
|
+
* outages, inverting the very rule this path claims parity with:
|
|
239
|
+
* `LLMService.persistUsageOnFailure` bills provider-REPORTED tokens, which
|
|
240
|
+
* are 0 when nothing was served. The damage would be real —
|
|
241
|
+
* `RateLimitedEmbedder` rejects with `EmbedderBucketStarvedError` before any
|
|
242
|
+
* HTTP request when our own token bucket cannot grant within `maxWaitMs`, and
|
|
243
|
+
* these calls sit inside BullMQ jobs with `attempts: 3`, so one transient
|
|
244
|
+
* local failure could bill the same batch up to four times.
|
|
245
|
+
*
|
|
246
|
+
* So the local count is only trusted when {@link providerServedWork} says the
|
|
247
|
+
* rejection carries positive evidence of provider-side work. See that method
|
|
248
|
+
* for the signal and for the residual over-billing it knowingly accepts.
|
|
249
|
+
*
|
|
250
|
+
* ZERO-TOKEN RULE, as everywhere else on this path: an operation that burned
|
|
251
|
+
* nothing records NOTHING — a 0-token row would assert a call that never
|
|
252
|
+
* happened.
|
|
253
|
+
*
|
|
254
|
+
* Never throws: it sits in a catch block and must not mask the original error.
|
|
255
|
+
*/
|
|
256
|
+
async persistUsageOnFailure(texts, attribution, error) {
|
|
257
|
+
if (!this.providerServedWork(error))
|
|
258
|
+
return;
|
|
259
|
+
await this.persistUsage(texts, attribution, true);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Does this rejection carry positive evidence that the provider did billable
|
|
263
|
+
* work? Nothing is billed unless it does.
|
|
264
|
+
*
|
|
265
|
+
* THE SIGNAL: a SERVER-side HTTP status (5xx) reported by the provider. That
|
|
266
|
+
* is the only class of rejection in which the provider accepted the request
|
|
267
|
+
* and failed during or after processing it — the case the failure-billing
|
|
268
|
+
* exists for (a multi-sub-batch call whose last sub-batch 500s, after earlier
|
|
269
|
+
* sub-batches were served and charged).
|
|
270
|
+
*
|
|
271
|
+
* Everything else records NOTHING, because in every other case the provider
|
|
272
|
+
* demonstrably served none of this input:
|
|
273
|
+
* - NO status at all — raised locally before or without any HTTP exchange:
|
|
274
|
+
* `EmbedderBucketStarvedError` (our own bucket refusing to grant), DNS
|
|
275
|
+
* failures, connection refused, aborts and client-side timeouts. This is
|
|
276
|
+
* the "our outage must not charge the customer" case.
|
|
277
|
+
* - A 4xx — the provider REFUSED the request rather than serving it: 401/403
|
|
278
|
+
* auth, 400/422 malformed, 413 too large, 429 rate-limited (including the
|
|
279
|
+
* retry-exhausted path). Providers do not charge for a request they
|
|
280
|
+
* rejected, so neither do we.
|
|
281
|
+
*
|
|
282
|
+
* RESIDUAL OVER-BILLING, KNOWINGLY ACCEPTED: on a 5xx this bills the WHOLE
|
|
283
|
+
* submitted input, including sub-batches the provider never got to.
|
|
284
|
+
* `RateLimitedEmbedder.embedDocuments` splits the input into sequential
|
|
285
|
+
* sub-batches and is all-or-nothing to its caller — it returns vectors or it
|
|
286
|
+
* throws, never a partial result — so this service cannot know how many
|
|
287
|
+
* sub-batches were served. Over-billing is bounded by the batch size and only
|
|
288
|
+
* on provider-side faults; the alternative (recording nothing) silently
|
|
289
|
+
* under-bills every genuinely-served chunk. Narrowing this needs
|
|
290
|
+
* `RateLimitedEmbedder` to report served-sub-batch counts, which would change
|
|
291
|
+
* its published surface.
|
|
292
|
+
*/
|
|
293
|
+
providerServedWork(error) {
|
|
294
|
+
if (!error || typeof error !== "object")
|
|
295
|
+
return false;
|
|
296
|
+
const candidate = error;
|
|
297
|
+
const status = candidate.status ?? candidate.statusCode ?? candidate.response?.status;
|
|
298
|
+
return typeof status === "number" && status >= 500 && status <= 599;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Token count for a SINGLE text, through the very tokenizer billing uses — so
|
|
302
|
+
* the oversize guard slices by the same measure the provider charges by.
|
|
303
|
+
*/
|
|
304
|
+
countText(text) {
|
|
305
|
+
return this.countTokens([text], this.config.get("ai")?.embedder);
|
|
306
|
+
}
|
|
77
307
|
countTokens(texts, embedderConfig) {
|
|
78
308
|
if (this.tokenizer === undefined) {
|
|
79
309
|
// Try the raw model name, then the provider-prefixed form normalised
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedder.service.js","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAsE;AACtE,2CAA+C;AAC/C,6CAAwE;AACxE,mDAA2F;AAE3F,2FAAuF;AACvF,oGAAgG;AAChG,oEAAgE;
|
|
1
|
+
{"version":3,"file":"embedder.service.js","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,6 +81,22 @@ export declare class LLMService {
|
|
|
81
81
|
* otherwise the configured default (`AI_REQUEST_TIMEOUT_MS`).
|
|
82
82
|
*/
|
|
83
83
|
private attemptTimeoutMs;
|
|
84
|
+
/**
|
|
85
|
+
* Reads a stream's `usage` promise WITHOUT ever hanging on it.
|
|
86
|
+
*
|
|
87
|
+
* Used only from the streaming error paths. `streamObject`/`streamText`
|
|
88
|
+
* usually settle `usage` even when `object`/`text` reject — a schema-invalid
|
|
89
|
+
* or aborted generation is still billed — so it is worth awaiting. But the
|
|
90
|
+
* `result` promise those catches belong to has no outer deadline (unlike
|
|
91
|
+
* `call()`, which runs under `runBounded`), so if the SDK ever rejected the
|
|
92
|
+
* content promise while leaving `usage` pending, an unbounded await would turn
|
|
93
|
+
* a prompt rejection into a caller that waits forever. Rejection is handled by
|
|
94
|
+
* `.catch`; PENDENCY is handled by the race. The loser's timer is cleared, so
|
|
95
|
+
* a settled call leaves no timer behind.
|
|
96
|
+
*
|
|
97
|
+
* @returns the usage object, or undefined if it rejected or did not settle in time
|
|
98
|
+
*/
|
|
99
|
+
private readUsageBounded;
|
|
84
100
|
/**
|
|
85
101
|
* Runs one provider call under a WATCHDOG and an ABSOLUTE DEADLINE.
|
|
86
102
|
*
|
|
@@ -109,6 +125,43 @@ export declare class LLMService {
|
|
|
109
125
|
* deadline means the adapter never honoured its own timeout.
|
|
110
126
|
*/
|
|
111
127
|
private runBounded;
|
|
128
|
+
/**
|
|
129
|
+
* True for a failure that means the request never reached a working provider,
|
|
130
|
+
* and is therefore worth another attempt: a DNS/socket-level error code, an
|
|
131
|
+
* HTTP 429 or 5xx, or the message text either of those arrives as.
|
|
132
|
+
*
|
|
133
|
+
* All three are checked because the same failure wears different clothes per
|
|
134
|
+
* transport: undici puts the code on `error.cause.code` behind a bare
|
|
135
|
+
* `TypeError: fetch failed`, the OpenAI SDK puts the status on the error and
|
|
136
|
+
* the code in the message, and LangChain re-wraps both in a plain `Error`.
|
|
137
|
+
*
|
|
138
|
+
* Deliberately NOT transient: a stall that burned its whole deadline
|
|
139
|
+
* ({@link LLMTimeoutError}), a refusal (402/403), a malformed request (400) or
|
|
140
|
+
* a parse failure. Those either already had their retry (`call()` re-issues a
|
|
141
|
+
* timed-out attempt once, escalating the OpenRouter pin) or will fail
|
|
142
|
+
* identically forever. The 429 vocabulary matches the one
|
|
143
|
+
* `VisionLLMService.isRateLimitError` retries on, so the two agree on what a
|
|
144
|
+
* rate limit looks like.
|
|
145
|
+
*/
|
|
146
|
+
private isTransientNetworkError;
|
|
147
|
+
/**
|
|
148
|
+
* Sleeps the jittered backoff for one transient retry and says so in the log.
|
|
149
|
+
* ±20% jitter so a fleet of workers knocked out by the same DNS blip does not
|
|
150
|
+
* come back in lockstep and knock it out again.
|
|
151
|
+
*/
|
|
152
|
+
private waitBeforeTransientRetry;
|
|
153
|
+
/**
|
|
154
|
+
* Runs a provider call under {@link runBounded}, retrying it when — and only
|
|
155
|
+
* when — it failed for a transient network reason
|
|
156
|
+
* ({@link isTransientNetworkError}). Two extra attempts, with the long
|
|
157
|
+
* jittered waits {@link TRANSIENT_RETRY_WAITS_MS} explains.
|
|
158
|
+
*
|
|
159
|
+
* Owns a FRESH AbortController per attempt: a controller that has already
|
|
160
|
+
* aborted stays aborted forever, so re-using one would make every retry abort
|
|
161
|
+
* before it sent a byte. `work` therefore receives the signal rather than
|
|
162
|
+
* capturing one from the caller.
|
|
163
|
+
*/
|
|
164
|
+
private runWithTransientRetry;
|
|
112
165
|
/**
|
|
113
166
|
* Records token usage for cost/observability attribution. Never throws —
|
|
114
167
|
* a persistence failure logs a warning and the LLM call continues, so
|
|
@@ -119,8 +172,38 @@ export declare class LLMService {
|
|
|
119
172
|
* is the ONLY token-usage write inside the package; any future package caller
|
|
120
173
|
* MUST use the same token rather than injecting `TokenUsageService` directly
|
|
121
174
|
* (see the token's docblock for why).
|
|
175
|
+
*
|
|
176
|
+
* ZERO-TOKEN SUCCESS RULE: a call that SUCCEEDED but reported no usage at all
|
|
177
|
+
* (the provider omitted `usage_metadata`) is still recorded — the call really
|
|
178
|
+
* happened and must stay visible — but with `applyMinimum: false`, so it
|
|
179
|
+
* costs 0 credits instead of being floored to `minCreditsPerRecord`. Flooring
|
|
180
|
+
* exists to stop sub-cent REAL usage rounding to nothing, not to invent a
|
|
181
|
+
* charge for tokens nobody measured. A success carrying real counts keeps the
|
|
182
|
+
* floor exactly as before.
|
|
183
|
+
*
|
|
184
|
+
* This is deliberately NOT the same rule as the zero-token FAILURE rule in
|
|
185
|
+
* {@link persistUsageOnFailure}, which writes nothing at all: there the
|
|
186
|
+
* provider was never reached, so there is no call to make visible.
|
|
122
187
|
*/
|
|
123
188
|
private persistUsage;
|
|
189
|
+
/**
|
|
190
|
+
* Records what a FAILED call already burned. A failure is not a free call:
|
|
191
|
+
* the provider bills every round it served, so a tool loop that dies on its
|
|
192
|
+
* final structured invocation has already been charged for six figures of
|
|
193
|
+
* input tokens. Billing only successful calls understates real spend.
|
|
194
|
+
*
|
|
195
|
+
* ZERO-TOKEN RULE: a failure that consumed nothing (the provider was never
|
|
196
|
+
* reached — input validation, an unreachable host, an immediate abort) is NOT
|
|
197
|
+
* recorded. `recordTokenUsage` floors every record at `minCreditsPerRecord`,
|
|
198
|
+
* so writing a 0/0 row would invent a charge for tokens nobody spent; the
|
|
199
|
+
* floor exists to stop sub-cent REAL usage rounding to nothing, not to price
|
|
200
|
+
* a call that never happened. Such failures remain fully visible through the
|
|
201
|
+
* dump session, which closes with `finalStatus: "error"`.
|
|
202
|
+
*
|
|
203
|
+
* Never throws (delegates to {@link persistUsage}), so it can sit in a catch
|
|
204
|
+
* block without masking the original error.
|
|
205
|
+
*/
|
|
206
|
+
private persistUsageOnFailure;
|
|
124
207
|
/**
|
|
125
208
|
* Converts AgentMessageType to LangChain BaseMessage
|
|
126
209
|
*/
|
|
@@ -408,14 +491,22 @@ export declare class LLMService {
|
|
|
408
491
|
/**
|
|
409
492
|
* Single-step model invocation with tools bound — the durable-checkpointing
|
|
410
493
|
* counterpart to {@link call}'s internal tool loop. Performs exactly ONE
|
|
411
|
-
* model
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
494
|
+
* model STEP (no tool execution, no loop, no structured output) and returns
|
|
495
|
+
* the raw AIMessage with any `tool_calls` untouched, so the caller (e.g. the
|
|
496
|
+
* operator agent) can checkpoint state and execute the tool calls itself.
|
|
497
|
+
*
|
|
498
|
+
* "One step" is not "one socket": the step is bounded like every other call
|
|
499
|
+
* (per-attempt budget, watchdog, deadline) and re-issued on a transient
|
|
500
|
+
* network failure. What it never does is re-run the AGENT — the caller's
|
|
501
|
+
* checkpointed state is untouched either way.
|
|
415
502
|
*
|
|
416
503
|
* Reuses {@link call}'s model construction (`modelService.getLLM` +
|
|
417
|
-
* `bindTools`) and `LLMCallDumper` hooks.
|
|
418
|
-
*
|
|
504
|
+
* `bindTools`) and `LLMCallDumper` hooks. The step's token usage is still
|
|
505
|
+
* RETURNED to the caller (so an agent can keep its own running total), and —
|
|
506
|
+
* when `relationshipId`/`relationshipType` are supplied — is now also
|
|
507
|
+
* persisted here, exactly like every other provider call in this service.
|
|
508
|
+
* A caller that omits the attribution gets the previous behaviour: nothing is
|
|
509
|
+
* written. Each step is billed once, by whichever path completes it.
|
|
419
510
|
*
|
|
420
511
|
* @param params.systemPrompts - System prompts, prepended (in order) as
|
|
421
512
|
* SystemMessages before `messages`
|
|
@@ -423,6 +514,9 @@ export declare class LLMService {
|
|
|
423
514
|
* @param params.tools - Tools to bind (NOT executed by this method)
|
|
424
515
|
* @param params.temperature - Optional temperature override
|
|
425
516
|
* @param params.metadata - Optional metadata for dump-session tracking
|
|
517
|
+
* @param params.tokenUsageType - Optional usage type for the recorded row
|
|
518
|
+
* @param params.relationshipId - Optional entity this usage is attributed to
|
|
519
|
+
* @param params.relationshipType - Optional entity type for the attribution
|
|
426
520
|
*
|
|
427
521
|
* @returns The raw AIMessage (tool_calls intact) plus this call's token usage
|
|
428
522
|
*/
|
|
@@ -432,6 +526,9 @@ export declare class LLMService {
|
|
|
432
526
|
tools: DynamicStructuredTool[];
|
|
433
527
|
temperature?: number;
|
|
434
528
|
metadata?: Record<string, unknown>;
|
|
529
|
+
tokenUsageType?: string;
|
|
530
|
+
relationshipId?: string;
|
|
531
|
+
relationshipType?: string;
|
|
435
532
|
}): Promise<{
|
|
436
533
|
message: AIMessage;
|
|
437
534
|
tokenUsage: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/llm.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAA4C,MAAM,0BAA0B,CAAC;AAE5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAwB,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAqB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/llm.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAA4C,MAAM,0BAA0B,CAAC;AAE5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAwB,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAqB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAchE,OAAO,EAAuC,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAmB/F,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AA6C9D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAStD;AAED;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAEtC,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM;gBADlB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM;CAK9B;AAED;;GAEG;AACH,UAAU,aAAa,CAAC,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAsGD,qBACa,UAAU;IAoBnB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAKtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAOO,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAlChF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IAEtD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,2BAA2B;gBAUvB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAC1C,MAAM,EAAE,aAAa,EACrB,iBAAiB,EAAE,iBAAiB,EAKxB,KAAK,CAAC,EAAE,eAAe,EAOO,kBAAkB,CAAC,EAAE,2BAA2B;IAG7G;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;;;;;;;;;OAcG;YACW,gBAAgB;IAkB9B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;YACW,UAAU;IAyCxB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,uBAAuB;IA8C/B;;;;OAIG;YACW,wBAAwB;IAatC;;;;;;;;;;OAUG;YACW,qBAAqB;IAmBnC;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,YAAY;IA4B1B;;;;;;;;;;;;;;;;OAgBG;YACW,qBAAqB;IAanC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAa7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,yBAAyB;IA6CjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,OAAO,CAAC,iCAAiC;IA0BzC;;OAEG;IACH,OAAO,CAAC,eAAe;IA6CvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqEG;IACG,IAAI,CAAC,CAAC,EACV,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,GAAG;QAAE,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC;YAyH7E,eAAe;IAumB7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACG,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5C,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC;QACT,mBAAmB,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG;YAAE,UAAU,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,WAAW,EAAE,WAAW,CAAA;SAAE,CAAC,CAAC;KAClG,CAAC;IA6NF;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC;QACV,UAAU,EAAE,aAAa,CAAC;YAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACzE,MAAM,EAAE,OAAO,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,MAAM,CAAC;YAClB,UAAU,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAC;YAC9C,WAAW,EAAE,WAAW,CAAC;SAC1B,CAAC,CAAC;KACJ,CAAC;IAqMF;;;;;OAKG;IACG,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE;QAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;SAAE,CAAC;QAChE,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B;+EACuE;QACvE,eAAe,CAAC,EAAE,eAAe,CAAC;QAClC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B;;qFAE6E;QAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;oDAE4C;QAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,2EAA2E;QAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,CAAC,CAAC;IA0Nd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACG,QAAQ,CAAC,MAAM,EAAE;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,EAAE,WAAW,EAAE,CAAC;QACxB,KAAK,EAAE,qBAAqB,EAAE,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,SAAS,CAAC;QAAC,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CAwHnF"}
|