@juspay/neurolink 9.23.0 → 9.25.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/CHANGELOG.md +12 -0
- package/README.md +10 -13
- package/dist/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/cli/commands/observability.d.ts +53 -0
- package/dist/cli/commands/observability.js +453 -0
- package/dist/cli/commands/telemetry.d.ts +63 -0
- package/dist/cli/commands/telemetry.js +689 -0
- package/dist/cli/factories/commandFactory.d.ts +34 -0
- package/dist/cli/factories/commandFactory.js +321 -116
- package/dist/cli/parser.js +6 -9
- package/dist/cli/utils/formatters.d.ts +13 -0
- package/dist/cli/utils/formatters.js +23 -0
- package/dist/constants/contextWindows.js +6 -0
- package/dist/constants/enums.d.ts +6 -0
- package/dist/constants/enums.js +8 -2
- package/dist/context/budgetChecker.js +75 -48
- package/dist/context/contextCompactor.js +135 -127
- package/dist/core/baseProvider.d.ts +5 -0
- package/dist/core/baseProvider.js +158 -102
- package/dist/core/conversationMemoryInitializer.js +7 -4
- package/dist/core/conversationMemoryManager.d.ts +2 -0
- package/dist/core/conversationMemoryManager.js +6 -2
- package/dist/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/core/modules/GenerationHandler.js +12 -12
- package/dist/evaluation/ragasEvaluator.js +39 -19
- package/dist/evaluation/scoring.js +46 -20
- package/dist/features/ppt/index.d.ts +1 -1
- package/dist/features/ppt/index.js +1 -1
- package/dist/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/features/ppt/slideGenerator.js +13 -0
- package/dist/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/features/ppt/slideRenderers.js +6 -4
- package/dist/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/features/ppt/slideTypeInference.js +75 -73
- package/dist/files/fileTools.d.ts +6 -6
- package/dist/index.d.ts +46 -12
- package/dist/index.js +79 -17
- package/dist/lib/adapters/tts/googleTTSHandler.js +26 -1
- package/dist/lib/adapters/video/vertexVideoHandler.js +23 -17
- package/dist/lib/constants/contextWindows.js +6 -0
- package/dist/lib/constants/enums.d.ts +6 -0
- package/dist/lib/constants/enums.js +8 -2
- package/dist/lib/context/budgetChecker.js +75 -48
- package/dist/lib/context/contextCompactor.js +135 -127
- package/dist/lib/core/baseProvider.d.ts +5 -0
- package/dist/lib/core/baseProvider.js +158 -102
- package/dist/lib/core/conversationMemoryInitializer.js +7 -4
- package/dist/lib/core/conversationMemoryManager.d.ts +2 -0
- package/dist/lib/core/conversationMemoryManager.js +6 -2
- package/dist/lib/core/modules/GenerationHandler.d.ts +2 -2
- package/dist/lib/core/modules/GenerationHandler.js +12 -12
- package/dist/lib/evaluation/ragasEvaluator.js +39 -19
- package/dist/lib/evaluation/scoring.js +46 -20
- package/dist/lib/features/ppt/index.d.ts +1 -1
- package/dist/lib/features/ppt/index.js +1 -1
- package/dist/lib/features/ppt/presentationOrchestrator.js +23 -0
- package/dist/lib/features/ppt/slideGenerator.js +13 -0
- package/dist/lib/features/ppt/slideRenderers.d.ts +1 -1
- package/dist/lib/features/ppt/slideRenderers.js +6 -4
- package/dist/lib/features/ppt/slideTypeInference.d.ts +1 -1
- package/dist/lib/features/ppt/slideTypeInference.js +75 -73
- package/dist/lib/files/fileTools.d.ts +6 -6
- package/dist/lib/index.d.ts +46 -12
- package/dist/lib/index.js +79 -17
- package/dist/lib/mcp/httpRateLimiter.js +39 -12
- package/dist/lib/mcp/httpRetryHandler.js +22 -1
- package/dist/lib/mcp/mcpClientFactory.js +13 -15
- package/dist/lib/memory/memoryRetrievalTools.js +22 -0
- package/dist/lib/neurolink.d.ts +64 -72
- package/dist/lib/neurolink.js +984 -566
- package/dist/lib/observability/exporterRegistry.d.ts +152 -0
- package/dist/lib/observability/exporterRegistry.js +414 -0
- package/dist/lib/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/arizeExporter.js +139 -0
- package/dist/lib/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/lib/observability/exporters/baseExporter.js +191 -0
- package/dist/lib/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/lib/observability/exporters/braintrustExporter.js +155 -0
- package/dist/lib/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/lib/observability/exporters/datadogExporter.js +197 -0
- package/dist/lib/observability/exporters/index.d.ts +13 -0
- package/dist/lib/observability/exporters/index.js +14 -0
- package/dist/lib/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/laminarExporter.js +303 -0
- package/dist/lib/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/lib/observability/exporters/langfuseExporter.js +200 -0
- package/dist/lib/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/lib/observability/exporters/langsmithExporter.js +124 -0
- package/dist/lib/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/lib/observability/exporters/otelExporter.js +165 -0
- package/dist/lib/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/lib/observability/exporters/posthogExporter.js +288 -0
- package/dist/lib/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/lib/observability/exporters/sentryExporter.js +166 -0
- package/dist/lib/observability/index.d.ts +25 -0
- package/dist/lib/observability/index.js +32 -0
- package/dist/lib/observability/metricsAggregator.d.ts +260 -0
- package/dist/lib/observability/metricsAggregator.js +553 -0
- package/dist/lib/observability/otelBridge.d.ts +49 -0
- package/dist/lib/observability/otelBridge.js +132 -0
- package/dist/lib/observability/retryPolicy.d.ts +192 -0
- package/dist/lib/observability/retryPolicy.js +384 -0
- package/dist/lib/observability/sampling/index.d.ts +4 -0
- package/dist/lib/observability/sampling/index.js +5 -0
- package/dist/lib/observability/sampling/samplers.d.ts +116 -0
- package/dist/lib/observability/sampling/samplers.js +217 -0
- package/dist/lib/observability/spanProcessor.d.ts +129 -0
- package/dist/lib/observability/spanProcessor.js +288 -0
- package/dist/lib/observability/tokenTracker.d.ts +156 -0
- package/dist/lib/observability/tokenTracker.js +414 -0
- package/dist/lib/observability/types/exporterTypes.d.ts +250 -0
- package/dist/lib/observability/types/exporterTypes.js +6 -0
- package/dist/lib/observability/types/index.d.ts +6 -0
- package/dist/lib/observability/types/index.js +5 -0
- package/dist/lib/observability/types/spanTypes.d.ts +244 -0
- package/dist/lib/observability/types/spanTypes.js +93 -0
- package/dist/lib/observability/utils/index.d.ts +4 -0
- package/dist/lib/observability/utils/index.js +5 -0
- package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/lib/observability/utils/spanSerializer.js +287 -0
- package/dist/lib/providers/amazonSagemaker.d.ts +5 -4
- package/dist/lib/providers/amazonSagemaker.js +3 -4
- package/dist/lib/providers/googleVertex.d.ts +7 -0
- package/dist/lib/providers/googleVertex.js +80 -2
- package/dist/lib/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/lib/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/lib/rag/ragIntegration.js +30 -0
- package/dist/lib/rag/retrieval/hybridSearch.js +22 -0
- package/dist/lib/server/abstract/baseServerAdapter.js +51 -19
- package/dist/lib/server/middleware/common.js +44 -12
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/lib/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/lib/types/cli.d.ts +18 -2
- package/dist/lib/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/lib/types/generateTypes.d.ts +2 -2
- package/dist/lib/types/modelTypes.d.ts +18 -18
- package/dist/lib/types/providers.d.ts +5 -0
- package/dist/lib/utils/pricing.js +25 -1
- package/dist/lib/utils/ttsProcessor.js +74 -59
- package/dist/lib/workflow/config.d.ts +36 -36
- package/dist/lib/workflow/core/ensembleExecutor.js +10 -0
- package/dist/lib/workflow/core/judgeScorer.js +20 -2
- package/dist/lib/workflow/core/workflowRunner.js +34 -1
- package/dist/mcp/httpRateLimiter.js +39 -12
- package/dist/mcp/httpRetryHandler.js +22 -1
- package/dist/mcp/mcpClientFactory.js +13 -15
- package/dist/memory/memoryRetrievalTools.js +22 -0
- package/dist/neurolink.d.ts +64 -72
- package/dist/neurolink.js +984 -566
- package/dist/observability/FEATURE-STATUS.md +269 -0
- package/dist/observability/exporterRegistry.d.ts +152 -0
- package/dist/observability/exporterRegistry.js +413 -0
- package/dist/observability/exporters/arizeExporter.d.ts +32 -0
- package/dist/observability/exporters/arizeExporter.js +138 -0
- package/dist/observability/exporters/baseExporter.d.ts +117 -0
- package/dist/observability/exporters/baseExporter.js +190 -0
- package/dist/observability/exporters/braintrustExporter.d.ts +30 -0
- package/dist/observability/exporters/braintrustExporter.js +154 -0
- package/dist/observability/exporters/datadogExporter.d.ts +37 -0
- package/dist/observability/exporters/datadogExporter.js +196 -0
- package/dist/observability/exporters/index.d.ts +13 -0
- package/dist/observability/exporters/index.js +13 -0
- package/dist/observability/exporters/laminarExporter.d.ts +48 -0
- package/dist/observability/exporters/laminarExporter.js +302 -0
- package/dist/observability/exporters/langfuseExporter.d.ts +47 -0
- package/dist/observability/exporters/langfuseExporter.js +199 -0
- package/dist/observability/exporters/langsmithExporter.d.ts +26 -0
- package/dist/observability/exporters/langsmithExporter.js +123 -0
- package/dist/observability/exporters/otelExporter.d.ts +39 -0
- package/dist/observability/exporters/otelExporter.js +164 -0
- package/dist/observability/exporters/posthogExporter.d.ts +48 -0
- package/dist/observability/exporters/posthogExporter.js +287 -0
- package/dist/observability/exporters/sentryExporter.d.ts +32 -0
- package/dist/observability/exporters/sentryExporter.js +165 -0
- package/dist/observability/index.d.ts +25 -0
- package/dist/observability/index.js +31 -0
- package/dist/observability/metricsAggregator.d.ts +260 -0
- package/dist/observability/metricsAggregator.js +552 -0
- package/dist/observability/otelBridge.d.ts +49 -0
- package/dist/observability/otelBridge.js +131 -0
- package/dist/observability/retryPolicy.d.ts +192 -0
- package/dist/observability/retryPolicy.js +383 -0
- package/dist/observability/sampling/index.d.ts +4 -0
- package/dist/observability/sampling/index.js +4 -0
- package/dist/observability/sampling/samplers.d.ts +116 -0
- package/dist/observability/sampling/samplers.js +216 -0
- package/dist/observability/spanProcessor.d.ts +129 -0
- package/dist/observability/spanProcessor.js +287 -0
- package/dist/observability/tokenTracker.d.ts +156 -0
- package/dist/observability/tokenTracker.js +413 -0
- package/dist/observability/types/exporterTypes.d.ts +250 -0
- package/dist/observability/types/exporterTypes.js +5 -0
- package/dist/observability/types/index.d.ts +6 -0
- package/dist/observability/types/index.js +4 -0
- package/dist/observability/types/spanTypes.d.ts +244 -0
- package/dist/observability/types/spanTypes.js +92 -0
- package/dist/observability/utils/index.d.ts +4 -0
- package/dist/observability/utils/index.js +4 -0
- package/dist/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/observability/utils/spanSerializer.js +286 -0
- package/dist/providers/amazonSagemaker.d.ts +5 -4
- package/dist/providers/amazonSagemaker.js +3 -4
- package/dist/providers/googleVertex.d.ts +7 -0
- package/dist/providers/googleVertex.js +80 -2
- package/dist/rag/pipeline/RAGPipeline.d.ts +0 -5
- package/dist/rag/pipeline/RAGPipeline.js +122 -87
- package/dist/rag/ragIntegration.js +30 -0
- package/dist/rag/retrieval/hybridSearch.js +22 -0
- package/dist/server/abstract/baseServerAdapter.js +51 -19
- package/dist/server/middleware/common.js +44 -12
- package/dist/services/server/ai/observability/instrumentation.d.ts +2 -2
- package/dist/services/server/ai/observability/instrumentation.js +10 -5
- package/dist/types/cli.d.ts +18 -2
- package/dist/types/conversationMemoryInterface.d.ts +2 -0
- package/dist/types/generateTypes.d.ts +2 -2
- package/dist/types/providers.d.ts +5 -0
- package/dist/utils/pricing.js +25 -1
- package/dist/utils/ttsProcessor.js +74 -59
- package/dist/workflow/config.d.ts +52 -52
- package/dist/workflow/core/ensembleExecutor.js +10 -0
- package/dist/workflow/core/judgeScorer.js +20 -2
- package/dist/workflow/core/workflowRunner.js +34 -1
- package/package.json +1 -1
|
@@ -33,12 +33,16 @@ import { InMemoryBM25Index, createHybridSearch, } from "../retrieval/hybridSearc
|
|
|
33
33
|
import { GraphRAG } from "../graphRag/graphRAG.js";
|
|
34
34
|
import { rerank } from "../reranker/reranker.js";
|
|
35
35
|
import { ProviderFactory } from "../../factories/providerFactory.js";
|
|
36
|
+
import { SpanSerializer, SpanType, SpanStatus, getMetricsAggregator, } from "../../observability/index.js";
|
|
36
37
|
import { logger } from "../../utils/logger.js";
|
|
38
|
+
import { withTimeout } from "../../utils/async/withTimeout.js";
|
|
37
39
|
/**
|
|
38
40
|
* RAG Pipeline Orchestrator
|
|
39
41
|
*
|
|
40
42
|
* Complete end-to-end pipeline for Retrieval-Augmented Generation.
|
|
41
43
|
*/
|
|
44
|
+
/** Default timeout for external provider calls (30 seconds) */
|
|
45
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
42
46
|
export class RAGPipeline {
|
|
43
47
|
id;
|
|
44
48
|
config;
|
|
@@ -195,96 +199,127 @@ export class RAGPipeline {
|
|
|
195
199
|
* @returns RAG response with retrieved context and optional generated answer
|
|
196
200
|
*/
|
|
197
201
|
async query(query, options) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
202
|
+
const span = SpanSerializer.createSpan(SpanType.RAG, "rag.pipeline", {
|
|
203
|
+
"rag.operation": "pipeline",
|
|
204
|
+
"rag.query": query.slice(0, 200),
|
|
205
|
+
"rag.topK": options?.topK ?? this.config.defaultTopK ?? 5,
|
|
206
|
+
"rag.hybrid": options?.hybrid ?? this.config.enableHybridSearch ?? false,
|
|
207
|
+
"rag.graph": options?.graph ?? this.config.enableGraphRAG ?? false,
|
|
208
|
+
"rag.rerank": options?.rerank ?? this.config.enableReranking ?? false,
|
|
209
|
+
});
|
|
210
|
+
const spanStartTime = Date.now();
|
|
211
|
+
try {
|
|
212
|
+
await this.ensureInitialized();
|
|
213
|
+
const startTime = Date.now();
|
|
214
|
+
const topK = options?.topK || this.config.defaultTopK || 5;
|
|
215
|
+
const useHybrid = options?.hybrid ?? this.config.enableHybridSearch;
|
|
216
|
+
const useGraph = options?.graph ?? this.config.enableGraphRAG;
|
|
217
|
+
const useRerank = options?.rerank ?? this.config.enableReranking;
|
|
218
|
+
let results;
|
|
219
|
+
let retrievalMethod = "vector";
|
|
220
|
+
// Generate query embedding
|
|
221
|
+
const queryEmbedding = await this.generateEmbedding(query);
|
|
222
|
+
if (useGraph && this.config.enableGraphRAG) {
|
|
223
|
+
// Graph RAG search
|
|
224
|
+
retrievalMethod = "graph";
|
|
225
|
+
const graphResults = this.graphRAG.query({
|
|
226
|
+
query: queryEmbedding,
|
|
227
|
+
topK: topK * 2, // Get more for potential reranking
|
|
228
|
+
});
|
|
229
|
+
results = graphResults.map((r) => ({
|
|
230
|
+
id: r.id,
|
|
231
|
+
text: r.content,
|
|
232
|
+
score: r.score,
|
|
233
|
+
metadata: r.metadata,
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
else if (useHybrid && this.hybridSearch) {
|
|
237
|
+
// Hybrid search
|
|
238
|
+
retrievalMethod = "hybrid";
|
|
239
|
+
const hybridResults = await this.hybridSearch(query, {
|
|
240
|
+
topK: topK * 2,
|
|
241
|
+
});
|
|
242
|
+
results = hybridResults.map((r) => ({
|
|
243
|
+
id: r.id,
|
|
244
|
+
text: r.text,
|
|
245
|
+
score: r.score,
|
|
246
|
+
metadata: r.metadata,
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
// Vector search
|
|
251
|
+
results = await this.vectorStore.query({
|
|
252
|
+
indexName: this.config.indexName ?? "default",
|
|
253
|
+
queryVector: queryEmbedding,
|
|
254
|
+
topK: topK * 2,
|
|
255
|
+
filter: options?.filter,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
// Apply reranking if enabled
|
|
259
|
+
let reranked = false;
|
|
260
|
+
if (useRerank && this.config.rerankingModel && results.length > 0) {
|
|
261
|
+
const rerankModel = await ProviderFactory.createProvider(this.config.rerankingModel.provider, this.config.rerankingModel.modelName);
|
|
262
|
+
const rerankedResults = await rerank(results, query, rerankModel, {
|
|
263
|
+
topK,
|
|
264
|
+
queryEmbedding,
|
|
265
|
+
});
|
|
266
|
+
results = rerankedResults.map((r) => r.result);
|
|
267
|
+
reranked = true;
|
|
268
|
+
}
|
|
269
|
+
// Take top K results
|
|
270
|
+
results = results.slice(0, topK);
|
|
271
|
+
// Assemble context
|
|
272
|
+
const context = this.assembleContext(results);
|
|
273
|
+
// Format sources
|
|
274
|
+
const sources = results.map((r) => ({
|
|
227
275
|
id: r.id,
|
|
228
|
-
text: r.text,
|
|
229
|
-
score: r.score,
|
|
276
|
+
text: r.text || r.metadata?.text || "",
|
|
277
|
+
score: r.score || 0,
|
|
230
278
|
metadata: r.metadata,
|
|
231
279
|
}));
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (useRerank && this.config.rerankingModel && results.length > 0) {
|
|
245
|
-
const rerankModel = await ProviderFactory.createProvider(this.config.rerankingModel.provider, this.config.rerankingModel.modelName);
|
|
246
|
-
const rerankedResults = await rerank(results, query, rerankModel, {
|
|
247
|
-
topK,
|
|
248
|
-
queryEmbedding,
|
|
280
|
+
// Generate answer if requested
|
|
281
|
+
let answer;
|
|
282
|
+
if (options?.generate !== false && this.generationProvider) {
|
|
283
|
+
answer = await this.generateAnswer(query, context, options?.systemPrompt, options?.temperature);
|
|
284
|
+
}
|
|
285
|
+
const queryTime = Date.now() - startTime;
|
|
286
|
+
logger.info("[RAGPipeline] Query completed", {
|
|
287
|
+
query: query.slice(0, 50),
|
|
288
|
+
retrievalMethod,
|
|
289
|
+
resultsCount: results.length,
|
|
290
|
+
reranked,
|
|
291
|
+
queryTime,
|
|
249
292
|
});
|
|
250
|
-
|
|
251
|
-
|
|
293
|
+
const response = {
|
|
294
|
+
answer,
|
|
295
|
+
context,
|
|
296
|
+
sources,
|
|
297
|
+
metadata: {
|
|
298
|
+
queryTime,
|
|
299
|
+
retrievalMethod,
|
|
300
|
+
chunksRetrieved: results.length,
|
|
301
|
+
reranked,
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
span.durationMs = Date.now() - spanStartTime;
|
|
305
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
306
|
+
endedSpan.attributes = {
|
|
307
|
+
...endedSpan.attributes,
|
|
308
|
+
"rag.retrieval_method": retrievalMethod,
|
|
309
|
+
"rag.results_count": results.length,
|
|
310
|
+
"rag.reranked": reranked,
|
|
311
|
+
};
|
|
312
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
313
|
+
return response;
|
|
252
314
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
text: r.text || r.metadata?.text || "",
|
|
261
|
-
score: r.score || 0,
|
|
262
|
-
metadata: r.metadata,
|
|
263
|
-
}));
|
|
264
|
-
// Generate answer if requested
|
|
265
|
-
let answer;
|
|
266
|
-
if (options?.generate !== false && this.generationProvider) {
|
|
267
|
-
answer = await this.generateAnswer(query, context, options?.systemPrompt, options?.temperature);
|
|
315
|
+
catch (error) {
|
|
316
|
+
span.durationMs = Date.now() - spanStartTime;
|
|
317
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
318
|
+
endedSpan.statusMessage =
|
|
319
|
+
error instanceof Error ? error.message : String(error);
|
|
320
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
321
|
+
throw error;
|
|
268
322
|
}
|
|
269
|
-
const queryTime = Date.now() - startTime;
|
|
270
|
-
logger.info("[RAGPipeline] Query completed", {
|
|
271
|
-
query: query.slice(0, 50),
|
|
272
|
-
retrievalMethod,
|
|
273
|
-
resultsCount: results.length,
|
|
274
|
-
reranked,
|
|
275
|
-
queryTime,
|
|
276
|
-
});
|
|
277
|
-
return {
|
|
278
|
-
answer,
|
|
279
|
-
context,
|
|
280
|
-
sources,
|
|
281
|
-
metadata: {
|
|
282
|
-
queryTime,
|
|
283
|
-
retrievalMethod,
|
|
284
|
-
chunksRetrieved: results.length,
|
|
285
|
-
reranked,
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
323
|
}
|
|
289
324
|
/**
|
|
290
325
|
* Get pipeline statistics
|
|
@@ -340,7 +375,7 @@ export class RAGPipeline {
|
|
|
340
375
|
.embed !== "function") {
|
|
341
376
|
throw new Error(`Provider ${this.config.embeddingModel.provider} does not support embeddings`);
|
|
342
377
|
}
|
|
343
|
-
return await this.embeddingProvider.embed(text);
|
|
378
|
+
return await withTimeout(this.embeddingProvider.embed(text), DEFAULT_TIMEOUT_MS, "Embedding generation timed out");
|
|
344
379
|
}
|
|
345
380
|
/**
|
|
346
381
|
* Assemble context from results
|
|
@@ -367,12 +402,12 @@ Use only the information from the context to answer the question.
|
|
|
367
402
|
If the context doesn't contain relevant information, say so.
|
|
368
403
|
Cite sources when possible using [Source N] format.`;
|
|
369
404
|
const prompt = `Context:\n${context}\n\nQuestion: ${query}\n\nAnswer:`;
|
|
370
|
-
const result = await this.generationProvider.generate({
|
|
405
|
+
const result = await withTimeout(this.generationProvider.generate({
|
|
371
406
|
prompt,
|
|
372
407
|
systemPrompt,
|
|
373
408
|
temperature: temperature ?? this.config.generationModel?.temperature ?? 0.7,
|
|
374
409
|
maxTokens: this.config.generationModel?.maxTokens ?? 1000,
|
|
375
|
-
});
|
|
410
|
+
}), DEFAULT_TIMEOUT_MS * 2, "Answer generation timed out");
|
|
376
411
|
return result?.content || "";
|
|
377
412
|
}
|
|
378
413
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { existsSync, readFileSync } from "fs";
|
|
10
10
|
import { extname, resolve } from "path";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
+
import { SpanSerializer, SpanType, SpanStatus, getMetricsAggregator, } from "../observability/index.js";
|
|
12
13
|
import { logger } from "../utils/logger.js";
|
|
13
14
|
import { createChunker } from "./ChunkerFactory.js";
|
|
14
15
|
import { createVectorQueryTool, InMemoryVectorStore, } from "./retrieval/vectorQueryTool.js";
|
|
@@ -149,6 +150,35 @@ function diversifyResults(results, topK) {
|
|
|
149
150
|
* @returns Prepared RAG tool to inject into the tools record
|
|
150
151
|
*/
|
|
151
152
|
export async function prepareRAGTool(ragConfig, fallbackProvider) {
|
|
153
|
+
const span = SpanSerializer.createSpan(SpanType.RAG, "rag.prepare", {
|
|
154
|
+
"rag.operation": "prepare",
|
|
155
|
+
"rag.files_count": ragConfig.files?.length ?? 0,
|
|
156
|
+
"rag.strategy": ragConfig.strategy ?? "auto",
|
|
157
|
+
"rag.chunk_size": ragConfig.chunkSize ?? 1000,
|
|
158
|
+
});
|
|
159
|
+
const startTime = Date.now();
|
|
160
|
+
try {
|
|
161
|
+
const result = await _prepareRAGToolInner(ragConfig, fallbackProvider);
|
|
162
|
+
span.durationMs = Date.now() - startTime;
|
|
163
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
164
|
+
endedSpan.attributes = {
|
|
165
|
+
...endedSpan.attributes,
|
|
166
|
+
"rag.chunks_indexed": result.chunksIndexed,
|
|
167
|
+
"rag.files_loaded": result.filesLoaded,
|
|
168
|
+
};
|
|
169
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
span.durationMs = Date.now() - startTime;
|
|
174
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
175
|
+
endedSpan.statusMessage =
|
|
176
|
+
error instanceof Error ? error.message : String(error);
|
|
177
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async function _prepareRAGToolInner(ragConfig, fallbackProvider) {
|
|
152
182
|
const { files, strategy: userStrategy, chunkSize = 1000, chunkOverlap = 200, topK: userTopK = 5, toolName = "search_knowledge_base", toolDescription = "REQUIRED: Search through pre-loaded local documents to find relevant information. Use this tool FIRST before any web search or other tools. This searches an indexed knowledge base of documents the user has provided.", embeddingProvider, embeddingModel, } = ragConfig;
|
|
153
183
|
if (!files || files.length === 0) {
|
|
154
184
|
throw new Error("RAG config requires at least one file path in 'files'");
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Supports multiple fusion methods: Reciprocal Rank Fusion (RRF) and Linear Combination.
|
|
6
6
|
*/
|
|
7
7
|
import { ProviderFactory } from "../../factories/providerFactory.js";
|
|
8
|
+
import { SpanSerializer, SpanType, SpanStatus, getMetricsAggregator, } from "../../observability/index.js";
|
|
8
9
|
import { logger } from "../../utils/logger.js";
|
|
9
10
|
import { rerank } from "../reranker/reranker.js";
|
|
10
11
|
/**
|
|
@@ -166,6 +167,13 @@ export function createHybridSearch(options) {
|
|
|
166
167
|
return async function hybridSearch(query, config) {
|
|
167
168
|
const startTime = Date.now();
|
|
168
169
|
const { vectorWeight = defaultConfig.vectorWeight ?? 0.5, bm25Weight = defaultConfig.bm25Weight ?? 0.5, fusionMethod = defaultConfig.fusionMethod ?? "rrf", rrfK = defaultConfig.rrfK ?? 60, topK = defaultConfig.topK ?? 10, enableReranking = defaultConfig.enableReranking ?? false, reranker: rerankerConfig = defaultConfig.reranker, } = config || {};
|
|
170
|
+
const span = SpanSerializer.createSpan(SpanType.RAG, "rag.search", {
|
|
171
|
+
"rag.operation": "search",
|
|
172
|
+
"rag.topK": topK,
|
|
173
|
+
"rag.fusionMethod": fusionMethod,
|
|
174
|
+
"rag.query": query.slice(0, 200),
|
|
175
|
+
});
|
|
176
|
+
const spanStartTime = Date.now();
|
|
169
177
|
try {
|
|
170
178
|
// Generate query embedding
|
|
171
179
|
const embeddingProvider = await ProviderFactory.createProvider(embeddingModel?.provider, embeddingModel?.modelName);
|
|
@@ -300,9 +308,23 @@ export function createHybridSearch(options) {
|
|
|
300
308
|
fusionMethod,
|
|
301
309
|
queryTime,
|
|
302
310
|
});
|
|
311
|
+
span.durationMs = Date.now() - spanStartTime;
|
|
312
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
313
|
+
endedSpan.attributes = {
|
|
314
|
+
...endedSpan.attributes,
|
|
315
|
+
"rag.results_count": fusedResults.length,
|
|
316
|
+
"rag.vector_results": vectorResults.length,
|
|
317
|
+
"rag.bm25_results": bm25Results.length,
|
|
318
|
+
};
|
|
319
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
303
320
|
return fusedResults;
|
|
304
321
|
}
|
|
305
322
|
catch (error) {
|
|
323
|
+
span.durationMs = Date.now() - spanStartTime;
|
|
324
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
325
|
+
endedSpan.statusMessage =
|
|
326
|
+
error instanceof Error ? error.message : String(error);
|
|
327
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
306
328
|
logger.error("[HybridSearch] Search failed", {
|
|
307
329
|
query: query.slice(0, 50),
|
|
308
330
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Follows NeuroLink's composition and factory patterns
|
|
5
5
|
*/
|
|
6
6
|
import { EventEmitter } from "events";
|
|
7
|
+
import { getMetricsAggregator } from "../../observability/index.js";
|
|
8
|
+
import { SpanSerializer, SpanStatus, SpanType, } from "../../observability/index.js";
|
|
7
9
|
import { withTimeout } from "../../utils/errorHandling.js";
|
|
8
10
|
import { logger } from "../../utils/logger.js";
|
|
9
11
|
import { DrainTimeoutError, InvalidLifecycleStateError, ShutdownTimeoutError, } from "../errors.js";
|
|
@@ -112,6 +114,12 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
112
114
|
host: this.config.host,
|
|
113
115
|
basePath: this.config.basePath,
|
|
114
116
|
});
|
|
117
|
+
const span = SpanSerializer.createSpan(SpanType.SERVER_REQUEST, "server.initialize", {
|
|
118
|
+
"server.operation": "initialize",
|
|
119
|
+
"server.port": this.config.port,
|
|
120
|
+
"server.host": this.config.host,
|
|
121
|
+
});
|
|
122
|
+
const startTime = Date.now();
|
|
115
123
|
try {
|
|
116
124
|
// Initialize framework-specific setup
|
|
117
125
|
this.initializeFramework();
|
|
@@ -129,9 +137,17 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
129
137
|
routes: this.routes.size,
|
|
130
138
|
middlewares: this.middlewares.length,
|
|
131
139
|
});
|
|
140
|
+
span.durationMs = Date.now() - startTime;
|
|
141
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
142
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
132
143
|
}
|
|
133
144
|
catch (error) {
|
|
134
145
|
this.lifecycleState = "error";
|
|
146
|
+
span.durationMs = Date.now() - startTime;
|
|
147
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
148
|
+
endedSpan.statusMessage =
|
|
149
|
+
error instanceof Error ? error.message : String(error);
|
|
150
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
135
151
|
throw error;
|
|
136
152
|
}
|
|
137
153
|
}
|
|
@@ -397,29 +413,34 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
397
413
|
gracefulShutdownTimeoutMs,
|
|
398
414
|
drainTimeoutMs,
|
|
399
415
|
});
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
// Create drain promise that resolves when all connections are closed
|
|
406
|
-
const drainPromise = this.drainConnections();
|
|
416
|
+
const shutdownSpan = SpanSerializer.createSpan(SpanType.SERVER_REQUEST, "server.shutdown", {
|
|
417
|
+
"server.operation": "gracefulShutdown",
|
|
418
|
+
"server.activeConnections": this.activeConnections.size,
|
|
419
|
+
});
|
|
420
|
+
const shutdownStartTime = Date.now();
|
|
407
421
|
// Timer references for cleanup
|
|
408
422
|
let shutdownTimer;
|
|
409
423
|
let drainTimer;
|
|
410
|
-
// Create timeout promise for overall shutdown
|
|
411
|
-
const shutdownTimeoutPromise = new Promise((_, reject) => {
|
|
412
|
-
shutdownTimer = setTimeout(() => {
|
|
413
|
-
reject(new ShutdownTimeoutError(gracefulShutdownTimeoutMs, this.activeConnections.size));
|
|
414
|
-
}, gracefulShutdownTimeoutMs);
|
|
415
|
-
});
|
|
416
|
-
// Create timeout promise for drain phase
|
|
417
|
-
const drainTimeoutPromise = new Promise((resolve) => {
|
|
418
|
-
drainTimer = setTimeout(() => {
|
|
419
|
-
resolve("drain_timeout");
|
|
420
|
-
}, drainTimeoutMs);
|
|
421
|
-
});
|
|
422
424
|
try {
|
|
425
|
+
// Set draining state
|
|
426
|
+
this.lifecycleState = "draining";
|
|
427
|
+
// Stop accepting new connections (covered by shutdown span)
|
|
428
|
+
await this.stopAcceptingConnections();
|
|
429
|
+
logger.info("[ServerAdapter] Stopped accepting new connections");
|
|
430
|
+
// Create drain promise that resolves when all connections are closed
|
|
431
|
+
const drainPromise = this.drainConnections();
|
|
432
|
+
// Create timeout promise for overall shutdown
|
|
433
|
+
const shutdownTimeoutPromise = new Promise((_, reject) => {
|
|
434
|
+
shutdownTimer = setTimeout(() => {
|
|
435
|
+
reject(new ShutdownTimeoutError(gracefulShutdownTimeoutMs, this.activeConnections.size));
|
|
436
|
+
}, gracefulShutdownTimeoutMs);
|
|
437
|
+
});
|
|
438
|
+
// Create timeout promise for drain phase
|
|
439
|
+
const drainTimeoutPromise = new Promise((resolve) => {
|
|
440
|
+
drainTimer = setTimeout(() => {
|
|
441
|
+
resolve("drain_timeout");
|
|
442
|
+
}, drainTimeoutMs);
|
|
443
|
+
});
|
|
423
444
|
// Race drain against drain timeout
|
|
424
445
|
const drainResult = await Promise.race([
|
|
425
446
|
drainPromise,
|
|
@@ -442,6 +463,9 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
442
463
|
// Close the server with shutdown timeout
|
|
443
464
|
await Promise.race([this.closeServer(), shutdownTimeoutPromise]);
|
|
444
465
|
logger.info("[ServerAdapter] Server closed successfully");
|
|
466
|
+
shutdownSpan.durationMs = Date.now() - shutdownStartTime;
|
|
467
|
+
const endedShutdownSpan = SpanSerializer.endSpan(shutdownSpan, SpanStatus.OK);
|
|
468
|
+
getMetricsAggregator().recordSpan(endedShutdownSpan);
|
|
445
469
|
}
|
|
446
470
|
catch (error) {
|
|
447
471
|
// If force close is enabled and we hit a timeout, try to force close
|
|
@@ -453,9 +477,17 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
453
477
|
});
|
|
454
478
|
await this.forceCloseConnections();
|
|
455
479
|
await this.closeServer();
|
|
480
|
+
shutdownSpan.durationMs = Date.now() - shutdownStartTime;
|
|
481
|
+
const endedShutdownSpan = SpanSerializer.endSpan(shutdownSpan, SpanStatus.OK);
|
|
482
|
+
getMetricsAggregator().recordSpan(endedShutdownSpan);
|
|
456
483
|
}
|
|
457
484
|
else {
|
|
458
485
|
this.lifecycleState = "error";
|
|
486
|
+
shutdownSpan.durationMs = Date.now() - shutdownStartTime;
|
|
487
|
+
const endedShutdownSpan = SpanSerializer.endSpan(shutdownSpan, SpanStatus.ERROR);
|
|
488
|
+
endedShutdownSpan.statusMessage =
|
|
489
|
+
error instanceof Error ? error.message : String(error);
|
|
490
|
+
getMetricsAggregator().recordSpan(endedShutdownSpan);
|
|
459
491
|
throw error;
|
|
460
492
|
}
|
|
461
493
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Common Middleware Components
|
|
3
3
|
* Utility middleware for common server operations
|
|
4
4
|
*/
|
|
5
|
+
import { getMetricsAggregator } from "../../observability/index.js";
|
|
6
|
+
import { SpanSerializer, SpanStatus, SpanType, } from "../../observability/index.js";
|
|
5
7
|
import { logger } from "../../utils/logger.js";
|
|
6
8
|
/**
|
|
7
9
|
* Create request timing middleware
|
|
@@ -21,17 +23,34 @@ export function createTimingMiddleware() {
|
|
|
21
23
|
const startHrTime = process.hrtime.bigint();
|
|
22
24
|
// Store start time in metadata
|
|
23
25
|
ctx.metadata.requestStartTime = startTime;
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
const span = SpanSerializer.createSpan(SpanType.SERVER_REQUEST, "server.middleware.timing", {
|
|
27
|
+
"server.operation": "middleware",
|
|
28
|
+
"server.middleware": "timing",
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
const result = await next();
|
|
32
|
+
// Calculate duration
|
|
33
|
+
const endHrTime = process.hrtime.bigint();
|
|
34
|
+
const durationNs = Number(endHrTime - startHrTime);
|
|
35
|
+
const durationMs = durationNs / 1_000_000;
|
|
36
|
+
// Add timing headers to responseHeaders (adapters read from here)
|
|
37
|
+
ctx.responseHeaders = ctx.responseHeaders || {};
|
|
38
|
+
ctx.responseHeaders["X-Response-Time"] = `${durationMs.toFixed(2)}ms`;
|
|
39
|
+
ctx.responseHeaders["Server-Timing"] =
|
|
40
|
+
`total;dur=${durationMs.toFixed(2)}`;
|
|
41
|
+
span.durationMs = Date.now() - startTime;
|
|
42
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
43
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
span.durationMs = Date.now() - startTime;
|
|
48
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
49
|
+
endedSpan.statusMessage =
|
|
50
|
+
error instanceof Error ? error.message : String(error);
|
|
51
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
35
54
|
},
|
|
36
55
|
};
|
|
37
56
|
}
|
|
@@ -77,8 +96,17 @@ export function createErrorHandlingMiddleware(options) {
|
|
|
77
96
|
name: "error-handling",
|
|
78
97
|
order: 1, // Run very early to catch all errors
|
|
79
98
|
handler: async (ctx, next) => {
|
|
99
|
+
const span = SpanSerializer.createSpan(SpanType.SERVER_REQUEST, "server.middleware.errorHandling", {
|
|
100
|
+
"server.operation": "middleware",
|
|
101
|
+
"server.middleware": "error-handling",
|
|
102
|
+
});
|
|
103
|
+
const middlewareStartTime = Date.now();
|
|
80
104
|
try {
|
|
81
|
-
|
|
105
|
+
const result = await next();
|
|
106
|
+
span.durationMs = Date.now() - middlewareStartTime;
|
|
107
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
108
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
109
|
+
return result;
|
|
82
110
|
}
|
|
83
111
|
catch (error) {
|
|
84
112
|
const err = error;
|
|
@@ -89,6 +117,10 @@ export function createErrorHandlingMiddleware(options) {
|
|
|
89
117
|
stack: err.stack,
|
|
90
118
|
});
|
|
91
119
|
}
|
|
120
|
+
span.durationMs = Date.now() - middlewareStartTime;
|
|
121
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
122
|
+
endedSpan.statusMessage = err.message;
|
|
123
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
92
124
|
// Use custom handler if provided
|
|
93
125
|
if (onError) {
|
|
94
126
|
return onError(err, ctx);
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Flow: Vercel AI SDK → OpenTelemetry Spans → LangfuseSpanProcessor → Langfuse Platform
|
|
8
8
|
*/
|
|
9
|
-
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
10
9
|
import { LangfuseSpanProcessor } from "@langfuse/otel";
|
|
11
|
-
import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
12
10
|
import { trace } from "@opentelemetry/api";
|
|
11
|
+
import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
12
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
13
13
|
import type { LangfuseConfig } from "../../../../types/observability.js";
|
|
14
14
|
/**
|
|
15
15
|
* Extended context for Langfuse spans
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Flow: Vercel AI SDK → OpenTelemetry Spans → LangfuseSpanProcessor → Langfuse Platform
|
|
8
8
|
*/
|
|
9
|
-
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
10
9
|
import { LangfuseSpanProcessor } from "@langfuse/otel";
|
|
11
|
-
import {
|
|
10
|
+
import { trace } from "@opentelemetry/api";
|
|
12
11
|
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
12
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
13
|
+
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semantic-conventions";
|
|
13
14
|
import { AsyncLocalStorage } from "async_hooks";
|
|
14
|
-
import { trace } from "@opentelemetry/api";
|
|
15
15
|
import { logger } from "../../../../utils/logger.js";
|
|
16
16
|
const LOG_PREFIX = "[OpenTelemetry]";
|
|
17
17
|
const contextStorage = new AsyncLocalStorage();
|
|
@@ -343,11 +343,16 @@ class ContextEnricher {
|
|
|
343
343
|
* @param config - Langfuse configuration passed from parent application
|
|
344
344
|
*/
|
|
345
345
|
export function initializeOpenTelemetry(config) {
|
|
346
|
-
// Guard against multiple initializations
|
|
346
|
+
// Guard against multiple initializations — but always update config
|
|
347
|
+
// so that later NeuroLink instances can change traceNameFormat,
|
|
348
|
+
// autoDetectOperationName, and other configuration preferences
|
|
349
|
+
// without re-initializing the OTEL infrastructure.
|
|
347
350
|
if (isInitialized) {
|
|
348
|
-
|
|
351
|
+
currentConfig = config;
|
|
352
|
+
logger.debug(`${LOG_PREFIX} Already initialized, config updated`, {
|
|
349
353
|
usingExternalProvider,
|
|
350
354
|
hasLangfuseProcessor: !!langfuseProcessor,
|
|
355
|
+
hasTraceNameFormat: typeof config.traceNameFormat === "function",
|
|
351
356
|
});
|
|
352
357
|
return;
|
|
353
358
|
}
|
package/dist/lib/types/cli.d.ts
CHANGED
|
@@ -68,8 +68,8 @@ export type GenerateCommandArgs = BaseCommandArgs & {
|
|
|
68
68
|
thinkingLevel?: "minimal" | "low" | "medium" | "high";
|
|
69
69
|
/** Vertex AI region */
|
|
70
70
|
region?: string;
|
|
71
|
-
/** Output mode - 'text' for standard generation, 'video' for video generation */
|
|
72
|
-
outputMode?: "text" | "video";
|
|
71
|
+
/** Output mode - 'text' for standard generation, 'video' for video generation, 'ppt' for presentation */
|
|
72
|
+
outputMode?: "text" | "video" | "ppt";
|
|
73
73
|
/** Path to save generated video file */
|
|
74
74
|
videoOutput?: string;
|
|
75
75
|
/** Video output resolution (720p or 1080p) */
|
|
@@ -80,6 +80,20 @@ export type GenerateCommandArgs = BaseCommandArgs & {
|
|
|
80
80
|
videoAspectRatio?: "9:16" | "16:9";
|
|
81
81
|
/** Enable/disable audio generation in video */
|
|
82
82
|
videoAudio?: boolean;
|
|
83
|
+
/** Number of slides to generate (5-50) */
|
|
84
|
+
pptPages?: number;
|
|
85
|
+
/** Presentation theme/style */
|
|
86
|
+
pptTheme?: "modern" | "corporate" | "creative" | "minimal" | "dark";
|
|
87
|
+
/** Target audience */
|
|
88
|
+
pptAudience?: "business" | "students" | "technical" | "general";
|
|
89
|
+
/** Presentation tone/style */
|
|
90
|
+
pptTone?: "professional" | "casual" | "educational" | "persuasive";
|
|
91
|
+
/** Path to save generated PPTX file */
|
|
92
|
+
pptOutput?: string;
|
|
93
|
+
/** PPT aspect ratio */
|
|
94
|
+
pptAspectRatio?: "16:9" | "4:3";
|
|
95
|
+
/** Disable AI image generation for PPT slides */
|
|
96
|
+
pptNoImages?: boolean;
|
|
83
97
|
/** Custom path for generated image output */
|
|
84
98
|
imageOutput?: string;
|
|
85
99
|
};
|
|
@@ -371,6 +385,8 @@ export type GenerateResult = CommandResult & {
|
|
|
371
385
|
audio?: import("./index.js").TTSResult;
|
|
372
386
|
/** Video generation result when video mode is enabled */
|
|
373
387
|
video?: import("./multimodal.js").VideoGenerationResult;
|
|
388
|
+
/** PPT generation result when ppt mode is enabled */
|
|
389
|
+
ppt?: import("./pptTypes.js").PPTGenerationResult;
|
|
374
390
|
imageOutput?: {
|
|
375
391
|
base64: string;
|
|
376
392
|
savedPath?: string;
|
|
@@ -28,4 +28,6 @@ export type IConversationMemoryManager = {
|
|
|
28
28
|
getSessionMessages(sessionId: string, userId?: string): Promise<ChatMessage[]>;
|
|
29
29
|
/** Replace the entire messages array for a session */
|
|
30
30
|
setSessionMessages(sessionId: string, messages: ChatMessage[], userId?: string): Promise<void>;
|
|
31
|
+
/** Close/shutdown the memory manager and release resources (e.g., Redis connections) */
|
|
32
|
+
close?(): Promise<void>;
|
|
31
33
|
};
|