@carlonicora/nestjs-neo4jsonapi 2.7.2 → 2.8.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.
Files changed (96) hide show
  1. package/dist/config/base.config.d.ts.map +1 -1
  2. package/dist/config/base.config.js +4 -0
  3. package/dist/config/base.config.js.map +1 -1
  4. package/dist/config/interfaces/config.ai.interface.d.ts +5 -0
  5. package/dist/config/interfaces/config.ai.interface.d.ts.map +1 -1
  6. package/dist/core/llm/index.d.ts +2 -0
  7. package/dist/core/llm/index.d.ts.map +1 -1
  8. package/dist/core/llm/index.js +2 -0
  9. package/dist/core/llm/index.js.map +1 -1
  10. package/dist/core/llm/interfaces/ai-candidate.interface.d.ts +32 -0
  11. package/dist/core/llm/interfaces/ai-candidate.interface.d.ts.map +1 -0
  12. package/dist/core/llm/interfaces/ai-candidate.interface.js +15 -0
  13. package/dist/core/llm/interfaces/ai-candidate.interface.js.map +1 -0
  14. package/dist/core/llm/llm.module.d.ts.map +1 -1
  15. package/dist/core/llm/llm.module.js +6 -1
  16. package/dist/core/llm/llm.module.js.map +1 -1
  17. package/dist/core/llm/services/ai-connection-resolver.service.d.ts +107 -0
  18. package/dist/core/llm/services/ai-connection-resolver.service.d.ts.map +1 -0
  19. package/dist/core/llm/services/ai-connection-resolver.service.js +329 -0
  20. package/dist/core/llm/services/ai-connection-resolver.service.js.map +1 -0
  21. package/dist/core/llm/services/embedder.service.d.ts +21 -0
  22. package/dist/core/llm/services/embedder.service.d.ts.map +1 -1
  23. package/dist/core/llm/services/embedder.service.js +52 -3
  24. package/dist/core/llm/services/embedder.service.js.map +1 -1
  25. package/dist/core/llm/services/llm.service.d.ts +65 -18
  26. package/dist/core/llm/services/llm.service.d.ts.map +1 -1
  27. package/dist/core/llm/services/llm.service.js +214 -70
  28. package/dist/core/llm/services/llm.service.js.map +1 -1
  29. package/dist/core/llm/services/model.service.d.ts +79 -2
  30. package/dist/core/llm/services/model.service.d.ts.map +1 -1
  31. package/dist/core/llm/services/model.service.js +289 -31
  32. package/dist/core/llm/services/model.service.js.map +1 -1
  33. package/dist/core/llm/services/vision.llm.service.d.ts +25 -1
  34. package/dist/core/llm/services/vision.llm.service.d.ts.map +1 -1
  35. package/dist/core/llm/services/vision.llm.service.js +74 -33
  36. package/dist/core/llm/services/vision.llm.service.js.map +1 -1
  37. package/dist/foundations/ai-connection/ai-connection.module.d.ts +5 -0
  38. package/dist/foundations/ai-connection/ai-connection.module.d.ts.map +1 -0
  39. package/dist/foundations/ai-connection/ai-connection.module.js +37 -0
  40. package/dist/foundations/ai-connection/ai-connection.module.js.map +1 -0
  41. package/dist/foundations/ai-connection/controllers/ai-connection.controller.d.ts +32 -0
  42. package/dist/foundations/ai-connection/controllers/ai-connection.controller.d.ts.map +1 -0
  43. package/dist/foundations/ai-connection/controllers/ai-connection.controller.js +162 -0
  44. package/dist/foundations/ai-connection/controllers/ai-connection.controller.js.map +1 -0
  45. package/dist/foundations/ai-connection/dtos/ai-connection.post.dto.d.ts +41 -0
  46. package/dist/foundations/ai-connection/dtos/ai-connection.post.dto.d.ts.map +1 -0
  47. package/dist/foundations/ai-connection/dtos/ai-connection.post.dto.js +189 -0
  48. package/dist/foundations/ai-connection/dtos/ai-connection.post.dto.js.map +1 -0
  49. package/dist/foundations/ai-connection/dtos/ai-connection.put.dto.d.ts +42 -0
  50. package/dist/foundations/ai-connection/dtos/ai-connection.put.dto.d.ts.map +1 -0
  51. package/dist/foundations/ai-connection/dtos/ai-connection.put.dto.js +179 -0
  52. package/dist/foundations/ai-connection/dtos/ai-connection.put.dto.js.map +1 -0
  53. package/dist/foundations/ai-connection/dtos/ai-connection.reorder.dto.d.ts +8 -0
  54. package/dist/foundations/ai-connection/dtos/ai-connection.reorder.dto.d.ts.map +1 -0
  55. package/dist/foundations/ai-connection/dtos/ai-connection.reorder.dto.js +38 -0
  56. package/dist/foundations/ai-connection/dtos/ai-connection.reorder.dto.js.map +1 -0
  57. package/dist/foundations/ai-connection/entities/ai-connection.d.ts +57 -0
  58. package/dist/foundations/ai-connection/entities/ai-connection.d.ts.map +1 -0
  59. package/dist/foundations/ai-connection/entities/ai-connection.js +73 -0
  60. package/dist/foundations/ai-connection/entities/ai-connection.js.map +1 -0
  61. package/dist/foundations/ai-connection/entities/ai-connection.meta.d.ts +3 -0
  62. package/dist/foundations/ai-connection/entities/ai-connection.meta.d.ts.map +1 -0
  63. package/dist/foundations/ai-connection/entities/ai-connection.meta.js +10 -0
  64. package/dist/foundations/ai-connection/entities/ai-connection.meta.js.map +1 -0
  65. package/dist/foundations/ai-connection/index.d.ts +12 -0
  66. package/dist/foundations/ai-connection/index.d.ts.map +1 -0
  67. package/dist/foundations/ai-connection/index.js +35 -0
  68. package/dist/foundations/ai-connection/index.js.map +1 -0
  69. package/dist/foundations/ai-connection/registry/ai-provider.registry.d.ts +54 -0
  70. package/dist/foundations/ai-connection/registry/ai-provider.registry.d.ts.map +1 -0
  71. package/dist/foundations/ai-connection/registry/ai-provider.registry.js +255 -0
  72. package/dist/foundations/ai-connection/registry/ai-provider.registry.js.map +1 -0
  73. package/dist/foundations/ai-connection/repositories/ai-connection.repository.d.ts +52 -0
  74. package/dist/foundations/ai-connection/repositories/ai-connection.repository.d.ts.map +1 -0
  75. package/dist/foundations/ai-connection/repositories/ai-connection.repository.js +85 -0
  76. package/dist/foundations/ai-connection/repositories/ai-connection.repository.js.map +1 -0
  77. package/dist/foundations/ai-connection/services/ai-connection-encryption.service.d.ts +52 -0
  78. package/dist/foundations/ai-connection/services/ai-connection-encryption.service.d.ts.map +1 -0
  79. package/dist/foundations/ai-connection/services/ai-connection-encryption.service.js +148 -0
  80. package/dist/foundations/ai-connection/services/ai-connection-encryption.service.js.map +1 -0
  81. package/dist/foundations/ai-connection/services/ai-connection.service.d.ts +79 -0
  82. package/dist/foundations/ai-connection/services/ai-connection.service.d.ts.map +1 -0
  83. package/dist/foundations/ai-connection/services/ai-connection.service.js +184 -0
  84. package/dist/foundations/ai-connection/services/ai-connection.service.js.map +1 -0
  85. package/dist/foundations/foundations.modules.d.ts.map +1 -1
  86. package/dist/foundations/foundations.modules.js +2 -0
  87. package/dist/foundations/foundations.modules.js.map +1 -1
  88. package/dist/foundations/index.d.ts +1 -0
  89. package/dist/foundations/index.d.ts.map +1 -1
  90. package/dist/foundations/index.js +1 -0
  91. package/dist/foundations/index.js.map +1 -1
  92. package/dist/foundations/tokenusage/services/tokenusage.service.d.ts +29 -0
  93. package/dist/foundations/tokenusage/services/tokenusage.service.d.ts.map +1 -1
  94. package/dist/foundations/tokenusage/services/tokenusage.service.js +15 -3
  95. package/dist/foundations/tokenusage/services/tokenusage.service.js.map +1 -1
  96. package/package.json +1 -1
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var AiConnectionResolverService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.AiConnectionResolverService = void 0;
17
+ exports.toCandidate = toCandidate;
18
+ const common_1 = require("@nestjs/common");
19
+ const config_1 = require("@nestjs/config");
20
+ const event_emitter_1 = require("@nestjs/event-emitter");
21
+ const nestjs_cls_1 = require("nestjs-cls");
22
+ const ai_connection_repository_1 = require("../../../foundations/ai-connection/repositories/ai-connection.repository");
23
+ const ai_connection_encryption_service_1 = require("../../../foundations/ai-connection/services/ai-connection-encryption.service");
24
+ const logging_service_1 = require("../../logging/services/logging.service");
25
+ const ai_candidate_interface_1 = require("../interfaces/ai-candidate.interface");
26
+ /** How often the in-memory snapshot is rebuilt from the database. */
27
+ const SNAPSHOT_REFRESH_INTERVAL_MS = 60_000;
28
+ /** Cooldown used when `ai.connectionCooldownMinutes` is missing from config. */
29
+ const DEFAULT_COOLDOWN_MINUTES = 5;
30
+ /** Snapshot key for the chain that applies to every company. */
31
+ const GLOBAL_SCOPE = "global";
32
+ const KNOWN_CONNECTION_TYPES = new Set(ai_candidate_interface_1.AI_CONNECTION_TYPES);
33
+ const asString = (value) => typeof value === "string" && value !== "" ? value : undefined;
34
+ const asNumber = (value) => (typeof value === "number" ? value : undefined);
35
+ const asBoolean = (value) => (typeof value === "boolean" ? value : undefined);
36
+ /**
37
+ * Normalises one `AiConnection` node into the candidate shape `buildChatModel`
38
+ * (and its embedder/transcriber siblings) already consume.
39
+ *
40
+ * Pure on purpose: the decryptor is injected so the caller decides what a
41
+ * decryption failure means. It THROWS when a stored secret cannot be decrypted —
42
+ * {@link AiConnectionResolverService.refreshNow} catches that and skips the
43
+ * connection, so a single unreadable secret never takes the chain down
44
+ * (spec § 5 "Error handling").
45
+ */
46
+ function toCandidate(connection, decrypt) {
47
+ return {
48
+ source: "db",
49
+ connectionId: connection.id,
50
+ connectionType: connection.connectionType,
51
+ provider: connection.provider,
52
+ apiKey: connection.apiKey ? decrypt(connection.apiKey) : "",
53
+ model: connection.model ?? "",
54
+ url: connection.url ?? "",
55
+ region: connection.region,
56
+ instance: connection.instance,
57
+ apiVersion: connection.apiVersion,
58
+ googleCredentialsBase64: connection.googleCredentialsBase64
59
+ ? decrypt(connection.googleCredentialsBase64)
60
+ : undefined,
61
+ allowFallbacks: connection.allowFallbacks,
62
+ reasoningEffort: connection.reasoningEffort,
63
+ maxOutputTokens: connection.maxOutputTokens,
64
+ dimensions: connection.dimensions,
65
+ inputCostPer1MTokens: connection.inputCostPer1MTokens,
66
+ outputCostPer1MTokens: connection.outputCostPer1MTokens,
67
+ cachedInputCostPer1MTokens: connection.cachedInputCostPer1MTokens,
68
+ costPerMinute: connection.costPerMinute,
69
+ costPerPage: connection.costPerPage,
70
+ directUrl: connection.directUrl,
71
+ language: connection.language,
72
+ directFormat: connection.directFormat,
73
+ directProvider: connection.directProvider,
74
+ };
75
+ }
76
+ /**
77
+ * Resolves the ordered fallback chain for an AI connection type.
78
+ *
79
+ * Holds an in-memory snapshot of every enabled `AiConnection` node (decrypted,
80
+ * grouped into chains by `(connectionType, companyId | null)`, ordered by
81
+ * `position`), refreshed at boot, every 60s, and immediately on any admin write
82
+ * in this process (`AI_CONNECTIONS_CHANGED_EVENT`).
83
+ *
84
+ * The snapshot exists because `ModelService.getLLM()` is synchronous and called
85
+ * directly by several library services: resolution must stay a pure sync lookup
86
+ * with no signature ripple (spec § 2).
87
+ *
88
+ * Failure ALWAYS degrades toward today's `.env` behaviour, never toward "no AI"
89
+ * (spec § 5): an empty table, a failed refresh, an undecryptable secret or an
90
+ * unknown connection type all leave the `.env` candidate in place, and nothing
91
+ * on the `resolve()` hot path throws.
92
+ */
93
+ let AiConnectionResolverService = AiConnectionResolverService_1 = class AiConnectionResolverService {
94
+ constructor(repository, encryption, cls, configService, logger) {
95
+ this.repository = repository;
96
+ this.encryption = encryption;
97
+ this.cls = cls;
98
+ this.configService = configService;
99
+ this.logger = logger;
100
+ /** `${connectionType}|${companyId ?? "global"}` → ordered candidates. */
101
+ this.snapshot = new Map();
102
+ /** connectionId → epoch ms before which the candidate is skipped. */
103
+ this.cooldownUntil = new Map();
104
+ }
105
+ /**
106
+ * Loads the first snapshot and starts the periodic refresh. Neither is
107
+ * awaited and neither can reject: boot must never depend on the database
108
+ * holding AI connection rows (spec § 5).
109
+ */
110
+ onModuleInit() {
111
+ void this.refreshNow().catch((error) => this.warn("initial snapshot load failed", error));
112
+ this.refreshTimer = setInterval(() => {
113
+ void this.refreshNow().catch((error) => this.warn("scheduled snapshot refresh failed", error));
114
+ }, SNAPSHOT_REFRESH_INTERVAL_MS);
115
+ // Never hold the process open for a cache refresh.
116
+ this.refreshTimer.unref?.();
117
+ }
118
+ /**
119
+ * The ordered candidates to try for `type`, best first.
120
+ *
121
+ * Per-company chain when the request's company has one, otherwise the global
122
+ * chain; the `.env` block is ALWAYS appended last. Candidates inside their
123
+ * cooldown window are dropped — unless that empties the list, in which case
124
+ * the full chain is returned anyway (fail-open, spec § 2).
125
+ *
126
+ * Never throws.
127
+ */
128
+ resolve(type) {
129
+ const candidates = [];
130
+ try {
131
+ const companyId = this.currentCompanyId();
132
+ if (companyId) {
133
+ const scoped = this.snapshot.get(this.chainKey(type, companyId));
134
+ if (scoped?.length)
135
+ candidates.push(...scoped);
136
+ }
137
+ if (candidates.length === 0) {
138
+ const global = this.snapshot.get(this.chainKey(type, undefined));
139
+ if (global?.length)
140
+ candidates.push(...global);
141
+ }
142
+ }
143
+ catch (error) {
144
+ // A broken CLS/snapshot read degrades to the env candidate alone.
145
+ this.warn(`chain lookup failed for "${type}"`, error);
146
+ candidates.length = 0;
147
+ }
148
+ candidates.push(this.buildEnvCandidate(type));
149
+ const now = Date.now();
150
+ const healthy = candidates.filter((candidate) => (this.cooldownUntil.get(candidate.connectionId) ?? 0) <= now);
151
+ return healthy.length > 0 ? healthy : candidates;
152
+ }
153
+ /**
154
+ * Parks a connection for `ai.connectionCooldownMinutes` after a transient
155
+ * failure (429 / 5xx / network). The `.env` candidate is tracked under
156
+ * `env:<type>` like any other, so a dead env fallback cannot block recovery.
157
+ */
158
+ markFailure(connectionId) {
159
+ if (!connectionId)
160
+ return;
161
+ this.cooldownUntil.set(connectionId, Date.now() + this.cooldownMinutes * 60_000);
162
+ }
163
+ /**
164
+ * Rebuilds the snapshot from the database. Also the handler for admin writes
165
+ * in this process; other processes catch up at the next scheduled refresh.
166
+ *
167
+ * A read failure keeps the PREVIOUS snapshot — a database blip must not wipe
168
+ * working configuration (spec § 5).
169
+ */
170
+ async refreshNow() {
171
+ let connections;
172
+ try {
173
+ connections = await this.readConnections();
174
+ }
175
+ catch (error) {
176
+ this.warn("snapshot refresh failed — keeping the previous snapshot", error);
177
+ return;
178
+ }
179
+ const next = new Map();
180
+ const ordered = [...(connections ?? [])].sort((a, b) => (a?.position ?? 0) - (b?.position ?? 0));
181
+ for (const connection of ordered) {
182
+ if (!connection || connection.enabled === false)
183
+ continue;
184
+ if (!KNOWN_CONNECTION_TYPES.has(connection.connectionType)) {
185
+ this.warn(`skipping connection ${connection.id}: unknown connectionType "${connection.connectionType}"`);
186
+ continue;
187
+ }
188
+ let candidate;
189
+ try {
190
+ candidate = toCandidate(connection, (value) => this.encryption.decrypt(value));
191
+ }
192
+ catch (error) {
193
+ this.warn(`skipping connection ${connection.id}: stored secret could not be decrypted`, error);
194
+ continue;
195
+ }
196
+ const key = this.chainKey(candidate.connectionType, connection.companyId);
197
+ const chain = next.get(key);
198
+ if (chain)
199
+ chain.push(candidate);
200
+ else
201
+ next.set(key, [candidate]);
202
+ }
203
+ this.snapshot = next;
204
+ }
205
+ // --- internals ----------------------------------------------------------
206
+ /**
207
+ * Reads every connection inside a CLS context: the refresh runs outside any
208
+ * HTTP request, and the query plumbing reads CLS (`companyId`) unconditionally.
209
+ */
210
+ readConnections() {
211
+ if (typeof this.cls?.run === "function") {
212
+ return this.cls.run(async () => this.repository.findAllForResolver());
213
+ }
214
+ return this.repository.findAllForResolver();
215
+ }
216
+ /**
217
+ * The company of the current request, or undefined when there is none.
218
+ *
219
+ * Optional-call plus a silent catch: the resolver is also used by workers and
220
+ * boot-time code with no CLS context at all, which is an ordinary state and
221
+ * must not log or throw — it simply means "use the global chain".
222
+ */
223
+ currentCompanyId() {
224
+ try {
225
+ const companyId = this.cls?.get?.("companyId");
226
+ return typeof companyId === "string" && companyId !== "" ? companyId : undefined;
227
+ }
228
+ catch {
229
+ return undefined;
230
+ }
231
+ }
232
+ chainKey(type, companyId) {
233
+ return `${type}|${companyId ?? GLOBAL_SCOPE}`;
234
+ }
235
+ get aiConfig() {
236
+ try {
237
+ return this.configService?.get("ai");
238
+ }
239
+ catch {
240
+ return undefined;
241
+ }
242
+ }
243
+ get cooldownMinutes() {
244
+ // `connectionCooldownMinutes` is added to the `ai` block by the config task;
245
+ // default defensively so this works even when the read returns undefined.
246
+ const ai = this.aiConfig;
247
+ const configured = ai?.connectionCooldownMinutes;
248
+ return typeof configured === "number" && configured > 0 ? configured : DEFAULT_COOLDOWN_MINUTES;
249
+ }
250
+ /**
251
+ * The `.env` block for a type, mapped field-for-field onto a candidate. This
252
+ * is the final link of every chain and the whole behaviour when the table is
253
+ * empty — with zero `AiConnection` nodes, resolution is byte-for-byte today's.
254
+ */
255
+ buildEnvCandidate(type) {
256
+ const block = this.envBlockFor(type);
257
+ return {
258
+ source: "env",
259
+ connectionId: `env:${type}`,
260
+ connectionType: type,
261
+ provider: asString(block.provider) ?? "",
262
+ apiKey: asString(block.apiKey) ?? "",
263
+ model: asString(block.model) ?? "",
264
+ url: asString(block.url) ?? "",
265
+ region: asString(block.region),
266
+ instance: asString(block.instance),
267
+ apiVersion: asString(block.apiVersion),
268
+ googleCredentialsBase64: asString(block.googleCredentialsBase64),
269
+ allowFallbacks: asBoolean(block.allowFallbacks),
270
+ reasoningEffort: asString(block.reasoningEffort),
271
+ maxOutputTokens: asNumber(block.maxOutputTokens),
272
+ dimensions: asNumber(block.dimensions),
273
+ inputCostPer1MTokens: asNumber(block.inputCostPer1MTokens),
274
+ outputCostPer1MTokens: asNumber(block.outputCostPer1MTokens),
275
+ cachedInputCostPer1MTokens: asNumber(block.cachedInputCostPer1MTokens),
276
+ costPerMinute: asNumber(block.costPerMinute),
277
+ costPerPage: asNumber(block.costPerPage),
278
+ directUrl: asString(block.directUrl),
279
+ language: asString(block.language),
280
+ directFormat: asString(block.directFormat),
281
+ directProvider: asString(block.directProvider),
282
+ };
283
+ }
284
+ /** Same block mapping the admin API uses for `meta.envDefaults`. */
285
+ envBlockFor(type) {
286
+ const ai = this.aiConfig;
287
+ if (!ai)
288
+ return {};
289
+ switch (type) {
290
+ case "aiLite":
291
+ return (ai.aiLite ?? {});
292
+ case "aiLarge":
293
+ return (ai.aiLarge ?? {});
294
+ case "vision":
295
+ return (ai.vision ?? {});
296
+ case "audio":
297
+ return (ai.audio ?? {});
298
+ case "embedder":
299
+ return (ai.embedder ?? {});
300
+ case "transcriber":
301
+ return (ai.transcriber ?? {});
302
+ case "documentAi":
303
+ return (ai.documentAi ?? {});
304
+ default:
305
+ return (ai.ai ?? {});
306
+ }
307
+ }
308
+ warn(message, error) {
309
+ const detail = error instanceof Error ? error.message : error !== undefined ? String(error) : undefined;
310
+ this.logger?.warn(detail ? `[AiConnectionResolver] ${message}: ${detail}` : `[AiConnectionResolver] ${message}`, AiConnectionResolverService_1.name);
311
+ }
312
+ };
313
+ exports.AiConnectionResolverService = AiConnectionResolverService;
314
+ __decorate([
315
+ (0, event_emitter_1.OnEvent)(ai_candidate_interface_1.AI_CONNECTIONS_CHANGED_EVENT),
316
+ __metadata("design:type", Function),
317
+ __metadata("design:paramtypes", []),
318
+ __metadata("design:returntype", Promise)
319
+ ], AiConnectionResolverService.prototype, "refreshNow", null);
320
+ exports.AiConnectionResolverService = AiConnectionResolverService = AiConnectionResolverService_1 = __decorate([
321
+ (0, common_1.Injectable)(),
322
+ __param(4, (0, common_1.Optional)()),
323
+ __metadata("design:paramtypes", [ai_connection_repository_1.AiConnectionRepository,
324
+ ai_connection_encryption_service_1.AiConnectionEncryptionService,
325
+ nestjs_cls_1.ClsService,
326
+ config_1.ConfigService,
327
+ logging_service_1.AppLoggingService])
328
+ ], AiConnectionResolverService);
329
+ //# sourceMappingURL=ai-connection-resolver.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-connection-resolver.service.js","sourceRoot":"","sources":["../../../../src/core/llm/services/ai-connection-resolver.service.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,27 @@ export declare class EmbedderService {
21
21
  private readonly tokenUsageRecorder?;
