@juspay/neurolink 9.63.1 → 9.65.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 +18 -17
- package/dist/adapters/providerImageAdapter.js +29 -1
- package/dist/adapters/replicate/auth.d.ts +19 -0
- package/dist/adapters/replicate/auth.js +32 -0
- package/dist/adapters/replicate/predictionLifecycle.d.ts +46 -0
- package/dist/adapters/replicate/predictionLifecycle.js +283 -0
- package/dist/adapters/video/klingVideoHandler.d.ts +37 -0
- package/dist/adapters/video/klingVideoHandler.js +305 -0
- package/dist/adapters/video/replicateVideoHandler.d.ts +29 -0
- package/dist/adapters/video/replicateVideoHandler.js +157 -0
- package/dist/adapters/video/runwayVideoHandler.d.ts +32 -0
- package/dist/adapters/video/runwayVideoHandler.js +316 -0
- package/dist/adapters/video/vertexVideoHandler.d.ts +19 -1
- package/dist/adapters/video/vertexVideoHandler.js +42 -11
- package/dist/autoresearch/runner.js +8 -2
- package/dist/avatar/index.d.ts +13 -0
- package/dist/avatar/index.js +13 -0
- package/dist/avatar/providers/DIDAvatar.d.ts +49 -0
- package/dist/avatar/providers/DIDAvatar.js +501 -0
- package/dist/avatar/providers/HeyGenAvatar.d.ts +30 -0
- package/dist/avatar/providers/HeyGenAvatar.js +337 -0
- package/dist/avatar/providers/ReplicateAvatar.d.ts +36 -0
- package/dist/avatar/providers/ReplicateAvatar.js +267 -0
- package/dist/browser/neurolink.min.js +573 -554
- package/dist/cli/commands/mcp.js +29 -0
- package/dist/cli/commands/proxy.js +24 -5
- package/dist/cli/factories/commandFactory.d.ts +25 -1
- package/dist/cli/factories/commandFactory.js +341 -63
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/loop/optionsSchema.js +12 -0
- package/dist/constants/contextWindows.js +101 -0
- package/dist/constants/enums.d.ts +273 -2
- package/dist/constants/enums.js +290 -1
- package/dist/constants/videoErrors.d.ts +4 -0
- package/dist/constants/videoErrors.js +4 -0
- package/dist/core/baseProvider.d.ts +23 -3
- package/dist/core/baseProvider.js +217 -11
- package/dist/core/constants.d.ts +11 -0
- package/dist/core/constants.js +69 -1
- package/dist/core/modules/MessageBuilder.js +20 -0
- package/dist/core/redisConversationMemoryManager.js +6 -0
- package/dist/evaluation/index.d.ts +2 -0
- package/dist/evaluation/index.js +4 -0
- package/dist/factories/providerFactory.js +7 -1
- package/dist/factories/providerRegistry.js +203 -2
- package/dist/features/ppt/contentPlanner.js +42 -14
- package/dist/index.d.ts +9 -1
- package/dist/index.js +16 -1
- package/dist/lib/adapters/providerImageAdapter.js +29 -1
- package/dist/lib/adapters/replicate/auth.d.ts +19 -0
- package/dist/lib/adapters/replicate/auth.js +33 -0
- package/dist/lib/adapters/replicate/predictionLifecycle.d.ts +46 -0
- package/dist/lib/adapters/replicate/predictionLifecycle.js +284 -0
- package/dist/lib/adapters/video/klingVideoHandler.d.ts +37 -0
- package/dist/lib/adapters/video/klingVideoHandler.js +306 -0
- package/dist/lib/adapters/video/replicateVideoHandler.d.ts +29 -0
- package/dist/lib/adapters/video/replicateVideoHandler.js +158 -0
- package/dist/lib/adapters/video/runwayVideoHandler.d.ts +32 -0
- package/dist/lib/adapters/video/runwayVideoHandler.js +317 -0
- package/dist/lib/adapters/video/vertexVideoHandler.d.ts +19 -1
- package/dist/lib/adapters/video/vertexVideoHandler.js +42 -11
- package/dist/lib/autoresearch/runner.js +8 -2
- package/dist/lib/avatar/index.d.ts +13 -0
- package/dist/lib/avatar/index.js +14 -0
- package/dist/lib/avatar/providers/DIDAvatar.d.ts +49 -0
- package/dist/lib/avatar/providers/DIDAvatar.js +502 -0
- package/dist/lib/avatar/providers/HeyGenAvatar.d.ts +30 -0
- package/dist/lib/avatar/providers/HeyGenAvatar.js +338 -0
- package/dist/lib/avatar/providers/ReplicateAvatar.d.ts +36 -0
- package/dist/lib/avatar/providers/ReplicateAvatar.js +268 -0
- package/dist/lib/constants/contextWindows.js +101 -0
- package/dist/lib/constants/enums.d.ts +273 -2
- package/dist/lib/constants/enums.js +290 -1
- package/dist/lib/constants/videoErrors.d.ts +4 -0
- package/dist/lib/constants/videoErrors.js +4 -0
- package/dist/lib/core/baseProvider.d.ts +23 -3
- package/dist/lib/core/baseProvider.js +217 -11
- package/dist/lib/core/constants.d.ts +11 -0
- package/dist/lib/core/constants.js +69 -1
- package/dist/lib/core/modules/MessageBuilder.js +20 -0
- package/dist/lib/core/redisConversationMemoryManager.js +6 -0
- package/dist/lib/evaluation/index.d.ts +2 -0
- package/dist/lib/evaluation/index.js +4 -0
- package/dist/lib/factories/providerFactory.js +7 -1
- package/dist/lib/factories/providerRegistry.js +203 -2
- package/dist/lib/features/ppt/contentPlanner.js +42 -14
- package/dist/lib/index.d.ts +9 -1
- package/dist/lib/index.js +16 -1
- package/dist/lib/memory/hippocampusInitializer.d.ts +2 -2
- package/dist/lib/memory/hippocampusInitializer.js +32 -2
- package/dist/lib/middleware/builtin/lifecycle.js +52 -51
- package/dist/lib/music/index.d.ts +13 -0
- package/dist/lib/music/index.js +14 -0
- package/dist/lib/music/providers/BeatovenMusic.d.ts +31 -0
- package/dist/lib/music/providers/BeatovenMusic.js +334 -0
- package/dist/lib/music/providers/ElevenLabsMusic.d.ts +30 -0
- package/dist/lib/music/providers/ElevenLabsMusic.js +169 -0
- package/dist/lib/music/providers/LyriaMusic.d.ts +29 -0
- package/dist/lib/music/providers/LyriaMusic.js +173 -0
- package/dist/lib/music/providers/ReplicateMusic.d.ts +31 -0
- package/dist/lib/music/providers/ReplicateMusic.js +262 -0
- package/dist/lib/neurolink.d.ts +30 -0
- package/dist/lib/neurolink.js +342 -49
- package/dist/lib/providers/amazonBedrock.d.ts +10 -0
- package/dist/lib/providers/amazonBedrock.js +94 -39
- package/dist/lib/providers/anthropic.js +55 -7
- package/dist/lib/providers/anthropicBaseProvider.js +1 -1
- package/dist/lib/providers/azureOpenai.js +66 -17
- package/dist/lib/providers/cloudflare.d.ts +35 -0
- package/dist/lib/providers/cloudflare.js +174 -0
- package/dist/lib/providers/cohere.d.ts +52 -0
- package/dist/lib/providers/cohere.js +253 -0
- package/dist/lib/providers/deepseek.js +72 -17
- package/dist/lib/providers/fireworks.d.ts +33 -0
- package/dist/lib/providers/fireworks.js +164 -0
- package/dist/lib/providers/googleAiStudio.d.ts +11 -3
- package/dist/lib/providers/googleAiStudio.js +336 -344
- package/dist/lib/providers/googleNativeGemini3.d.ts +107 -2
- package/dist/lib/providers/googleNativeGemini3.js +381 -25
- package/dist/lib/providers/googleVertex.d.ts +116 -129
- package/dist/lib/providers/googleVertex.js +3002 -1988
- package/dist/lib/providers/groq.d.ts +33 -0
- package/dist/lib/providers/groq.js +181 -0
- package/dist/lib/providers/huggingFace.js +9 -8
- package/dist/lib/providers/ideogram.d.ts +34 -0
- package/dist/lib/providers/ideogram.js +184 -0
- package/dist/lib/providers/index.d.ts +13 -0
- package/dist/lib/providers/index.js +13 -0
- package/dist/lib/providers/jina.d.ts +59 -0
- package/dist/lib/providers/jina.js +218 -0
- package/dist/lib/providers/llamaCpp.js +14 -46
- package/dist/lib/providers/lmStudio.js +14 -47
- package/dist/lib/providers/mistral.js +7 -7
- package/dist/lib/providers/nvidiaNim.js +160 -19
- package/dist/lib/providers/ollama.js +7 -7
- package/dist/lib/providers/openAI.d.ts +22 -1
- package/dist/lib/providers/openAI.js +181 -0
- package/dist/lib/providers/openRouter.js +38 -22
- package/dist/lib/providers/openaiCompatible.js +9 -8
- package/dist/lib/providers/perplexity.d.ts +33 -0
- package/dist/lib/providers/perplexity.js +179 -0
- package/dist/lib/providers/recraft.d.ts +34 -0
- package/dist/lib/providers/recraft.js +197 -0
- package/dist/lib/providers/replicate.d.ts +75 -0
- package/dist/lib/providers/replicate.js +403 -0
- package/dist/lib/providers/stability.d.ts +37 -0
- package/dist/lib/providers/stability.js +191 -0
- package/dist/lib/providers/togetherAi.d.ts +33 -0
- package/dist/lib/providers/togetherAi.js +176 -0
- package/dist/lib/providers/voyage.d.ts +47 -0
- package/dist/lib/providers/voyage.js +177 -0
- package/dist/lib/providers/xai.d.ts +33 -0
- package/dist/lib/providers/xai.js +172 -0
- package/dist/lib/telemetry/index.d.ts +1 -1
- package/dist/lib/telemetry/index.js +1 -1
- package/dist/lib/telemetry/tracers.d.ts +19 -0
- package/dist/lib/telemetry/tracers.js +19 -0
- package/dist/lib/telemetry/withSpan.d.ts +35 -0
- package/dist/lib/telemetry/withSpan.js +103 -0
- package/dist/lib/types/aliases.d.ts +14 -0
- package/dist/lib/types/avatar.d.ts +143 -0
- package/dist/lib/types/avatar.js +20 -0
- package/dist/lib/types/cli.d.ts +6 -0
- package/dist/lib/types/common.d.ts +0 -3
- package/dist/lib/types/conversation.d.ts +10 -3
- package/dist/lib/types/generate.d.ts +76 -5
- package/dist/lib/types/index.d.ts +6 -0
- package/dist/lib/types/index.js +8 -0
- package/dist/lib/types/memory.d.ts +96 -0
- package/dist/lib/types/memory.js +23 -0
- package/dist/lib/types/middleware.d.ts +27 -0
- package/dist/lib/types/multimodal.d.ts +35 -2
- package/dist/lib/types/music.d.ts +165 -0
- package/dist/lib/types/music.js +21 -0
- package/dist/lib/types/providers.d.ts +284 -3
- package/dist/lib/types/replicate.d.ts +67 -0
- package/dist/lib/types/replicate.js +10 -0
- package/dist/lib/types/safeFetch.d.ts +15 -0
- package/dist/lib/types/safeFetch.js +7 -0
- package/dist/lib/types/stream.d.ts +8 -1
- package/dist/lib/types/tools.d.ts +13 -0
- package/dist/lib/types/video.d.ts +89 -0
- package/dist/lib/types/video.js +15 -0
- package/dist/lib/utils/avatarProcessor.d.ts +68 -0
- package/dist/lib/utils/avatarProcessor.js +172 -0
- package/dist/lib/utils/cloneOptions.d.ts +36 -0
- package/dist/lib/utils/cloneOptions.js +62 -0
- package/dist/lib/utils/lifecycleCallbacks.d.ts +56 -0
- package/dist/lib/utils/lifecycleCallbacks.js +100 -0
- package/dist/lib/utils/lifecycleTimeout.d.ts +25 -0
- package/dist/lib/utils/lifecycleTimeout.js +39 -0
- package/dist/lib/utils/logSanitize.d.ts +49 -0
- package/dist/lib/utils/logSanitize.js +170 -0
- package/dist/lib/utils/loggingFetch.d.ts +29 -0
- package/dist/lib/utils/loggingFetch.js +60 -0
- package/dist/lib/utils/messageBuilder.d.ts +10 -0
- package/dist/lib/utils/messageBuilder.js +83 -30
- package/dist/lib/utils/modelChoices.js +236 -3
- package/dist/lib/utils/modelDetection.d.ts +11 -0
- package/dist/lib/utils/modelDetection.js +27 -0
- package/dist/lib/utils/musicProcessor.d.ts +67 -0
- package/dist/lib/utils/musicProcessor.js +189 -0
- package/dist/lib/utils/optionsConversion.js +3 -2
- package/dist/lib/utils/parameterValidation.js +14 -4
- package/dist/lib/utils/pricing.js +193 -0
- package/dist/lib/utils/providerConfig.d.ts +55 -0
- package/dist/lib/utils/providerConfig.js +224 -0
- package/dist/lib/utils/providerHealth.js +7 -7
- package/dist/lib/utils/safeFetch.d.ts +26 -0
- package/dist/lib/utils/safeFetch.js +83 -0
- package/dist/lib/utils/schemaConversion.d.ts +1 -1
- package/dist/lib/utils/schemaConversion.js +59 -4
- package/dist/lib/utils/sizeGuard.d.ts +34 -0
- package/dist/lib/utils/sizeGuard.js +45 -0
- package/dist/lib/utils/ssrfGuard.d.ts +52 -0
- package/dist/lib/utils/ssrfGuard.js +411 -0
- package/dist/lib/utils/tokenLimits.js +23 -32
- package/dist/lib/utils/videoProcessor.d.ts +60 -0
- package/dist/lib/utils/videoProcessor.js +201 -0
- package/dist/lib/voice/providers/FishAudioTTS.d.ts +27 -0
- package/dist/lib/voice/providers/FishAudioTTS.js +183 -0
- package/dist/lib/workflow/core/ensembleExecutor.js +26 -9
- package/dist/memory/hippocampusInitializer.d.ts +2 -2
- package/dist/memory/hippocampusInitializer.js +32 -2
- package/dist/middleware/builtin/lifecycle.js +52 -51
- package/dist/music/index.d.ts +13 -0
- package/dist/music/index.js +13 -0
- package/dist/music/providers/BeatovenMusic.d.ts +31 -0
- package/dist/music/providers/BeatovenMusic.js +333 -0
- package/dist/music/providers/ElevenLabsMusic.d.ts +30 -0
- package/dist/music/providers/ElevenLabsMusic.js +168 -0
- package/dist/music/providers/LyriaMusic.d.ts +29 -0
- package/dist/music/providers/LyriaMusic.js +172 -0
- package/dist/music/providers/ReplicateMusic.d.ts +31 -0
- package/dist/music/providers/ReplicateMusic.js +261 -0
- package/dist/neurolink.d.ts +30 -0
- package/dist/neurolink.js +342 -49
- package/dist/providers/amazonBedrock.d.ts +10 -0
- package/dist/providers/amazonBedrock.js +94 -39
- package/dist/providers/anthropic.js +55 -7
- package/dist/providers/anthropicBaseProvider.js +1 -1
- package/dist/providers/azureOpenai.js +66 -17
- package/dist/providers/cloudflare.d.ts +35 -0
- package/dist/providers/cloudflare.js +173 -0
- package/dist/providers/cohere.d.ts +52 -0
- package/dist/providers/cohere.js +252 -0
- package/dist/providers/deepseek.js +72 -17
- package/dist/providers/fireworks.d.ts +33 -0
- package/dist/providers/fireworks.js +163 -0
- package/dist/providers/googleAiStudio.d.ts +11 -3
- package/dist/providers/googleAiStudio.js +335 -344
- package/dist/providers/googleNativeGemini3.d.ts +107 -2
- package/dist/providers/googleNativeGemini3.js +381 -25
- package/dist/providers/googleVertex.d.ts +116 -129
- package/dist/providers/googleVertex.js +3000 -1987
- package/dist/providers/groq.d.ts +33 -0
- package/dist/providers/groq.js +180 -0
- package/dist/providers/huggingFace.js +9 -8
- package/dist/providers/ideogram.d.ts +34 -0
- package/dist/providers/ideogram.js +183 -0
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/jina.d.ts +59 -0
- package/dist/providers/jina.js +217 -0
- package/dist/providers/llamaCpp.js +14 -46
- package/dist/providers/lmStudio.js +14 -47
- package/dist/providers/mistral.js +7 -7
- package/dist/providers/nvidiaNim.js +160 -19
- package/dist/providers/ollama.js +7 -7
- package/dist/providers/openAI.d.ts +22 -1
- package/dist/providers/openAI.js +181 -0
- package/dist/providers/openRouter.js +38 -22
- package/dist/providers/openaiCompatible.js +9 -8
- package/dist/providers/perplexity.d.ts +33 -0
- package/dist/providers/perplexity.js +178 -0
- package/dist/providers/recraft.d.ts +34 -0
- package/dist/providers/recraft.js +196 -0
- package/dist/providers/replicate.d.ts +75 -0
- package/dist/providers/replicate.js +402 -0
- package/dist/providers/stability.d.ts +37 -0
- package/dist/providers/stability.js +190 -0
- package/dist/providers/togetherAi.d.ts +33 -0
- package/dist/providers/togetherAi.js +175 -0
- package/dist/providers/voyage.d.ts +47 -0
- package/dist/providers/voyage.js +176 -0
- package/dist/providers/xai.d.ts +33 -0
- package/dist/providers/xai.js +171 -0
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/telemetry/tracers.d.ts +19 -0
- package/dist/telemetry/tracers.js +19 -0
- package/dist/telemetry/withSpan.d.ts +35 -0
- package/dist/telemetry/withSpan.js +103 -0
- package/dist/types/aliases.d.ts +14 -0
- package/dist/types/avatar.d.ts +143 -0
- package/dist/types/avatar.js +19 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/common.d.ts +0 -3
- package/dist/types/conversation.d.ts +10 -3
- package/dist/types/generate.d.ts +76 -5
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +8 -0
- package/dist/types/memory.d.ts +96 -0
- package/dist/types/memory.js +22 -0
- package/dist/types/middleware.d.ts +27 -0
- package/dist/types/multimodal.d.ts +35 -2
- package/dist/types/music.d.ts +165 -0
- package/dist/types/music.js +20 -0
- package/dist/types/providers.d.ts +284 -3
- package/dist/types/replicate.d.ts +67 -0
- package/dist/types/replicate.js +9 -0
- package/dist/types/safeFetch.d.ts +15 -0
- package/dist/types/safeFetch.js +6 -0
- package/dist/types/stream.d.ts +8 -1
- package/dist/types/tools.d.ts +13 -0
- package/dist/types/video.d.ts +89 -0
- package/dist/types/video.js +14 -0
- package/dist/utils/avatarProcessor.d.ts +68 -0
- package/dist/utils/avatarProcessor.js +171 -0
- package/dist/utils/cloneOptions.d.ts +36 -0
- package/dist/utils/cloneOptions.js +61 -0
- package/dist/utils/lifecycleCallbacks.d.ts +56 -0
- package/dist/utils/lifecycleCallbacks.js +99 -0
- package/dist/utils/lifecycleTimeout.d.ts +25 -0
- package/dist/utils/lifecycleTimeout.js +38 -0
- package/dist/utils/logSanitize.d.ts +49 -0
- package/dist/utils/logSanitize.js +169 -0
- package/dist/utils/loggingFetch.d.ts +29 -0
- package/dist/utils/loggingFetch.js +59 -0
- package/dist/utils/messageBuilder.d.ts +10 -0
- package/dist/utils/messageBuilder.js +83 -30
- package/dist/utils/modelChoices.js +236 -3
- package/dist/utils/modelDetection.d.ts +11 -0
- package/dist/utils/modelDetection.js +27 -0
- package/dist/utils/musicProcessor.d.ts +67 -0
- package/dist/utils/musicProcessor.js +188 -0
- package/dist/utils/optionsConversion.js +3 -2
- package/dist/utils/parameterValidation.js +14 -4
- package/dist/utils/pricing.js +193 -0
- package/dist/utils/providerConfig.d.ts +55 -0
- package/dist/utils/providerConfig.js +224 -0
- package/dist/utils/providerHealth.js +7 -7
- package/dist/utils/safeFetch.d.ts +26 -0
- package/dist/utils/safeFetch.js +82 -0
- package/dist/utils/schemaConversion.d.ts +1 -1
- package/dist/utils/schemaConversion.js +59 -4
- package/dist/utils/sizeGuard.d.ts +34 -0
- package/dist/utils/sizeGuard.js +44 -0
- package/dist/utils/ssrfGuard.d.ts +52 -0
- package/dist/utils/ssrfGuard.js +410 -0
- package/dist/utils/tokenLimits.js +23 -32
- package/dist/utils/videoProcessor.d.ts +60 -0
- package/dist/utils/videoProcessor.js +200 -0
- package/dist/voice/providers/FishAudioTTS.d.ts +27 -0
- package/dist/voice/providers/FishAudioTTS.js +182 -0
- package/dist/workflow/core/ensembleExecutor.js +26 -9
- package/package.json +42 -8
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar / Lip-sync Generation Processing Utility
|
|
3
|
+
*
|
|
4
|
+
* Central registry + dispatch for avatar handlers across providers
|
|
5
|
+
* (D-ID, HeyGen, Replicate-hosted MuseTalk / SadTalker / Wav2Lip).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the static-handler-registry pattern established by
|
|
8
|
+
* `TTSProcessor` / `STTProcessor` / `VideoProcessor` / `MusicProcessor`.
|
|
9
|
+
*
|
|
10
|
+
* @module utils/avatarProcessor
|
|
11
|
+
*/
|
|
12
|
+
import { ErrorCategory, ErrorSeverity } from "../constants/enums.js";
|
|
13
|
+
import { SpanSerializer, SpanStatus, SpanType, getMetricsAggregator, } from "../observability/index.js";
|
|
14
|
+
import { NeuroLinkError } from "./errorHandling.js";
|
|
15
|
+
import { logger } from "./logger.js";
|
|
16
|
+
/**
|
|
17
|
+
* Avatar-specific error codes.
|
|
18
|
+
*/
|
|
19
|
+
export const AVATAR_ERROR_CODES = {
|
|
20
|
+
PROVIDER_NOT_SUPPORTED: "AVATAR_PROVIDER_NOT_SUPPORTED",
|
|
21
|
+
PROVIDER_NOT_CONFIGURED: "AVATAR_PROVIDER_NOT_CONFIGURED",
|
|
22
|
+
GENERATION_FAILED: "AVATAR_GENERATION_FAILED",
|
|
23
|
+
POLL_TIMEOUT: "AVATAR_POLL_TIMEOUT",
|
|
24
|
+
INVALID_INPUT: "AVATAR_INVALID_INPUT",
|
|
25
|
+
AUDIO_REQUIRED: "AVATAR_AUDIO_REQUIRED",
|
|
26
|
+
IMAGE_REQUIRED: "AVATAR_IMAGE_REQUIRED",
|
|
27
|
+
AUDIO_TOO_LONG: "AVATAR_AUDIO_TOO_LONG",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Typed error class for avatar-generation failures.
|
|
31
|
+
*/
|
|
32
|
+
export class AvatarError extends NeuroLinkError {
|
|
33
|
+
constructor(options) {
|
|
34
|
+
super({
|
|
35
|
+
code: options.code,
|
|
36
|
+
message: options.message,
|
|
37
|
+
category: options.category ?? ErrorCategory.EXECUTION,
|
|
38
|
+
severity: options.severity ?? ErrorSeverity.HIGH,
|
|
39
|
+
retriable: options.retriable ?? false,
|
|
40
|
+
context: options.context,
|
|
41
|
+
originalError: options.originalError,
|
|
42
|
+
});
|
|
43
|
+
this.name = "AvatarError";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Static processor managing the avatar handler registry.
|
|
48
|
+
*/
|
|
49
|
+
export class AvatarProcessor {
|
|
50
|
+
static handlers = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Register an avatar handler for a specific provider.
|
|
53
|
+
*/
|
|
54
|
+
static registerHandler(providerName, handler) {
|
|
55
|
+
if (!providerName) {
|
|
56
|
+
throw new Error("Provider name is required");
|
|
57
|
+
}
|
|
58
|
+
if (!handler) {
|
|
59
|
+
throw new Error("Handler is required");
|
|
60
|
+
}
|
|
61
|
+
const key = providerName.toLowerCase();
|
|
62
|
+
if (this.handlers.has(key)) {
|
|
63
|
+
logger.warn(`[AvatarProcessor] Overwriting existing handler for provider: ${key}`);
|
|
64
|
+
}
|
|
65
|
+
this.handlers.set(key, handler);
|
|
66
|
+
logger.debug(`[AvatarProcessor] Registered avatar handler: ${key}`);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if a provider has a registered avatar handler.
|
|
70
|
+
*/
|
|
71
|
+
static supports(providerName) {
|
|
72
|
+
if (!providerName) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return this.handlers.has(providerName.toLowerCase());
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* List the names of all registered providers.
|
|
79
|
+
*/
|
|
80
|
+
static listProviders() {
|
|
81
|
+
return Array.from(this.handlers.keys());
|
|
82
|
+
}
|
|
83
|
+
static getHandler(providerName) {
|
|
84
|
+
return this.handlers.get(providerName.toLowerCase());
|
|
85
|
+
}
|
|
86
|
+
static buildSpanAttributes(provider, options) {
|
|
87
|
+
return {
|
|
88
|
+
"avatar.operation": "generate",
|
|
89
|
+
"avatar.provider": provider,
|
|
90
|
+
"avatar.quality": options.quality,
|
|
91
|
+
"avatar.format": options.format,
|
|
92
|
+
"avatar.has_text": options.text !== undefined,
|
|
93
|
+
"avatar.has_audio": options.audio !== undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Generate an avatar video via the registered handler.
|
|
98
|
+
*
|
|
99
|
+
* @throws AvatarError on registry miss, handler-not-configured, or
|
|
100
|
+
* generation failure.
|
|
101
|
+
*/
|
|
102
|
+
static async generate(provider, options) {
|
|
103
|
+
const span = SpanSerializer.createSpan(SpanType.MEDIA_GENERATION, "avatar.generate", this.buildSpanAttributes(provider, options));
|
|
104
|
+
try {
|
|
105
|
+
if (!options.image) {
|
|
106
|
+
throw new AvatarError({
|
|
107
|
+
code: AVATAR_ERROR_CODES.IMAGE_REQUIRED,
|
|
108
|
+
message: "Avatar generation requires an `image` (Buffer, path, or URL)",
|
|
109
|
+
category: ErrorCategory.VALIDATION,
|
|
110
|
+
severity: ErrorSeverity.MEDIUM,
|
|
111
|
+
retriable: false,
|
|
112
|
+
context: { provider },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (!options.audio && !options.text) {
|
|
116
|
+
throw new AvatarError({
|
|
117
|
+
code: AVATAR_ERROR_CODES.INVALID_INPUT,
|
|
118
|
+
message: "Avatar generation requires either `audio` (a Buffer/URL) or `text` (to be TTS'd by the provider).",
|
|
119
|
+
category: ErrorCategory.VALIDATION,
|
|
120
|
+
severity: ErrorSeverity.HIGH,
|
|
121
|
+
retriable: false,
|
|
122
|
+
context: { provider },
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const handler = this.getHandler(provider);
|
|
126
|
+
if (!handler) {
|
|
127
|
+
throw new AvatarError({
|
|
128
|
+
code: AVATAR_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
|
|
129
|
+
message: `Avatar provider "${provider}" is not registered. Available: ${this.listProviders().join(", ")}`,
|
|
130
|
+
category: ErrorCategory.CONFIGURATION,
|
|
131
|
+
severity: ErrorSeverity.HIGH,
|
|
132
|
+
retriable: false,
|
|
133
|
+
context: { provider, available: this.listProviders() },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (!handler.isConfigured()) {
|
|
137
|
+
throw new AvatarError({
|
|
138
|
+
code: AVATAR_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
|
|
139
|
+
message: `Avatar provider "${provider}" is not configured. Set the required credentials.`,
|
|
140
|
+
category: ErrorCategory.CONFIGURATION,
|
|
141
|
+
severity: ErrorSeverity.HIGH,
|
|
142
|
+
retriable: false,
|
|
143
|
+
context: { provider },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
logger.debug(`[AvatarProcessor] Starting avatar generation with provider: ${provider}`);
|
|
147
|
+
const result = await handler.generate(options);
|
|
148
|
+
const ended = SpanSerializer.endSpan(span, SpanStatus.OK);
|
|
149
|
+
getMetricsAggregator().recordSpan(ended);
|
|
150
|
+
logger.info(`[AvatarProcessor] Generated ${result.size} bytes (${provider})`);
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
const ended = SpanSerializer.endSpan(span, SpanStatus.ERROR, err instanceof Error ? err.message : String(err));
|
|
155
|
+
getMetricsAggregator().recordSpan(ended);
|
|
156
|
+
if (err instanceof AvatarError) {
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
159
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
160
|
+
throw new AvatarError({
|
|
161
|
+
code: AVATAR_ERROR_CODES.GENERATION_FAILED,
|
|
162
|
+
message: `Avatar generation failed for provider "${provider}": ${message}`,
|
|
163
|
+
category: ErrorCategory.EXECUTION,
|
|
164
|
+
severity: ErrorSeverity.HIGH,
|
|
165
|
+
retriable: true,
|
|
166
|
+
context: { provider },
|
|
167
|
+
originalError: err instanceof Error ? err : undefined,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The set of top-level branches on a `StreamOptions` / `GenerateOptions`
|
|
3
|
+
* / `DynamicOptions` bag that downstream prep stages mutate. Listed here
|
|
4
|
+
* once so the runtime clone (`cloneOptionsForCallIsolation`) and any
|
|
5
|
+
* future test that wants to assert call isolation reference the same
|
|
6
|
+
* source of truth.
|
|
7
|
+
*
|
|
8
|
+
* If you add a new top-level field to `StreamOptions` that gets mutated
|
|
9
|
+
* by prepareStreamOptions / applyStreamOrchestration / RAG/MCP injection
|
|
10
|
+
* / memory retrieval / etc., add it here AND add an entry to
|
|
11
|
+
* `test/helpers/cloneOptions.test.ts` so the isolation guarantee gets
|
|
12
|
+
* exercised.
|
|
13
|
+
*
|
|
14
|
+
* Branches that are deliberately NOT cloned (and why):
|
|
15
|
+
* - `signal` / `abortSignal` — `AbortSignal` can't be `structuredClone`d
|
|
16
|
+
* and a shallow copy would strip the listener wiring.
|
|
17
|
+
* - `tools[name].execute` — function identity is used as a cache key
|
|
18
|
+
* downstream; cloning would break that.
|
|
19
|
+
* - schema objects (zod / JSON Schema) — large, frequently frozen,
|
|
20
|
+
* and not mutated by NeuroLink internals.
|
|
21
|
+
*/
|
|
22
|
+
export declare const CLONE_MUTABLE_OPTION_BRANCHES: readonly ["input", "context", "memory", "tools", "middleware", "rag", "csvOptions", "stt", "tts"];
|
|
23
|
+
/**
|
|
24
|
+
* Defensive call-isolation clone for stream() / generate()-shaped inputs.
|
|
25
|
+
*
|
|
26
|
+
* Shallow-clones the top-level options bag plus every branch listed in
|
|
27
|
+
* `CLONE_MUTABLE_OPTION_BRANCHES`. Caller-supplied objects can be reused
|
|
28
|
+
* across calls without accumulating cross-call mutations from
|
|
29
|
+
* prepareStreamOptions, applyStreamOrchestration, memory retrieval, or
|
|
30
|
+
* RAG/MCP tool injection.
|
|
31
|
+
*
|
|
32
|
+
* Unclonable / by-reference values are deliberately kept by-reference —
|
|
33
|
+
* cloning them would either fail outright (`structuredClone(AbortSignal)`)
|
|
34
|
+
* or strip behavior (function identity used as a cache key).
|
|
35
|
+
*/
|
|
36
|
+
export declare function cloneOptionsForCallIsolation<T>(options: T): T;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The set of top-level branches on a `StreamOptions` / `GenerateOptions`
|
|
3
|
+
* / `DynamicOptions` bag that downstream prep stages mutate. Listed here
|
|
4
|
+
* once so the runtime clone (`cloneOptionsForCallIsolation`) and any
|
|
5
|
+
* future test that wants to assert call isolation reference the same
|
|
6
|
+
* source of truth.
|
|
7
|
+
*
|
|
8
|
+
* If you add a new top-level field to `StreamOptions` that gets mutated
|
|
9
|
+
* by prepareStreamOptions / applyStreamOrchestration / RAG/MCP injection
|
|
10
|
+
* / memory retrieval / etc., add it here AND add an entry to
|
|
11
|
+
* `test/helpers/cloneOptions.test.ts` so the isolation guarantee gets
|
|
12
|
+
* exercised.
|
|
13
|
+
*
|
|
14
|
+
* Branches that are deliberately NOT cloned (and why):
|
|
15
|
+
* - `signal` / `abortSignal` — `AbortSignal` can't be `structuredClone`d
|
|
16
|
+
* and a shallow copy would strip the listener wiring.
|
|
17
|
+
* - `tools[name].execute` — function identity is used as a cache key
|
|
18
|
+
* downstream; cloning would break that.
|
|
19
|
+
* - schema objects (zod / JSON Schema) — large, frequently frozen,
|
|
20
|
+
* and not mutated by NeuroLink internals.
|
|
21
|
+
*/
|
|
22
|
+
export const CLONE_MUTABLE_OPTION_BRANCHES = [
|
|
23
|
+
"input",
|
|
24
|
+
"context",
|
|
25
|
+
"memory",
|
|
26
|
+
"tools",
|
|
27
|
+
"middleware",
|
|
28
|
+
"rag",
|
|
29
|
+
"csvOptions",
|
|
30
|
+
"stt",
|
|
31
|
+
"tts",
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Defensive call-isolation clone for stream() / generate()-shaped inputs.
|
|
35
|
+
*
|
|
36
|
+
* Shallow-clones the top-level options bag plus every branch listed in
|
|
37
|
+
* `CLONE_MUTABLE_OPTION_BRANCHES`. Caller-supplied objects can be reused
|
|
38
|
+
* across calls without accumulating cross-call mutations from
|
|
39
|
+
* prepareStreamOptions, applyStreamOrchestration, memory retrieval, or
|
|
40
|
+
* RAG/MCP tool injection.
|
|
41
|
+
*
|
|
42
|
+
* Unclonable / by-reference values are deliberately kept by-reference —
|
|
43
|
+
* cloning them would either fail outright (`structuredClone(AbortSignal)`)
|
|
44
|
+
* or strip behavior (function identity used as a cache key).
|
|
45
|
+
*/
|
|
46
|
+
export function cloneOptionsForCallIsolation(options) {
|
|
47
|
+
if (!options || typeof options !== "object") {
|
|
48
|
+
return options;
|
|
49
|
+
}
|
|
50
|
+
const cloned = { ...options };
|
|
51
|
+
const o = cloned;
|
|
52
|
+
for (const branch of CLONE_MUTABLE_OPTION_BRANCHES) {
|
|
53
|
+
const value = o[branch];
|
|
54
|
+
if (value && typeof value === "object") {
|
|
55
|
+
o[branch] = Array.isArray(value)
|
|
56
|
+
? [...value]
|
|
57
|
+
: { ...value };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return cloned;
|
|
61
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lifecycle callback firing + dedupe.
|
|
3
|
+
*
|
|
4
|
+
* The same thrown error can travel through multiple layers that each
|
|
5
|
+
* want to surface it to the consumer's `onError`:
|
|
6
|
+
* - LifecycleMiddleware's `wrapGenerate` / `wrapStream` catch
|
|
7
|
+
* - `BaseProvider.wrapStreamWithLifecycleCallbacks` (raw-fetch
|
|
8
|
+
* streaming providers that bypass AI SDK middleware)
|
|
9
|
+
* - `BaseProvider.fireLifecycleErrorCallback` (top-level provider catch)
|
|
10
|
+
* - `NeuroLink.generate()` / `NeuroLink.stream()` (early-resolution
|
|
11
|
+
* failures, before the language model is wrapped)
|
|
12
|
+
*
|
|
13
|
+
* Without a shared dedupe these layers would fire `onError` multiple
|
|
14
|
+
* times for one logical failure. This module stamps a non-enumerable
|
|
15
|
+
* `Symbol.for("neurolink.onErrorFired")` on the error the first time
|
|
16
|
+
* a firing site is reached; subsequent sites observe the stamp and
|
|
17
|
+
* skip their own fire.
|
|
18
|
+
*
|
|
19
|
+
* `Symbol.for` (rather than a local Symbol) so the same key works
|
|
20
|
+
* across modules — anyone who can read the symbol can read the stamp.
|
|
21
|
+
*
|
|
22
|
+
* Frozen / sealed / non-extensible errors: `Object.defineProperty`
|
|
23
|
+
* throws, we catch and proceed. Worst case is a single duplicate fire
|
|
24
|
+
* (the pre-shared-marker behaviour). `WeakSet`-based bookkeeping
|
|
25
|
+
* would handle this case cleanly but the symbol stamp is preferred
|
|
26
|
+
* for cross-realm consistency: a Symbol.for-keyed property survives
|
|
27
|
+
* structuredClone / cross-realm postMessage where a closed-over
|
|
28
|
+
* WeakSet does not.
|
|
29
|
+
*/
|
|
30
|
+
import type { LifecycleErrorPayload, OnErrorCallback } from "../types/index.js";
|
|
31
|
+
/**
|
|
32
|
+
* Returns true when `markLifecycleErrorFired` or a previous
|
|
33
|
+
* `fireOnErrorOnce` call has already stamped this error.
|
|
34
|
+
*/
|
|
35
|
+
export declare function hasLifecycleErrorFired(error: unknown): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Stamps the error as already-fired without invoking any callback.
|
|
38
|
+
* Use this from sites that already invoked `onError` via their own
|
|
39
|
+
* path (e.g. a provider-specific raw-fetch stream wrapper) so the
|
|
40
|
+
* shared dedupe still works.
|
|
41
|
+
*/
|
|
42
|
+
export declare function markLifecycleErrorFired(error: unknown): void;
|
|
43
|
+
/**
|
|
44
|
+
* Fire the consumer's `onError` once per logical failure.
|
|
45
|
+
*
|
|
46
|
+
* - No-op when `onError` is missing.
|
|
47
|
+
* - No-op when the error is already stamped (any prior layer fired).
|
|
48
|
+
* - Otherwise: stamps the error, then invokes the callback.
|
|
49
|
+
*
|
|
50
|
+
* The callback is fire-and-forget; rejections are swallowed so a
|
|
51
|
+
* faulty handler can't mask the original throw. Callers that need
|
|
52
|
+
* to AWAIT the callback (e.g. to enforce a timeout) should use
|
|
53
|
+
* `hasLifecycleErrorFired` + `markLifecycleErrorFired` directly and
|
|
54
|
+
* run the callback themselves.
|
|
55
|
+
*/
|
|
56
|
+
export declare function fireOnErrorOnce(onError: OnErrorCallback | undefined, error: unknown, payload: LifecycleErrorPayload): void;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lifecycle callback firing + dedupe.
|
|
3
|
+
*
|
|
4
|
+
* The same thrown error can travel through multiple layers that each
|
|
5
|
+
* want to surface it to the consumer's `onError`:
|
|
6
|
+
* - LifecycleMiddleware's `wrapGenerate` / `wrapStream` catch
|
|
7
|
+
* - `BaseProvider.wrapStreamWithLifecycleCallbacks` (raw-fetch
|
|
8
|
+
* streaming providers that bypass AI SDK middleware)
|
|
9
|
+
* - `BaseProvider.fireLifecycleErrorCallback` (top-level provider catch)
|
|
10
|
+
* - `NeuroLink.generate()` / `NeuroLink.stream()` (early-resolution
|
|
11
|
+
* failures, before the language model is wrapped)
|
|
12
|
+
*
|
|
13
|
+
* Without a shared dedupe these layers would fire `onError` multiple
|
|
14
|
+
* times for one logical failure. This module stamps a non-enumerable
|
|
15
|
+
* `Symbol.for("neurolink.onErrorFired")` on the error the first time
|
|
16
|
+
* a firing site is reached; subsequent sites observe the stamp and
|
|
17
|
+
* skip their own fire.
|
|
18
|
+
*
|
|
19
|
+
* `Symbol.for` (rather than a local Symbol) so the same key works
|
|
20
|
+
* across modules — anyone who can read the symbol can read the stamp.
|
|
21
|
+
*
|
|
22
|
+
* Frozen / sealed / non-extensible errors: `Object.defineProperty`
|
|
23
|
+
* throws, we catch and proceed. Worst case is a single duplicate fire
|
|
24
|
+
* (the pre-shared-marker behaviour). `WeakSet`-based bookkeeping
|
|
25
|
+
* would handle this case cleanly but the symbol stamp is preferred
|
|
26
|
+
* for cross-realm consistency: a Symbol.for-keyed property survives
|
|
27
|
+
* structuredClone / cross-realm postMessage where a closed-over
|
|
28
|
+
* WeakSet does not.
|
|
29
|
+
*/
|
|
30
|
+
const ON_ERROR_FIRED = Symbol.for("neurolink.onErrorFired");
|
|
31
|
+
function stampFired(error) {
|
|
32
|
+
try {
|
|
33
|
+
Object.defineProperty(error, ON_ERROR_FIRED, {
|
|
34
|
+
value: true,
|
|
35
|
+
enumerable: false,
|
|
36
|
+
writable: false,
|
|
37
|
+
configurable: false,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Non-extensible — fall through; worst case is a duplicate fire.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns true when `markLifecycleErrorFired` or a previous
|
|
46
|
+
* `fireOnErrorOnce` call has already stamped this error.
|
|
47
|
+
*/
|
|
48
|
+
export function hasLifecycleErrorFired(error) {
|
|
49
|
+
if (error === null || typeof error !== "object") {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return error[ON_ERROR_FIRED] === true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Stamps the error as already-fired without invoking any callback.
|
|
56
|
+
* Use this from sites that already invoked `onError` via their own
|
|
57
|
+
* path (e.g. a provider-specific raw-fetch stream wrapper) so the
|
|
58
|
+
* shared dedupe still works.
|
|
59
|
+
*/
|
|
60
|
+
export function markLifecycleErrorFired(error) {
|
|
61
|
+
if (error === null || typeof error !== "object") {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (error[ON_ERROR_FIRED] === true) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
stampFired(error);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Fire the consumer's `onError` once per logical failure.
|
|
71
|
+
*
|
|
72
|
+
* - No-op when `onError` is missing.
|
|
73
|
+
* - No-op when the error is already stamped (any prior layer fired).
|
|
74
|
+
* - Otherwise: stamps the error, then invokes the callback.
|
|
75
|
+
*
|
|
76
|
+
* The callback is fire-and-forget; rejections are swallowed so a
|
|
77
|
+
* faulty handler can't mask the original throw. Callers that need
|
|
78
|
+
* to AWAIT the callback (e.g. to enforce a timeout) should use
|
|
79
|
+
* `hasLifecycleErrorFired` + `markLifecycleErrorFired` directly and
|
|
80
|
+
* run the callback themselves.
|
|
81
|
+
*/
|
|
82
|
+
export function fireOnErrorOnce(onError, error, payload) {
|
|
83
|
+
if (typeof onError !== "function") {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (hasLifecycleErrorFired(error)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (error !== null && typeof error === "object") {
|
|
90
|
+
stampFired(error);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const result = onError(payload);
|
|
94
|
+
Promise.resolve(result).catch(() => undefined);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Consumer callback errors must not poison the original throw.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LifecycleMiddlewareConfig } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default deadline applied to consumer-supplied lifecycle callbacks
|
|
4
|
+
* (`onChunk`, `onFinish`, `onError`) when neither
|
|
5
|
+
* `LifecycleMiddlewareConfig.timeoutMs` nor the
|
|
6
|
+
* `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var is set.
|
|
7
|
+
*
|
|
8
|
+
* 5s is generous — far longer than legitimate sync logging, far
|
|
9
|
+
* shorter than a stuck network call. Callers with slow telemetry
|
|
10
|
+
* sinks should set `timeoutMs` explicitly.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_LIFECYCLE_TIMEOUT_MS = 5000;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the deadline for a single lifecycle callback invocation.
|
|
15
|
+
*
|
|
16
|
+
* Order of precedence:
|
|
17
|
+
* 1. `lifecycle.timeoutMs` from the per-call SDK config
|
|
18
|
+
* 2. `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var (also honored by the CLI)
|
|
19
|
+
* 3. `DEFAULT_LIFECYCLE_TIMEOUT_MS` (5_000)
|
|
20
|
+
*
|
|
21
|
+
* Negative / non-finite values fall through to the next source. `0`
|
|
22
|
+
* is accepted and means "no wait" (the consumer's async work is
|
|
23
|
+
* effectively fire-and-forget).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveLifecycleTimeoutMs(lifecycle?: Pick<LifecycleMiddlewareConfig, "timeoutMs"> | null): number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default deadline applied to consumer-supplied lifecycle callbacks
|
|
3
|
+
* (`onChunk`, `onFinish`, `onError`) when neither
|
|
4
|
+
* `LifecycleMiddlewareConfig.timeoutMs` nor the
|
|
5
|
+
* `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var is set.
|
|
6
|
+
*
|
|
7
|
+
* 5s is generous — far longer than legitimate sync logging, far
|
|
8
|
+
* shorter than a stuck network call. Callers with slow telemetry
|
|
9
|
+
* sinks should set `timeoutMs` explicitly.
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_LIFECYCLE_TIMEOUT_MS = 5_000;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the deadline for a single lifecycle callback invocation.
|
|
14
|
+
*
|
|
15
|
+
* Order of precedence:
|
|
16
|
+
* 1. `lifecycle.timeoutMs` from the per-call SDK config
|
|
17
|
+
* 2. `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var (also honored by the CLI)
|
|
18
|
+
* 3. `DEFAULT_LIFECYCLE_TIMEOUT_MS` (5_000)
|
|
19
|
+
*
|
|
20
|
+
* Negative / non-finite values fall through to the next source. `0`
|
|
21
|
+
* is accepted and means "no wait" (the consumer's async work is
|
|
22
|
+
* effectively fire-and-forget).
|
|
23
|
+
*/
|
|
24
|
+
export function resolveLifecycleTimeoutMs(lifecycle) {
|
|
25
|
+
if (lifecycle && typeof lifecycle.timeoutMs === "number") {
|
|
26
|
+
if (Number.isFinite(lifecycle.timeoutMs) && lifecycle.timeoutMs >= 0) {
|
|
27
|
+
return lifecycle.timeoutMs;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const raw = process.env.NEUROLINK_LIFECYCLE_TIMEOUT_MS;
|
|
31
|
+
if (raw) {
|
|
32
|
+
const parsed = Number(raw);
|
|
33
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
34
|
+
return parsed;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return DEFAULT_LIFECYCLE_TIMEOUT_MS;
|
|
38
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared log-sanitization helpers.
|
|
3
|
+
*
|
|
4
|
+
* Centralises truncate + secret-redaction patterns so every provider stays
|
|
5
|
+
* consistent and any regex improvements only need one change.
|
|
6
|
+
*
|
|
7
|
+
* Coverage:
|
|
8
|
+
* - `Authorization: Bearer <token>` (with required whitespace)
|
|
9
|
+
* - `Authorization: Token <token>` (Replicate uses this, not Bearer)
|
|
10
|
+
* - `Authorization: Basic <base64>` (D-ID and similar)
|
|
11
|
+
* - Bare tokens by known provider prefix:
|
|
12
|
+
* sk-/pk- (OpenAI, Anthropic, Stability),
|
|
13
|
+
* r8_ (Replicate), gsk_ (Groq), xai- (xAI), tgp_ (Together),
|
|
14
|
+
* fw_ (Fireworks), pplx- (Perplexity), pa- (Voyage),
|
|
15
|
+
* jina_ (Jina), fish- (Fish Audio)
|
|
16
|
+
* - Generic key=value pairs: api_key=…, access_token: …, secret_key=…
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Truncate `text` to `maxLen` chars then replace embedded secrets with `***`.
|
|
20
|
+
*
|
|
21
|
+
* Use this for free-form text logged from response/request bodies. For
|
|
22
|
+
* structured data (records, headers) prefer {@link sanitizeRecord} and
|
|
23
|
+
* {@link sanitizeHeaders} which know to redact by key name as well.
|
|
24
|
+
*
|
|
25
|
+
* @param text - Raw text to sanitize (typically an HTTP response body).
|
|
26
|
+
* @param maxLen - Maximum number of characters to keep (default 500).
|
|
27
|
+
*/
|
|
28
|
+
export declare function sanitizeForLog(text: string, maxLen?: number): string;
|
|
29
|
+
/**
|
|
30
|
+
* Recursively sanitize a record/array, returning a structurally identical
|
|
31
|
+
* value with sensitive keys redacted and string values run through
|
|
32
|
+
* {@link sanitizeForLog}.
|
|
33
|
+
*
|
|
34
|
+
* Safe to call on any JSON-shaped data. Cycles are detected and replaced
|
|
35
|
+
* with the string `"[Circular]"` to avoid infinite recursion when logging
|
|
36
|
+
* mid-stream objects that reference themselves.
|
|
37
|
+
*
|
|
38
|
+
* @param value - The value to sanitize.
|
|
39
|
+
* @param maxStringLen - Per-string truncation cap (default 1000).
|
|
40
|
+
*/
|
|
41
|
+
export declare function sanitizeRecord<T>(value: T, maxStringLen?: number): T;
|
|
42
|
+
/**
|
|
43
|
+
* Sanitize an HTTP headers object — redacts sensitive header names entirely
|
|
44
|
+
* (`***`) and applies {@link sanitizeForLog} to remaining values.
|
|
45
|
+
*
|
|
46
|
+
* Accepts both `Headers` instances and plain-object header maps so providers
|
|
47
|
+
* can log either shape uniformly.
|
|
48
|
+
*/
|
|
49
|
+
export declare function sanitizeHeaders(headers: Headers | Record<string, string | undefined> | undefined): Record<string, string>;
|