@juspay/neurolink 9.24.0 → 9.25.1
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/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.js +29 -15
- 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 +117 -110
- 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/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 +117 -110
- 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/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 +1007 -564
- 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 +204 -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 +557 -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 +304 -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/safeMetadata.d.ts +10 -0
- package/dist/lib/observability/utils/safeMetadata.js +26 -0
- package/dist/lib/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/lib/observability/utils/spanSerializer.js +291 -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 +76 -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/conversationMemoryInterface.d.ts +2 -0
- 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 +1007 -564
- 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 +203 -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 +556 -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 +303 -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/safeMetadata.d.ts +10 -0
- package/dist/observability/utils/safeMetadata.js +25 -0
- package/dist/observability/utils/spanSerializer.d.ts +115 -0
- package/dist/observability/utils/spanSerializer.js +290 -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 +76 -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/conversationMemoryInterface.d.ts +2 -0
- 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
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Conversation Memory Initializer
|
|
3
3
|
* Provides integration with Redis storage for conversation memory
|
|
4
4
|
*/
|
|
5
|
-
import { createConversationMemoryManager, getStorageType, getRedisConfigFromEnv, } from "./conversationMemoryFactory.js";
|
|
6
5
|
import { applyConversationMemoryDefaults } from "../utils/conversationMemory.js";
|
|
7
6
|
import { logger } from "../utils/logger.js";
|
|
7
|
+
import { createConversationMemoryManager, getRedisConfigFromEnv, getStorageType, } from "./conversationMemoryFactory.js";
|
|
8
8
|
/**
|
|
9
9
|
* Initialize conversation memory for NeuroLink
|
|
10
10
|
* This function decides whether to use in-memory or Redis storage
|
|
@@ -30,11 +30,14 @@ export async function initializeConversationMemory(config) {
|
|
|
30
30
|
maxTurnsPerSession: memoryConfig.maxTurnsPerSession,
|
|
31
31
|
enableSummarization: memoryConfig.enableSummarization,
|
|
32
32
|
});
|
|
33
|
-
// Determine storage type
|
|
34
|
-
|
|
33
|
+
// Determine storage type: if redisConfig is passed in the SDK config, use Redis
|
|
34
|
+
// regardless of STORAGE_TYPE env var. This lets consumers configure Redis via the API.
|
|
35
|
+
const hasRedisConfig = !!config.conversationMemory?.redisConfig;
|
|
36
|
+
const storageType = hasRedisConfig ? "redis" : getStorageType();
|
|
35
37
|
logger.debug("[conversationMemoryInitializer] Storage type determined", {
|
|
36
38
|
storageType,
|
|
37
|
-
|
|
39
|
+
fromConfig: hasRedisConfig,
|
|
40
|
+
fromEnv: !hasRedisConfig && !!process.env.STORAGE_TYPE,
|
|
38
41
|
});
|
|
39
42
|
if (storageType === "redis") {
|
|
40
43
|
logger.info("[conversationMemoryInitializer] Initializing Redis-based conversation memory manager");
|
|
@@ -71,4 +71,6 @@ export declare class ConversationMemoryManager implements IConversationMemoryMan
|
|
|
71
71
|
* Resets summary pointers since old pointers may reference messages that no longer exist.
|
|
72
72
|
*/
|
|
73
73
|
setSessionMessages(sessionId: string, messages: ChatMessage[], userId?: string): Promise<void>;
|
|
74
|
+
/** Close/shutdown — no-op for in-memory manager (no external connections to release) */
|
|
75
|
+
close(): Promise<void>;
|
|
74
76
|
}
|
|
@@ -6,11 +6,11 @@ import { randomUUID } from "crypto";
|
|
|
6
6
|
import { DEFAULT_MAX_SESSIONS, MEMORY_THRESHOLD_PERCENTAGE, MESSAGES_PER_TURN, } from "../config/conversationMemory.js";
|
|
7
7
|
import { TokenUtils } from "../constants/tokens.js";
|
|
8
8
|
import { SummarizationEngine } from "../context/summarizationEngine.js";
|
|
9
|
+
import { runWithCurrentLangfuseContext } from "../services/server/ai/observability/instrumentation.js";
|
|
10
|
+
import { tracers, withSpan } from "../telemetry/index.js";
|
|
9
11
|
import { ConversationMemoryError } from "../types/conversation.js";
|
|
10
12
|
import { buildContextFromPointer, getEffectiveTokenThreshold, } from "../utils/conversationMemory.js";
|
|
11
|
-
import { runWithCurrentLangfuseContext } from "../services/server/ai/observability/instrumentation.js";
|
|
12
13
|
import { logger } from "../utils/logger.js";
|
|
13
|
-
import { tracers, withSpan } from "../telemetry/index.js";
|
|
14
14
|
export class ConversationMemoryManager {
|
|
15
15
|
sessions = new Map();
|
|
16
16
|
config;
|
|
@@ -337,5 +337,9 @@ export class ConversationMemoryManager {
|
|
|
337
337
|
session.lastCountedAt = undefined;
|
|
338
338
|
session.lastActivity = Date.now();
|
|
339
339
|
}
|
|
340
|
+
/** Close/shutdown — no-op for in-memory manager (no external connections to release) */
|
|
341
|
+
async close() {
|
|
342
|
+
// In-memory manager has nothing to close
|
|
343
|
+
}
|
|
340
344
|
}
|
|
341
345
|
//# sourceMappingURL=conversationMemoryManager.js.map
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @module core/modules/GenerationHandler
|
|
14
14
|
*/
|
|
15
|
-
import type {
|
|
15
|
+
import type { CoreMessage, LanguageModelV1, Tool } from "ai";
|
|
16
16
|
import { generateText } from "ai";
|
|
17
|
-
import type {
|
|
17
|
+
import type { AIProviderName, EnhancedGenerateResult, StandardRecord, TextGenerationOptions } from "../../types/index.js";
|
|
18
18
|
/**
|
|
19
19
|
* GenerationHandler class - Handles text generation operations for AI providers
|
|
20
20
|
*/
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @module core/modules/GenerationHandler
|
|
14
14
|
*/
|
|
15
|
-
import { generateText, Output, NoObjectGeneratedError } from "ai";
|
|
16
15
|
import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
|
|
16
|
+
import { generateText, NoObjectGeneratedError, Output } from "ai";
|
|
17
17
|
import { tracers } from "../../telemetry/tracers.js";
|
|
18
18
|
import { logger } from "../../utils/logger.js";
|
|
19
|
-
import { extractTokenUsage, extractCacheCreationTokens, extractCacheReadTokens, calculateCacheSavingsPercent, } from "../../utils/tokenUtils.js";
|
|
20
|
-
import { withProviderRetry } from "../../utils/providerRetry.js";
|
|
21
19
|
import { calculateCost } from "../../utils/pricing.js";
|
|
20
|
+
import { withProviderRetry } from "../../utils/providerRetry.js";
|
|
21
|
+
import { calculateCacheSavingsPercent, extractCacheCreationTokens, extractCacheReadTokens, extractTokenUsage, } from "../../utils/tokenUtils.js";
|
|
22
22
|
import { DEFAULT_MAX_STEPS } from "../constants.js";
|
|
23
23
|
const genTracer = tracers.generation;
|
|
24
24
|
/**
|
|
@@ -67,8 +67,8 @@ export class GenerationHandler {
|
|
|
67
67
|
// Gemini 2.5 and earlier cannot use tools + structured JSON output simultaneously.
|
|
68
68
|
// When both are requested on a Google provider, disable structured output (tools take priority).
|
|
69
69
|
const wantsStructuredOutput = includeStructuredOutput &&
|
|
70
|
-
!!options.schema
|
|
71
|
-
|
|
70
|
+
(!!options.schema ||
|
|
71
|
+
options.output?.format === "json" ||
|
|
72
72
|
options.output?.format === "structured");
|
|
73
73
|
const useStructuredOutput = wantsStructuredOutput &&
|
|
74
74
|
!(isGoogleProvider && shouldUseTools && Object.keys(tools).length > 0);
|
|
@@ -166,9 +166,9 @@ export class GenerationHandler {
|
|
|
166
166
|
return genTracer.startActiveSpan("neurolink.executeGeneration", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
167
167
|
const shouldUseTools = !options.disableTools && this.supportsToolsFn();
|
|
168
168
|
const toolCount = Object.keys(tools || {}).length;
|
|
169
|
-
const useStructuredOutput = !!options.schema
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
const useStructuredOutput = !!options.schema ||
|
|
170
|
+
options.output?.format === "json" ||
|
|
171
|
+
options.output?.format === "structured";
|
|
172
172
|
span.setAttribute("gen_ai.system", this.providerName || "unknown");
|
|
173
173
|
span.setAttribute("neurolink.structured_output", useStructuredOutput);
|
|
174
174
|
span.setAttribute("neurolink.tool_count", toolCount);
|
|
@@ -452,10 +452,10 @@ export class GenerationHandler {
|
|
|
452
452
|
* Format the enhanced result
|
|
453
453
|
*/
|
|
454
454
|
formatEnhancedResult(generateResult, tools, toolsUsed, toolExecutions, options) {
|
|
455
|
-
// Structured output check
|
|
456
|
-
const useStructuredOutput = !!options.schema
|
|
457
|
-
|
|
458
|
-
|
|
455
|
+
// Structured output check — schema alone is sufficient to activate
|
|
456
|
+
const useStructuredOutput = !!options.schema ||
|
|
457
|
+
options.output?.format === "json" ||
|
|
458
|
+
options.output?.format === "structured";
|
|
459
459
|
let content;
|
|
460
460
|
if (useStructuredOutput) {
|
|
461
461
|
try {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AIProviderFactory } from "../core/factory.js";
|
|
2
2
|
import { PromptBuilder } from "./prompts.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
|
|
5
|
+
import { getMetricsAggregator } from "../observability/index.js";
|
|
4
6
|
/**
|
|
5
7
|
* Implements a RAGAS-style evaluator that uses a "judge" LLM to score the
|
|
6
8
|
* quality of an AI response based on rich, contextual information.
|
|
@@ -32,27 +34,45 @@ export class RAGASEvaluator {
|
|
|
32
34
|
* @returns A promise that resolves to a detailed `EvaluationResult`.
|
|
33
35
|
*/
|
|
34
36
|
async evaluate(context) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
input: { text: prompt },
|
|
37
|
+
const span = SpanSerializer.createSpan(SpanType.EVALUATION, "evaluation.ragas", {
|
|
38
|
+
"evaluation.dimension": "relevance|accuracy|completeness",
|
|
39
|
+
"ai.provider": this.providerName,
|
|
40
|
+
"ai.model": this.evaluationModel,
|
|
40
41
|
});
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
const startTime = Date.now();
|
|
43
|
+
try {
|
|
44
|
+
const prompt = this.promptBuilder.buildEvaluationPrompt(context, this.promptGenerator);
|
|
45
|
+
const provider = await AIProviderFactory.createProvider(this.providerName, this.evaluationModel);
|
|
46
|
+
const result = await provider.generate({
|
|
47
|
+
input: { text: prompt },
|
|
48
|
+
});
|
|
49
|
+
if (!result) {
|
|
50
|
+
throw new Error("Evaluation generation failed to return a result.");
|
|
51
|
+
}
|
|
52
|
+
const rawEvaluationResponse = result.content;
|
|
53
|
+
const parsedResult = this.parseEvaluationResponse(rawEvaluationResponse);
|
|
54
|
+
const evaluationTime = Date.now() - startTime;
|
|
55
|
+
const finalResult = {
|
|
56
|
+
...parsedResult,
|
|
57
|
+
isPassing: parsedResult.finalScore >= this.threshold, // This will be recalculated, but is needed for the type
|
|
58
|
+
evaluationModel: this.evaluationModel,
|
|
59
|
+
evaluationTime,
|
|
60
|
+
attemptNumber: context.attemptNumber,
|
|
61
|
+
rawEvaluationResponse,
|
|
62
|
+
};
|
|
63
|
+
span.durationMs = Date.now() - startTime;
|
|
64
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
65
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
66
|
+
return finalResult;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
span.durationMs = Date.now() - startTime;
|
|
70
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
71
|
+
endedSpan.statusMessage =
|
|
72
|
+
error instanceof Error ? error.message : String(error);
|
|
73
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
74
|
+
throw error;
|
|
43
75
|
}
|
|
44
|
-
const rawEvaluationResponse = result.content;
|
|
45
|
-
const parsedResult = this.parseEvaluationResponse(rawEvaluationResponse);
|
|
46
|
-
const evaluationTime = Date.now() - startTime;
|
|
47
|
-
const finalResult = {
|
|
48
|
-
...parsedResult,
|
|
49
|
-
isPassing: parsedResult.finalScore >= this.threshold, // This will be recalculated, but is needed for the type
|
|
50
|
-
evaluationModel: this.evaluationModel,
|
|
51
|
-
evaluationTime,
|
|
52
|
-
attemptNumber: context.attemptNumber,
|
|
53
|
-
rawEvaluationResponse,
|
|
54
|
-
};
|
|
55
|
-
return finalResult;
|
|
56
76
|
}
|
|
57
77
|
/**
|
|
58
78
|
* Parses the raw JSON string from the judge LLM into a structured `EvaluationResult` object.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Contains the logic for mapping raw evaluation results to the structured EvaluationData type.
|
|
3
3
|
*/
|
|
4
|
+
import { SpanSerializer, SpanType, SpanStatus, } from "../observability/index.js";
|
|
5
|
+
import { getMetricsAggregator } from "../observability/index.js";
|
|
4
6
|
/**
|
|
5
7
|
* Maps a raw `EvaluationResult` to the structured `EvaluationData` format.
|
|
6
8
|
* This includes calculating derived fields like `isOffTopic` and `alertSeverity`.
|
|
@@ -12,25 +14,49 @@
|
|
|
12
14
|
* @returns A structured `EvaluationData` object.
|
|
13
15
|
*/
|
|
14
16
|
export function mapToEvaluationData(evalContext, result, threshold, offTopicThreshold = 5, highSeverityThreshold = 4) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
const span = SpanSerializer.createSpan(SpanType.EVALUATION, "evaluation.score", {
|
|
18
|
+
"evaluation.dimension": "relevance|accuracy|completeness|overall",
|
|
19
|
+
scores: {
|
|
20
|
+
relevance: result.relevanceScore,
|
|
21
|
+
accuracy: result.accuracyScore,
|
|
22
|
+
completeness: result.completenessScore,
|
|
23
|
+
overall: result.finalScore,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
try {
|
|
28
|
+
const isPassing = result.finalScore >= threshold;
|
|
29
|
+
const evaluationData = {
|
|
30
|
+
relevance: result.relevanceScore,
|
|
31
|
+
accuracy: result.accuracyScore,
|
|
32
|
+
completeness: result.completenessScore,
|
|
33
|
+
overall: result.finalScore,
|
|
34
|
+
isOffTopic: result.finalScore < offTopicThreshold,
|
|
35
|
+
alertSeverity: isPassing
|
|
36
|
+
? "none"
|
|
37
|
+
: result.finalScore < highSeverityThreshold
|
|
38
|
+
? "high"
|
|
39
|
+
: "medium",
|
|
40
|
+
reasoning: result.reasoning,
|
|
41
|
+
suggestedImprovements: result.suggestedImprovements,
|
|
42
|
+
evaluationModel: result.evaluationModel,
|
|
43
|
+
evaluationTime: result.evaluationTime,
|
|
44
|
+
evaluationAttempt: result.attemptNumber,
|
|
45
|
+
responseContent: evalContext.aiResponse,
|
|
46
|
+
queryContent: evalContext.userQuery,
|
|
47
|
+
};
|
|
48
|
+
span.durationMs = Date.now() - startTime;
|
|
49
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
50
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
51
|
+
return evaluationData;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
span.durationMs = Date.now() - startTime;
|
|
55
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
56
|
+
endedSpan.statusMessage =
|
|
57
|
+
error instanceof Error ? error.message : String(error);
|
|
58
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
35
61
|
}
|
|
36
62
|
//# sourceMappingURL=scoring.js.map
|
|
@@ -21,6 +21,8 @@ import { SlideGenerator } from "./slideGenerator.js";
|
|
|
21
21
|
import { PPT_GENERATION_TIMEOUT_MS } from "./constants.js";
|
|
22
22
|
import { logger } from "../../utils/logger.js";
|
|
23
23
|
import { withTimeout, ErrorFactory } from "../../utils/errorHandling.js";
|
|
24
|
+
import { SpanSerializer, SpanType, SpanStatus, } from "../../observability/index.js";
|
|
25
|
+
import { getMetricsAggregator } from "../../observability/index.js";
|
|
24
26
|
import { generateOutputPath, ensureOutputDirectory, normalizeLogoConfig, getLayoutName, getFailureStage, toError, } from "./utils.js";
|
|
25
27
|
// ============================================================================
|
|
26
28
|
// MAIN ORCHESTRATION FUNCTION
|
|
@@ -48,6 +50,13 @@ import { generateOutputPath, ensureOutputDirectory, normalizeLogoConfig, getLayo
|
|
|
48
50
|
* ```
|
|
49
51
|
*/
|
|
50
52
|
export async function generatePresentation(options) {
|
|
53
|
+
const span = SpanSerializer.createSpan(SpanType.PPT_GENERATION, "ppt.orchestrate", {
|
|
54
|
+
"ppt.operation": "orchestrate",
|
|
55
|
+
"ppt.slideCount": options.context.pages,
|
|
56
|
+
"ppt.theme": typeof options.context.theme === "string"
|
|
57
|
+
? options.context.theme
|
|
58
|
+
: "custom",
|
|
59
|
+
});
|
|
51
60
|
const state = {
|
|
52
61
|
startTime: Date.now(),
|
|
53
62
|
contentPlan: null,
|
|
@@ -73,6 +82,12 @@ export async function generatePresentation(options) {
|
|
|
73
82
|
ErrorFactory.toolTimeout("contentPlanning", PPT_GENERATION_TIMEOUT_MS / 2));
|
|
74
83
|
// Post-process: ensure title and thank-you slides
|
|
75
84
|
state.contentPlan = postProcessPlan(planResult);
|
|
85
|
+
// Update span attributes with post-processed plan values (AI may have changed slide count/theme)
|
|
86
|
+
span.attributes["ppt.slideCount"] = state.contentPlan.totalSlides;
|
|
87
|
+
span.attributes["ppt.theme"] =
|
|
88
|
+
typeof state.contentPlan.theme === "string"
|
|
89
|
+
? state.contentPlan.theme
|
|
90
|
+
: "custom";
|
|
76
91
|
logger.info("[PresentationOrchestrator] Content plan ready", {
|
|
77
92
|
title: state.contentPlan.title,
|
|
78
93
|
totalSlides: state.contentPlan.totalSlides,
|
|
@@ -163,6 +178,9 @@ export async function generatePresentation(options) {
|
|
|
163
178
|
// =========================================================================
|
|
164
179
|
// STEP 5: Return Result
|
|
165
180
|
// =========================================================================
|
|
181
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
182
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
183
|
+
neurolink?.recordMetricsSpan(endedSpan);
|
|
166
184
|
// Use values from content plan (AI may have chosen them if "AI will decide" was passed)
|
|
167
185
|
const finalTheme = state.contentPlan?.theme || context.theme;
|
|
168
186
|
const finalAudience = state.contentPlan?.audience || context.audience;
|
|
@@ -185,6 +203,11 @@ export async function generatePresentation(options) {
|
|
|
185
203
|
};
|
|
186
204
|
}
|
|
187
205
|
catch (error) {
|
|
206
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
207
|
+
endedSpan.statusMessage =
|
|
208
|
+
error instanceof Error ? error.message : String(error);
|
|
209
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
210
|
+
neurolink?.recordMetricsSpan(endedSpan);
|
|
188
211
|
// Re-throw PPTError as-is
|
|
189
212
|
if (error instanceof PPTError) {
|
|
190
213
|
logger.error("[PresentationOrchestrator] Generation failed", {
|
|
@@ -19,6 +19,8 @@ import { SLIDE_DIMENSIONS } from "./types.js";
|
|
|
19
19
|
import { getTheme, isImageSlideType, enhanceImagePrompt, IMAGE_GENERATION_TIMEOUT_MS, MAX_CONCURRENT_IMAGE_GENERATIONS, } from "./constants.js";
|
|
20
20
|
import { logger } from "../../utils/logger.js";
|
|
21
21
|
import { withTimeout, ErrorFactory, NeuroLinkError, } from "../../utils/errorHandling.js";
|
|
22
|
+
import { SpanSerializer, SpanType, SpanStatus, } from "../../observability/index.js";
|
|
23
|
+
import { getMetricsAggregator } from "../../observability/index.js";
|
|
22
24
|
import { NeuroLink } from "../../neurolink.js";
|
|
23
25
|
import { LAYOUT_POSITIONS, renderTitleSlide, renderSectionHeaderSlide, renderThankYouSlide, renderContentSlide, renderImageSlide, renderTwoColumnSlide, renderThreeColumnSlide, renderQuoteSlide, renderStatisticsSlide, renderChartSlide, renderTableSlide, renderTimelineSlide, renderProcessFlowSlide, renderComparisonSlide, renderFeaturesSlide, renderTeamSlide, renderConclusionSlide, renderDashboardSlide, renderMixedContentSlide, renderStatsGridSlide, renderIconGridSlide, } from "./slideRenderers.js";
|
|
24
26
|
// ============================================================================
|
|
@@ -86,6 +88,11 @@ export class SlideGenerator {
|
|
|
86
88
|
* Generate a single complete slide
|
|
87
89
|
*/
|
|
88
90
|
async generateSlide(slideSchema) {
|
|
91
|
+
const span = SpanSerializer.createSpan(SpanType.PPT_GENERATION, "ppt.generateSlide", {
|
|
92
|
+
"ppt.operation": "generateSlide",
|
|
93
|
+
"ppt.slideIndex": slideSchema.slideNumber,
|
|
94
|
+
"ppt.theme": this.theme.name,
|
|
95
|
+
});
|
|
89
96
|
const startTime = Date.now();
|
|
90
97
|
try {
|
|
91
98
|
let imageBuffer;
|
|
@@ -126,6 +133,8 @@ export class SlideGenerator {
|
|
|
126
133
|
hasImage: !!imageBuffer,
|
|
127
134
|
generationTime,
|
|
128
135
|
});
|
|
136
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
137
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
129
138
|
return {
|
|
130
139
|
slideNumber: slideSchema.slideNumber,
|
|
131
140
|
schema: slideSchema,
|
|
@@ -135,6 +144,10 @@ export class SlideGenerator {
|
|
|
135
144
|
};
|
|
136
145
|
}
|
|
137
146
|
catch (error) {
|
|
147
|
+
const endedSpan = SpanSerializer.endSpan(span, SpanStatus.ERROR);
|
|
148
|
+
endedSpan.statusMessage =
|
|
149
|
+
error instanceof Error ? error.message : String(error);
|
|
150
|
+
getMetricsAggregator().recordSpan(endedSpan);
|
|
138
151
|
const err = error instanceof NeuroLinkError
|
|
139
152
|
? error
|
|
140
153
|
: ErrorFactory.toolExecutionFailed("slideGenerator", error instanceof Error ? error : new Error(String(error)));
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module presentation/slideRenderers
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { BackgroundStyle, BulletPoint, ColumnData, PptxChartName, PptxSlide, PresentationTheme, RenderContentSlideOptions, SlideContent, SlideLayout, SlideType } from "./types.js";
|
|
10
10
|
export declare const LAYOUT_POSITIONS: {
|
|
11
11
|
margin: {
|
|
12
12
|
x: number;
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module presentation/slideRenderers
|
|
8
8
|
*/
|
|
9
|
-
import { getSlideTypeFormatting, getBulletOptions } from "./constants.js";
|
|
10
9
|
import { logger } from "../../utils/logger.js";
|
|
11
|
-
import {
|
|
10
|
+
import { getBulletOptions, getSlideTypeFormatting } from "./constants.js";
|
|
11
|
+
import { bufferToDataUrl, calculateFontSize, createFormattedTextProps, hasMarkdownFormatting, parseMarkdownText, validateImageBuffer, } from "./utils.js";
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// LAYOUT POSITIONS
|
|
14
14
|
// ============================================================================
|
|
@@ -986,9 +986,11 @@ export function renderThankYouSlide(slide, title, content, theme, imageBuffer) {
|
|
|
986
986
|
fit: DEFAULT_TEXT_FIT,
|
|
987
987
|
});
|
|
988
988
|
}
|
|
989
|
-
if (content.contactInfo.social &&
|
|
989
|
+
if (content.contactInfo.social &&
|
|
990
|
+
Array.isArray(content.contactInfo.social) &&
|
|
991
|
+
content.contactInfo.social.length > 0) {
|
|
990
992
|
const socialText = content.contactInfo.social
|
|
991
|
-
.map((s) => `${s.platform}: ${s.handle}`)
|
|
993
|
+
.map((s) => `${s.platform || ""}: ${s.handle || ""}`)
|
|
992
994
|
.join(" • ");
|
|
993
995
|
slide.addText(socialText, {
|
|
994
996
|
x: 0.5,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* This helps ensure consistent slide rendering when AI doesn't explicitly
|
|
10
10
|
* specify a slide type, or when we want to normalize AI responses.
|
|
11
11
|
*/
|
|
12
|
-
import type {
|
|
12
|
+
import type { BulletPoint, BulletStyle, SlideContent, SlideType } from "./types.js";
|
|
13
13
|
/**
|
|
14
14
|
* Infer slide type and bullet style from title text
|
|
15
15
|
*/
|
|
@@ -20,13 +20,13 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
20
20
|
// Agenda / Table of Contents - numbered list
|
|
21
21
|
{
|
|
22
22
|
patterns: [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
/\bagenda\b/i,
|
|
24
|
+
/\btable\s+of\s+contents\b/i,
|
|
25
|
+
/\boutline\b/i,
|
|
26
|
+
/\boverview\b/i,
|
|
27
|
+
/\bwhat\s+we('ll)?\s+cover\b/i,
|
|
28
|
+
/\btoday('s)?\s+topics?\b/i,
|
|
29
|
+
/\bsession\s+outline\b/i,
|
|
30
30
|
],
|
|
31
31
|
slideType: "agenda",
|
|
32
32
|
bulletStyle: "number",
|
|
@@ -34,18 +34,18 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
34
34
|
// Conclusion / Summary - checkmark
|
|
35
35
|
{
|
|
36
36
|
patterns: [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
/\bconclusion\b/i,
|
|
38
|
+
/\bsummary\b/i,
|
|
39
|
+
/\bkey\s+takeaways?\b/i,
|
|
40
|
+
/\btakeaways?\b/i,
|
|
41
|
+
/\brecap\b/i,
|
|
42
|
+
/\bin\s+summary\b/i,
|
|
43
|
+
/\bwhat\s+we('ve)?\s+learned\b/i,
|
|
44
|
+
/\bmain\s+points?\b/i,
|
|
45
|
+
/\bkey\s+points?\b/i,
|
|
46
|
+
/\bhighlights?\b/i,
|
|
47
|
+
/\bachievements?\b/i,
|
|
48
|
+
/\baccomplishments?\b/i,
|
|
49
49
|
],
|
|
50
50
|
slideType: "conclusion",
|
|
51
51
|
bulletStyle: "checkmark",
|
|
@@ -53,15 +53,15 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
53
53
|
// Closing / Thank You - checkmark
|
|
54
54
|
{
|
|
55
55
|
patterns: [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
/\bthank\s+you\b/i,
|
|
57
|
+
/\bthanks?\b/i,
|
|
58
|
+
/\bquestions?\b\??/i,
|
|
59
|
+
/\bq\s*&\s*a\b/i,
|
|
60
|
+
/\bcontact(\s+us)?\b/i,
|
|
61
|
+
/\bnext\s+steps?\b/i,
|
|
62
|
+
/\baction\s+items?\b/i,
|
|
63
|
+
/\blet('s)?\s+connect\b/i,
|
|
64
|
+
/\bget\s+(in\s+)?touch\b/i,
|
|
65
65
|
],
|
|
66
66
|
slideType: "closing",
|
|
67
67
|
bulletStyle: "checkmark",
|
|
@@ -69,14 +69,15 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
69
69
|
// Comparison - arrow bullets
|
|
70
70
|
{
|
|
71
71
|
patterns: [
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
/\bcomparison\b/i,
|
|
73
|
+
/\bcompare\b/i,
|
|
74
|
+
/\bvs\.?\b/i,
|
|
75
|
+
/\bversus\b/i,
|
|
76
|
+
/\bbefore\s+(and|&|vs\.?)\s+after\b/i,
|
|
77
|
+
/\bpros?\s+(and|&|vs\.?)\s+cons?\b/i,
|
|
78
|
+
/\badvantages?\s+(and|&|vs\.?)\s+disadvantages?\b/i,
|
|
79
|
+
/\bbenefits?\s+(and|&|vs\.?)\s+risks?\b/i,
|
|
80
|
+
/\bold\s+vs\.?\s+new\b/i,
|
|
80
81
|
],
|
|
81
82
|
slideType: "comparison",
|
|
82
83
|
bulletStyle: "arrow",
|
|
@@ -84,15 +85,16 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
84
85
|
// Process / Steps - numbered
|
|
85
86
|
{
|
|
86
87
|
patterns: [
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
/\bprocess\b/i,
|
|
89
|
+
/\bsteps?\b/i,
|
|
90
|
+
/\bstep[\s-]+by[\s-]+step\b/i,
|
|
91
|
+
/\bhow\s+to\b/i,
|
|
92
|
+
/\bworkflow\b/i,
|
|
93
|
+
/\bprocedure\b/i,
|
|
94
|
+
/\bmethodology\b/i,
|
|
95
|
+
/\d+\s+steps?\s+to\b/i,
|
|
96
|
+
/\bimplementation\s+steps?\b/i,
|
|
97
|
+
/\bgetting\s+started\b/i,
|
|
96
98
|
],
|
|
97
99
|
slideType: "numbered-list",
|
|
98
100
|
bulletStyle: "number",
|
|
@@ -100,21 +102,21 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
100
102
|
// Features / Benefits - disc (but could be checkmark for benefits)
|
|
101
103
|
{
|
|
102
104
|
patterns: [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
/\bfeatures?\b/i,
|
|
106
|
+
/\bcapabilities?\b/i,
|
|
107
|
+
/\bwhat\s+(we|it)\s+offers?\b/i,
|
|
108
|
+
/\bour\s+offerings?\b/i,
|
|
107
109
|
],
|
|
108
110
|
slideType: "features",
|
|
109
111
|
bulletStyle: "disc",
|
|
110
112
|
},
|
|
111
113
|
{
|
|
112
114
|
patterns: [
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
/\bbenefits?\b/i,
|
|
116
|
+
/\badvantages?\b/i,
|
|
117
|
+
/\bwhy\s+choose\b/i,
|
|
118
|
+
/\breasons?\s+to\b/i,
|
|
119
|
+
/\bvalue\s+proposition\b/i,
|
|
118
120
|
],
|
|
119
121
|
slideType: "content",
|
|
120
122
|
bulletStyle: "checkmark",
|
|
@@ -122,12 +124,12 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
122
124
|
// Goals / Objectives - checkmark
|
|
123
125
|
{
|
|
124
126
|
patterns: [
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
/\bgoals?\b/i,
|
|
128
|
+
/\bobjectives?\b/i,
|
|
129
|
+
/\btargets?\b/i,
|
|
130
|
+
/\baims?\b/i,
|
|
131
|
+
/\bour\s+mission\b/i,
|
|
132
|
+
/\bwhat\s+we\s+aim\s+for\b/i,
|
|
131
133
|
],
|
|
132
134
|
slideType: "content",
|
|
133
135
|
bulletStyle: "checkmark",
|
|
@@ -135,13 +137,13 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
135
137
|
// Challenges / Risks - arrow
|
|
136
138
|
{
|
|
137
139
|
patterns: [
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
/\bchallenges?\b/i,
|
|
141
|
+
/\brisks?\b/i,
|
|
142
|
+
/\bobstacles?\b/i,
|
|
143
|
+
/\bbarriers?\b/i,
|
|
144
|
+
/\bconcerns?\b/i,
|
|
145
|
+
/\bissues?\b/i,
|
|
146
|
+
/\bproblems?\b/i,
|
|
145
147
|
],
|
|
146
148
|
slideType: "content",
|
|
147
149
|
bulletStyle: "arrow",
|
|
@@ -149,12 +151,12 @@ const TITLE_KEYWORD_PATTERNS = [
|
|
|
149
151
|
// Requirements / Checklist - checkmark
|
|
150
152
|
{
|
|
151
153
|
patterns: [
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
/\brequirements?\b/i,
|
|
155
|
+
/\bchecklist\b/i,
|
|
156
|
+
/\bprerequisites?\b/i,
|
|
157
|
+
/\bwhat\s+you\s+need\b/i,
|
|
158
|
+
/\bmust\s+haves?\b/i,
|
|
159
|
+
/\bessentials?\b/i,
|
|
158
160
|
],
|
|
159
161
|
slideType: "content",
|
|
160
162
|
bulletStyle: "checkmark",
|