22
22
  private readonly logger;
23
23
  constructor(modelService: ModelService, config: ConfigService<BaseConfigInterface>, tokenUsageService?: TokenUsageService, tokenUsageRecorder?: TokenUsageRecorderInterface);
24
+ /**
25
+ * Runs ONE embedding invocation, with a single failover retry on a transient
26
+ * provider failure (429/5xx/socket-level — classified by exactly the rule
27
+ * `LLMService` uses).
28
+ *
29
+ * ONE retry only, and only when there is somewhere to go: the failed
30
+ * connection is put into cooldown and the embedder is rebuilt, so
31
+ * `getEmbedder()` resolves the NEXT healthy link of the chain. A chain of one
32
+ * (no DB-backed embedder connection — just the `.env` block) has nowhere to
33
+ * fail over to, so the rejection propagates immediately, exactly as it does
34
+ * today. Everything beyond that single re-resolution belongs to the BullMQ
35
+ * job retry that owns these calls (spec § 2, "Other modalities").
36
+ */
37
+ private withCandidateFailover;
38
+ /**
39
+ * Puts the embedder connection currently in service into its cooldown window
40
+ * and returns it — or undefined when there is nothing to fail over to: no
41
+ * candidate-aware `ModelService`, a chain of one (`.env` only), or a registry
42
+ * that threw. Undefined means "behave exactly as before failover existed".
43
+ */
44
+ private failCurrentEmbedderCandidate;
24
45
  vectoriseText(params: {
25
46
  text: string;
26
47
  attribution?: EmbedderAttribution;
@@ -1 +1 @@
1
- {"version":3,"file":"embedder.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,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,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD,qBACa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAIX,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACL,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAThF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;gBAGxC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAI9B,iBAAiB,CAAC,EAAE,iBAAiB,EACP,kBAAkB,CAAC,EAAE,2BAA2B;IAGvG,aAAa,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,mBAAmB,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAWxF,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IA2B5F;;;;;OAKG;YACW,YAAY;IAO1B;;;;OAIG;YACW,WAAW;IAMzB,OAAO,CAAC,kBAAkB;IAW1B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAuB1B,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAYhB,0FAA0F;IAC1F,OAAO,CAAC,SAAS,CAA8B;IAE/C;;;;;;;;;OASG;YACW,YAAY;IA4B1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;YACW,qBAAqB;IASnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;OAGG;IACH,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;CAsBpB"}
1
+ {"version":3,"file":"embedder.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,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,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAehE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD,qBACa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAIX,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACL,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAThF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;gBAGxC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAI9B,iBAAiB,CAAC,EAAE,iBAAiB,EACP,kBAAkB,CAAC,EAAE,2BAA2B;IAG7G;;;;;;;;;;;;OAYG;YACW,qBAAqB;IAgBnC;;;;;OAKG;IACH,OAAO,CAAC,4BAA4B;IAc9B,aAAa,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,mBAAmB,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAWxF,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IA6B5F;;;;;OAKG;YACW,YAAY;IAO1B;;;;OAIG;YACW,WAAW;IAOzB,OAAO,CAAC,kBAAkB;IAW1B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAuB1B,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAYhB,0FAA0F;IAC1F,OAAO,CAAC,SAAS,CAA8B;IAE/C;;;;;;;;;OASG;YACW,YAAY;IA4B1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;YACW,qBAAqB;IASnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;OAGG;IACH,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;CAsBpB"}
@@ -21,6 +21,7 @@ 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
+ const llm_service_1 = require("./llm.service");
24
25
  /**
25
26
  * Ceiling for ONE embedding input. The provider hard cap is 8192 tokens
26
27
  * (`400 Invalid 'input[0]': maximum input length is 8192 tokens` from
@@ -39,6 +40,54 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
39
40
  this.tokenUsageRecorder = tokenUsageRecorder;
40
41
  this.logger = new common_1.Logger(EmbedderService_1.name);
41
42
  }
43
+ /**
44
+ * Runs ONE embedding invocation, with a single failover retry on a transient
45
+ * provider failure (429/5xx/socket-level — classified by exactly the rule
46
+ * `LLMService` uses).
47
+ *
48
+ * ONE retry only, and only when there is somewhere to go: the failed
49
+ * connection is put into cooldown and the embedder is rebuilt, so
50
+ * `getEmbedder()` resolves the NEXT healthy link of the chain. A chain of one
51
+ * (no DB-backed embedder connection — just the `.env` block) has nowhere to
52
+ * fail over to, so the rejection propagates immediately, exactly as it does
53
+ * today. Everything beyond that single re-resolution belongs to the BullMQ
54
+ * job retry that owns these calls (spec § 2, "Other modalities").
55
+ */
56
+ async withCandidateFailover(work) {
57
+ try {
58
+ return await work(this.modelService.getEmbedder());
59
+ }
60
+ catch (error) {
61
+ if (!(0, llm_service_1.isTransientNetworkError)(error))
62
+ throw error;
63
+ const failed = this.failCurrentEmbedderCandidate();
64
+ if (!failed)
65
+ throw error;
66
+ this.logger.warn(`Embedder connection ${failed.connectionId} failed transiently — retrying once on the next candidate: ${String(error)}`);
67
+ return work(this.modelService.getEmbedder());
68
+ }
69
+ }
70
+ /**
71
+ * Puts the embedder connection currently in service into its cooldown window
72
+ * and returns it — or undefined when there is nothing to fail over to: no
73
+ * candidate-aware `ModelService`, a chain of one (`.env` only), or a registry
74
+ * that threw. Undefined means "behave exactly as before failover existed".
75
+ */
76
+ failCurrentEmbedderCandidate() {
77
+ const resolver = this.modelService;
78
+ if (typeof resolver.getCandidatesForType !== "function" || typeof resolver.notifyCandidateFailure !== "function")
79
+ return undefined;
80
+ try {
81
+ const candidates = resolver.getCandidatesForType("embedder") ?? [];
82
+ if (candidates.length < 2)
83
+ return undefined;
84
+ resolver.notifyCandidateFailure(candidates[0]);
85
+ return candidates[0];
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ }
42
91
  async vectoriseText(params) {
43
92
  try {
44
93
  const result = await this.embedGuarded(params.text, params.attribution);
@@ -60,7 +109,7 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
60
109
  // The texts that fit still travel as ONE provider batch, in input order —
61
110
  // batching is why vectoriseTextBatch exists (chunk.repository.ts:405).
62
111
  if (withinBudget.length > 0) {
63
- const vectors = await this.modelService.getEmbedder().embedDocuments(withinBudget.map((index) => texts[index]));
112
+ const vectors = await this.withCandidateFailover((embedder) => embedder.embedDocuments(withinBudget.map((index) => texts[index])));
64
113
  withinBudget.forEach((index, position) => (result[index] = vectors[position]));
65
114
  }
66
115
  for (const index of oversized) {
@@ -84,7 +133,7 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
84
133
  async embedGuarded(text, attribution) {
85
134
  const slices = this.splitByTokenBudget(text);
86
135
  if (slices.length === 1)
87
- return this.modelService.getEmbedder().embedQuery(text);
136
+ return this.withCandidateFailover((embedder) => embedder.embedQuery(text));
88
137
  this.warnOversizedInput(text, slices.length, attribution);
89
138
  return this.meanPool(await this.embedSlices(slices));
90
139
  }
@@ -96,7 +145,7 @@ let EmbedderService = EmbedderService_1 = class EmbedderService {
96
145
  async embedSlices(slices) {
97
146
  const vectors = [];
98
147
  for (const slice of slices)
99
- vectors.push(await this.modelService.getEmbedder().embedQuery(slice));
148
+ vectors.push(await this.withCandidateFailover((embedder) => embedder.embedQuery(slice)));
100
149
  return vectors;
101
150
  }
102
151
  warnOversizedInput(text, sliceCount, attribution) {
@@ -1 +1 @@
1
- {"version":3,"file":"embedder.service.js","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embedder.service.js","sourceRoot":"","sources":["../../../../src/core/llm/services/embedder.service.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,30 @@ export { injectOpenRouterProvider } from "./openrouter-fetch";
19
19
  * name and message because the concrete class differs per transport.
20
20
  */
21
21
  export declare function isTimeoutError(error: unknown): boolean;
22
+ /**
23
+ * True for a failure that means the request never reached a working provider,
24
+ * and is therefore worth another attempt: a DNS/socket-level error code, an
25
+ * HTTP 429 or 5xx, or the message text either of those arrives as.
26
+ *
27
+ * All three are checked because the same failure wears different clothes per
28
+ * transport: undici puts the code on `error.cause.code` behind a bare
29
+ * `TypeError: fetch failed`, the OpenAI SDK puts the status on the error and
30
+ * the code in the message, and LangChain re-wraps both in a plain `Error`.
31
+ *
32
+ * Deliberately NOT transient: a stall that burned its whole deadline
33
+ * ({@link LLMTimeoutError}), a refusal (402/403), a malformed request (400) or
34
+ * a parse failure. Those either already had their retry (`call()` re-issues a
35
+ * timed-out attempt once, escalating the OpenRouter pin) or will fail
36
+ * identically forever. The 429 vocabulary matches the one
37
+ * `VisionLLMService.isRateLimitError` retries on, so the two agree on what a
38
+ * rate limit looks like.
39
+ *
40
+ * Exported as a standalone function (with {@link LLMService} keeping a private
41
+ * method that delegates to it) so the other modality services — which have no
42
+ * `LLMService` dependency and must not grow one — classify a failure by exactly
43
+ * the same rule before failing a connection over to the next candidate.
44
+ */
45
+ export declare function isTransientNetworkError(err: unknown): boolean;
22
46
  /**
23
47
  * Thrown when a provider call burns its whole deadline without settling.
24
48
  * Distinguishable from a provider error so callers can treat a stall
@@ -126,24 +150,41 @@ export declare class LLMService {
126
150
  */
127
151
  private runBounded;
128
152
  /**
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.
153
+ * See the module-level {@link isTransientNetworkError} for the classification
154
+ * rule and why it lives outside the class. Kept as a method because it is part
155
+ * of this service's shape (spec harnesses stub and assert on it) the
156
+ * unqualified call below resolves to the module function, not to itself.
145
157
  */
146
158
  private isTransientNetworkError;
159
+ /**
160
+ * Ordered failover candidates for a chat tier, newest health state applied.
161
+ *
162
+ * EMPTY means "no candidate machinery available" (a `ModelService` double
163
+ * without `getCandidates`, or a resolution failure) — every caller then
164
+ * behaves exactly as it did before failover existed. A resolution failure is
165
+ * logged and swallowed rather than thrown: losing the chain must degrade to
166
+ * the configured tier, never break the call.
167
+ */
168
+ private resolveCandidates;
169
+ /**
170
+ * Puts the candidate that just failed transiently into its cooldown window, so
171
+ * the next resolution skips it. Best-effort in every direction: no candidate,
172
+ * no candidate-aware `ModelService`, or a throwing registry all leave the call
173
+ * itself untouched — bookkeeping must never turn a retryable failure into a
174
+ * hard one.
175
+ */
176
+ private markCandidateFailure;
177
+ /**
178
+ * The cost rates to bill this call at, or undefined to keep the config-block
179
+ * rates.
180
+ *
181
+ * ONLY a DB-backed connection supplies rates: an `.env` candidate is the very
182
+ * config block `computeCost` already reads, so passing its numbers back in
183
+ * would be a no-op at best and a rounding difference at worst. A DB connection
184
+ * that prices nothing also returns undefined, so it bills at the tier rate
185
+ * instead of silently costing zero.
186
+ */
187
+ private ratesForCandidate;
147
188
  /**
148
189
  * Sleeps the jittered backoff for one transient retry and says so in the log.
149
190
  * ±20% jitter so a fleet of workers knocked out by the same DNS blip does not
@@ -153,13 +194,19 @@ export declare class LLMService {
153
194
  /**
154
195
  * Runs a provider call under {@link runBounded}, retrying it when — and only
155
196
  * 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.
197
+ * ({@link isTransientNetworkError}). Two extra attempts by default, with the
198
+ * long jittered waits {@link TRANSIENT_RETRY_WAITS_MS} explains.
158
199
  *
159
200
  * Owns a FRESH AbortController per attempt: a controller that has already
160
201
  * aborted stays aborted forever, so re-using one would make every retry abort
161
202
  * before it sent a byte. `work` therefore receives the signal rather than
162
203
  * capturing one from the caller.
204
+ *
205
+ * `work` also receives the ATTEMPT INDEX, which is what turns this retry into
206
+ * a failover: `call()` uses it to pick the n-th connection of the chain, so
207
+ * attempt 2 of a 429 storm talks to a different provider instead of knocking
208
+ * on the same closed door. Callers that pass no `options` keep today's budget
209
+ * (three attempts, the two configured waits) exactly.
163
210
  */
164
211
  private runWithTransientRetry;
165
212
  /**