@juspay/neurolink 9.64.0 → 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 +6 -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 +33 -9
- 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 +633 -610
- package/dist/cli/commands/mcp.js +29 -0
- package/dist/cli/commands/proxy.js +24 -5
- package/dist/cli/factories/commandFactory.d.ts +11 -1
- package/dist/cli/factories/commandFactory.js +291 -38
- 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 +22 -2
- 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/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 +202 -5
- 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 +33 -9
- 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 +22 -2
- 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/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 +202 -5
- 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/middleware/builtin/lifecycle.js +39 -9
- 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 +323 -77
- 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.js +45 -6
- package/dist/lib/providers/googleNativeGemini3.d.ts +24 -1
- package/dist/lib/providers/googleNativeGemini3.js +173 -21
- package/dist/lib/providers/googleVertex.js +173 -17
- 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 +35 -23
- 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/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/generate.d.ts +62 -5
- package/dist/lib/types/index.d.ts +5 -0
- package/dist/lib/types/index.js +7 -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 +144 -1
- 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 +2 -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 +51 -8
- package/dist/lib/utils/lifecycleCallbacks.js +82 -26
- 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.js +43 -25
- package/dist/lib/utils/modelChoices.js +236 -3
- 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/safeFetch.d.ts +26 -0
- package/dist/lib/utils/safeFetch.js +83 -0
- 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/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/middleware/builtin/lifecycle.js +39 -9
- 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 +323 -77
- 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.js +45 -6
- package/dist/providers/googleNativeGemini3.d.ts +24 -1
- package/dist/providers/googleNativeGemini3.js +173 -21
- package/dist/providers/googleVertex.js +173 -17
- 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 +35 -23
- 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/avatar.d.ts +143 -0
- package/dist/types/avatar.js +19 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/generate.d.ts +62 -5
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +7 -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 +144 -1
- 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 +2 -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 +51 -8
- package/dist/utils/lifecycleCallbacks.js +82 -26
- 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.js +43 -25
- package/dist/utils/modelChoices.js +236 -3
- 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/safeFetch.d.ts +26 -0
- package/dist/utils/safeFetch.js +82 -0
- 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/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 +32 -5
|
@@ -167,7 +167,8 @@ export type StreamChunk = {
|
|
|
167
167
|
};
|
|
168
168
|
export type StreamOptions = {
|
|
169
169
|
input: {
|
|
170
|
-
text
|
|
170
|
+
/** Prompt text. Optional for media-only modes (avatar, music) that are driven by uploaded files rather than a prompt. */
|
|
171
|
+
text?: string;
|
|
171
172
|
audio?: AudioInputSpec;
|
|
172
173
|
/**
|
|
173
174
|
* Images to include in the request.
|
|
@@ -515,3 +515,16 @@ export declare function isToolResult(value: unknown): value is ToolResult;
|
|
|
515
515
|
* Type guard for tool definition
|
|
516
516
|
*/
|
|
517
517
|
export declare function isToolDefinition(value: unknown): value is ToolDefinition;
|
|
518
|
+
/**
|
|
519
|
+
* Result shape returned by the built-in `bashTool` execute function in
|
|
520
|
+
* `src/lib/agent/directTools.ts`. Centralised here per CLAUDE.md rule 2
|
|
521
|
+
* so callers (incl. the mcp-bash test suite) don't need to declare a
|
|
522
|
+
* local re-shaping of the runtime contract.
|
|
523
|
+
*/
|
|
524
|
+
export type BashToolResult = {
|
|
525
|
+
success: boolean;
|
|
526
|
+
code: number;
|
|
527
|
+
stdout: string;
|
|
528
|
+
stderr: string;
|
|
529
|
+
error?: string;
|
|
530
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video Generation Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Shared types for video generation across providers (Vertex Veo, Kling,
|
|
5
|
+
* Runway, Replicate-hosted models, etc.).
|
|
6
|
+
*
|
|
7
|
+
* The shared base shapes (`VideoOutputOptions`, `VideoGenerationResult`)
|
|
8
|
+
* are defined in `multimodal.ts` for backwards compatibility — they are
|
|
9
|
+
* re-exported here so callers can import every video-related type from a
|
|
10
|
+
* single module.
|
|
11
|
+
*
|
|
12
|
+
* @module types/video
|
|
13
|
+
*/
|
|
14
|
+
import type { VideoGenerationResult, VideoOutputOptions } from "./multimodal.js";
|
|
15
|
+
export type { VideoGenerationResult, VideoOutputOptions, } from "./multimodal.js";
|
|
16
|
+
/**
|
|
17
|
+
* Director-mode transition options.
|
|
18
|
+
*
|
|
19
|
+
* Used by handlers that support first-and-last-frame interpolation
|
|
20
|
+
* (e.g., Veo 3.1 Fast). Providers without transition support omit the
|
|
21
|
+
* `generateTransition` method on `VideoHandler`.
|
|
22
|
+
*/
|
|
23
|
+
export type VideoTransitionOptions = {
|
|
24
|
+
aspectRatio?: "9:16" | "16:9" | "1:1" | string;
|
|
25
|
+
resolution?: "720p" | "1080p";
|
|
26
|
+
audio?: boolean;
|
|
27
|
+
/** Duration of the transition clip (Veo accepts 4, 6, or 8). Default 4. */
|
|
28
|
+
durationSeconds?: 4 | 6 | 8;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Handler contract for video generation providers.
|
|
32
|
+
*
|
|
33
|
+
* Every concrete handler (`VertexVideoHandler`, `KlingVideoHandler`,
|
|
34
|
+
* `RunwayVideoHandler`, `ReplicateVideoHandler`, …) implements this
|
|
35
|
+
* interface and registers itself with `VideoProcessor.registerHandler`.
|
|
36
|
+
*
|
|
37
|
+
* Implementations MUST enforce their own timeouts. The recommended
|
|
38
|
+
* total-deadline for image-to-video predictLongRunning APIs is
|
|
39
|
+
* 3-5 minutes; the per-request fetch timeout is 30 seconds.
|
|
40
|
+
*/
|
|
41
|
+
export type VideoHandler = {
|
|
42
|
+
/**
|
|
43
|
+
* Generate a single video clip from an input image and prompt.
|
|
44
|
+
*
|
|
45
|
+
* @param image - Input image buffer (JPEG, PNG, or WebP)
|
|
46
|
+
* @param prompt - Text prompt describing desired video motion / content
|
|
47
|
+
* @param options - Resolution, length, aspect ratio, audio settings
|
|
48
|
+
* @param region - Provider-specific region override (e.g. Vertex location)
|
|
49
|
+
* @returns Buffer + metadata
|
|
50
|
+
*/
|
|
51
|
+
generate(image: Buffer, prompt: string, options: VideoOutputOptions, region?: string): Promise<VideoGenerationResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Optional — generate a transition clip between two frames (Director Mode).
|
|
54
|
+
*
|
|
55
|
+
* Providers without first-and-last-frame interpolation omit this method;
|
|
56
|
+
* `VideoProcessor.generateTransition` will surface a typed error.
|
|
57
|
+
*
|
|
58
|
+
* `durationSeconds` is on `VideoTransitionOptions` (default 4).
|
|
59
|
+
*/
|
|
60
|
+
generateTransition?(firstFrame: Buffer, lastFrame: Buffer, prompt: string, options?: VideoTransitionOptions, region?: string): Promise<Buffer>;
|
|
61
|
+
/** Validate the provider is configured (auth, base URL, etc.). */
|
|
62
|
+
isConfigured(): boolean;
|
|
63
|
+
/** Maximum video duration in seconds supported by this provider. */
|
|
64
|
+
readonly maxDurationSeconds?: number;
|
|
65
|
+
/** Supported aspect ratios. */
|
|
66
|
+
readonly supportedAspectRatios?: readonly ("9:16" | "16:9" | "1:1" | "4:3" | "3:4")[];
|
|
67
|
+
/** Supported output resolutions. */
|
|
68
|
+
readonly supportedResolutions?: readonly ("480p" | "720p" | "1080p" | "4k")[];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Kling (PiAPI) task status response.
|
|
72
|
+
*/
|
|
73
|
+
export type KlingTaskResponse = {
|
|
74
|
+
status?: string;
|
|
75
|
+
video_url?: string;
|
|
76
|
+
output?: {
|
|
77
|
+
video_url?: string;
|
|
78
|
+
};
|
|
79
|
+
error?: string;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Runway task status response.
|
|
83
|
+
*/
|
|
84
|
+
export type RunwayTaskResponse = {
|
|
85
|
+
status?: string;
|
|
86
|
+
output?: string[] | string;
|
|
87
|
+
error?: string;
|
|
88
|
+
failure?: string;
|
|
89
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video Generation Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Shared types for video generation across providers (Vertex Veo, Kling,
|
|
5
|
+
* Runway, Replicate-hosted models, etc.).
|
|
6
|
+
*
|
|
7
|
+
* The shared base shapes (`VideoOutputOptions`, `VideoGenerationResult`)
|
|
8
|
+
* are defined in `multimodal.ts` for backwards compatibility — they are
|
|
9
|
+
* re-exported here so callers can import every video-related type from a
|
|
10
|
+
* single module.
|
|
11
|
+
*
|
|
12
|
+
* @module types/video
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=video.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
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 type { AvatarHandler, AvatarOptions, AvatarResult } from "../types/index.js";
|
|
14
|
+
import { NeuroLinkError } from "./errorHandling.js";
|
|
15
|
+
/**
|
|
16
|
+
* Avatar-specific error codes.
|
|
17
|
+
*/
|
|
18
|
+
export declare const AVATAR_ERROR_CODES: {
|
|
19
|
+
readonly PROVIDER_NOT_SUPPORTED: "AVATAR_PROVIDER_NOT_SUPPORTED";
|
|
20
|
+
readonly PROVIDER_NOT_CONFIGURED: "AVATAR_PROVIDER_NOT_CONFIGURED";
|
|
21
|
+
readonly GENERATION_FAILED: "AVATAR_GENERATION_FAILED";
|
|
22
|
+
readonly POLL_TIMEOUT: "AVATAR_POLL_TIMEOUT";
|
|
23
|
+
readonly INVALID_INPUT: "AVATAR_INVALID_INPUT";
|
|
24
|
+
readonly AUDIO_REQUIRED: "AVATAR_AUDIO_REQUIRED";
|
|
25
|
+
readonly IMAGE_REQUIRED: "AVATAR_IMAGE_REQUIRED";
|
|
26
|
+
readonly AUDIO_TOO_LONG: "AVATAR_AUDIO_TOO_LONG";
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Typed error class for avatar-generation failures.
|
|
30
|
+
*/
|
|
31
|
+
export declare class AvatarError extends NeuroLinkError {
|
|
32
|
+
constructor(options: {
|
|
33
|
+
code: string;
|
|
34
|
+
message: string;
|
|
35
|
+
category?: ErrorCategory;
|
|
36
|
+
severity?: ErrorSeverity;
|
|
37
|
+
retriable?: boolean;
|
|
38
|
+
context?: Record<string, unknown>;
|
|
39
|
+
originalError?: Error;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Static processor managing the avatar handler registry.
|
|
44
|
+
*/
|
|
45
|
+
export declare class AvatarProcessor {
|
|
46
|
+
private static readonly handlers;
|
|
47
|
+
/**
|
|
48
|
+
* Register an avatar handler for a specific provider.
|
|
49
|
+
*/
|
|
50
|
+
static registerHandler(providerName: string, handler: AvatarHandler): void;
|
|
51
|
+
/**
|
|
52
|
+
* Check if a provider has a registered avatar handler.
|
|
53
|
+
*/
|
|
54
|
+
static supports(providerName: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* List the names of all registered providers.
|
|
57
|
+
*/
|
|
58
|
+
static listProviders(): string[];
|
|
59
|
+
private static getHandler;
|
|
60
|
+
private static buildSpanAttributes;
|
|
61
|
+
/**
|
|
62
|
+
* Generate an avatar video via the registered handler.
|
|
63
|
+
*
|
|
64
|
+
* @throws AvatarError on registry miss, handler-not-configured, or
|
|
65
|
+
* generation failure.
|
|
66
|
+
*/
|
|
67
|
+
static generate(provider: string, options: AvatarOptions): Promise<AvatarResult>;
|
|
68
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
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
|
+
}
|
|
172
|
+
//# sourceMappingURL=avatarProcessor.js.map
|
|
@@ -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,62 @@
|
|
|
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
|
+
}
|
|
62
|
+
//# sourceMappingURL=cloneOptions.js.map
|
|
@@ -1,13 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* callback. The same thrown error can travel through both the middleware
|
|
4
|
-
* pipeline (which fires `onError` then re-throws) and the top-level
|
|
5
|
-
* generate/stream catch in `neurolink.ts` — without a guard, the consumer
|
|
6
|
-
* callback would fire twice for one logical failure.
|
|
2
|
+
* Lifecycle callback firing + dedupe.
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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.
|
|
11
29
|
*/
|
|
12
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
|
+
*/
|
|
13
56
|
export declare function fireOnErrorOnce(onError: OnErrorCallback | undefined, error: unknown, payload: LifecycleErrorPayload): void;
|
|
@@ -1,37 +1,93 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* callback. The same thrown error can travel through both the middleware
|
|
4
|
-
* pipeline (which fires `onError` then re-throws) and the top-level
|
|
5
|
-
* generate/stream catch in `neurolink.ts` — without a guard, the consumer
|
|
6
|
-
* callback would fire twice for one logical failure.
|
|
2
|
+
* Lifecycle callback firing + dedupe.
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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.
|
|
11
29
|
*/
|
|
12
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
|
+
*/
|
|
13
82
|
export function fireOnErrorOnce(onError, error, payload) {
|
|
14
83
|
if (typeof onError !== "function") {
|
|
15
84
|
return;
|
|
16
85
|
}
|
|
17
|
-
if (error
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
Object.defineProperty(error, ON_ERROR_FIRED, {
|
|
24
|
-
value: true,
|
|
25
|
-
enumerable: false,
|
|
26
|
-
writable: false,
|
|
27
|
-
configurable: false,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// Frozen/sealed error object — proceed without the stamp; the
|
|
32
|
-
// worst case is a single duplicate fire if multiple sites observe
|
|
33
|
-
// the same frozen value, which is the pre-existing behaviour.
|
|
34
|
-
}
|
|
86
|
+
if (hasLifecycleErrorFired(error)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (error !== null && typeof error === "object") {
|
|
90
|
+
stampFired(error);
|
|
35
91
|
}
|
|
36
92
|
try {
|
|
37
93
|
const result = onError(payload);
|