@juspay/neurolink 9.41.0 → 9.42.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 +8 -0
- package/README.md +7 -1
- package/dist/auth/anthropicOAuth.d.ts +18 -3
- package/dist/auth/anthropicOAuth.js +149 -4
- package/dist/auth/providers/firebase.js +5 -1
- package/dist/auth/providers/jwt.js +5 -1
- package/dist/auth/providers/workos.js +5 -1
- package/dist/auth/sessionManager.d.ts +1 -1
- package/dist/auth/sessionManager.js +58 -27
- package/dist/browser/neurolink.min.js +354 -334
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.js +188 -181
- package/dist/cli/commands/proxy.d.ts +2 -1
- package/dist/cli/commands/proxy.js +713 -431
- package/dist/cli/commands/task.js +3 -0
- package/dist/cli/factories/commandFactory.d.ts +2 -0
- package/dist/cli/factories/commandFactory.js +38 -0
- package/dist/cli/parser.js +4 -3
- package/dist/client/aiSdkAdapter.js +3 -0
- package/dist/client/streamingClient.js +30 -10
- package/dist/core/baseProvider.d.ts +6 -1
- package/dist/core/baseProvider.js +208 -230
- package/dist/core/factory.d.ts +3 -0
- package/dist/core/factory.js +138 -188
- package/dist/core/modules/GenerationHandler.js +3 -2
- package/dist/core/redisConversationMemoryManager.js +7 -3
- package/dist/evaluation/BatchEvaluator.js +4 -1
- package/dist/evaluation/hooks/observabilityHooks.js +5 -3
- package/dist/evaluation/pipeline/evaluationPipeline.d.ts +3 -2
- package/dist/evaluation/pipeline/evaluationPipeline.js +24 -9
- package/dist/evaluation/pipeline/strategies/batchStrategy.js +6 -3
- package/dist/evaluation/pipeline/strategies/samplingStrategy.js +18 -10
- package/dist/evaluation/scorers/scorerRegistry.d.ts +3 -0
- package/dist/evaluation/scorers/scorerRegistry.js +353 -282
- package/dist/lib/auth/anthropicOAuth.d.ts +18 -3
- package/dist/lib/auth/anthropicOAuth.js +149 -4
- package/dist/lib/auth/providers/firebase.js +5 -1
- package/dist/lib/auth/providers/jwt.js +5 -1
- package/dist/lib/auth/providers/workos.js +5 -1
- package/dist/lib/auth/sessionManager.d.ts +1 -1
- package/dist/lib/auth/sessionManager.js +58 -27
- package/dist/lib/client/aiSdkAdapter.js +3 -0
- package/dist/lib/client/streamingClient.js +30 -10
- package/dist/lib/core/baseProvider.d.ts +6 -1
- package/dist/lib/core/baseProvider.js +208 -230
- package/dist/lib/core/factory.d.ts +3 -0
- package/dist/lib/core/factory.js +138 -188
- package/dist/lib/core/modules/GenerationHandler.js +3 -2
- package/dist/lib/core/redisConversationMemoryManager.js +7 -3
- package/dist/lib/evaluation/BatchEvaluator.js +4 -1
- package/dist/lib/evaluation/hooks/observabilityHooks.js +5 -3
- package/dist/lib/evaluation/pipeline/evaluationPipeline.d.ts +3 -2
- package/dist/lib/evaluation/pipeline/evaluationPipeline.js +24 -9
- package/dist/lib/evaluation/pipeline/strategies/batchStrategy.js +6 -3
- package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.js +18 -10
- package/dist/lib/evaluation/scorers/scorerRegistry.d.ts +3 -0
- package/dist/lib/evaluation/scorers/scorerRegistry.js +353 -282
- package/dist/lib/mcp/toolRegistry.d.ts +2 -0
- package/dist/lib/mcp/toolRegistry.js +32 -31
- package/dist/lib/neurolink.d.ts +41 -2
- package/dist/lib/neurolink.js +1616 -1681
- package/dist/lib/observability/otelBridge.d.ts +2 -2
- package/dist/lib/observability/otelBridge.js +12 -3
- package/dist/lib/providers/amazonBedrock.js +2 -4
- package/dist/lib/providers/anthropic.d.ts +9 -5
- package/dist/lib/providers/anthropic.js +19 -14
- package/dist/lib/providers/anthropicBaseProvider.d.ts +3 -3
- package/dist/lib/providers/anthropicBaseProvider.js +5 -4
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +5 -4
- package/dist/lib/providers/googleAiStudio.js +30 -6
- package/dist/lib/providers/googleVertex.d.ts +10 -0
- package/dist/lib/providers/googleVertex.js +437 -423
- package/dist/lib/providers/huggingFace.d.ts +3 -3
- package/dist/lib/providers/huggingFace.js +6 -8
- package/dist/lib/providers/litellm.d.ts +1 -0
- package/dist/lib/providers/litellm.js +76 -55
- package/dist/lib/providers/mistral.js +2 -1
- package/dist/lib/providers/ollama.js +93 -23
- package/dist/lib/providers/openAI.d.ts +2 -0
- package/dist/lib/providers/openAI.js +141 -141
- package/dist/lib/providers/openRouter.js +2 -1
- package/dist/lib/providers/openaiCompatible.d.ts +4 -4
- package/dist/lib/providers/openaiCompatible.js +4 -4
- package/dist/lib/proxy/claudeFormat.d.ts +3 -2
- package/dist/lib/proxy/claudeFormat.js +27 -14
- package/dist/lib/proxy/cloaking/plugins/sessionIdentity.d.ts +2 -6
- package/dist/lib/proxy/cloaking/plugins/sessionIdentity.js +9 -33
- package/dist/lib/proxy/modelRouter.js +3 -0
- package/dist/lib/proxy/oauthFetch.d.ts +1 -1
- package/dist/lib/proxy/oauthFetch.js +289 -316
- package/dist/lib/proxy/proxyConfig.js +46 -24
- package/dist/lib/proxy/proxyEnv.d.ts +19 -0
- package/dist/lib/proxy/proxyEnv.js +73 -0
- package/dist/lib/proxy/proxyFetch.js +291 -217
- package/dist/lib/proxy/proxyTracer.d.ts +133 -0
- package/dist/lib/proxy/proxyTracer.js +645 -0
- package/dist/lib/proxy/rawStreamCapture.d.ts +10 -0
- package/dist/lib/proxy/rawStreamCapture.js +83 -0
- package/dist/lib/proxy/requestLogger.d.ts +32 -5
- package/dist/lib/proxy/requestLogger.js +503 -47
- package/dist/lib/proxy/sseInterceptor.d.ts +97 -0
- package/dist/lib/proxy/sseInterceptor.js +427 -0
- package/dist/lib/proxy/usageStats.d.ts +4 -3
- package/dist/lib/proxy/usageStats.js +25 -12
- package/dist/lib/rag/chunkers/MarkdownChunker.js +13 -5
- package/dist/lib/rag/chunking/markdownChunker.js +15 -6
- package/dist/lib/server/routes/claudeProxyRoutes.d.ts +17 -3
- package/dist/lib/server/routes/claudeProxyRoutes.js +3032 -1349
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +7 -1
- package/dist/lib/services/server/ai/observability/instrumentation.js +337 -161
- package/dist/lib/tasks/backends/bullmqBackend.d.ts +1 -0
- package/dist/lib/tasks/backends/bullmqBackend.js +35 -22
- package/dist/lib/tasks/store/redisTaskStore.d.ts +1 -0
- package/dist/lib/tasks/store/redisTaskStore.js +54 -39
- package/dist/lib/tasks/taskManager.d.ts +5 -0
- package/dist/lib/tasks/taskManager.js +158 -30
- package/dist/lib/telemetry/index.d.ts +2 -1
- package/dist/lib/telemetry/index.js +2 -1
- package/dist/lib/telemetry/telemetryService.d.ts +3 -0
- package/dist/lib/telemetry/telemetryService.js +69 -5
- package/dist/lib/types/cli.d.ts +10 -0
- package/dist/lib/types/proxyTypes.d.ts +160 -5
- package/dist/lib/types/streamTypes.d.ts +25 -3
- package/dist/lib/utils/messageBuilder.js +3 -2
- package/dist/lib/utils/providerHealth.d.ts +19 -0
- package/dist/lib/utils/providerHealth.js +279 -33
- package/dist/lib/utils/providerUtils.js +17 -22
- package/dist/lib/utils/toolChoice.d.ts +4 -0
- package/dist/lib/utils/toolChoice.js +7 -0
- package/dist/mcp/toolRegistry.d.ts +2 -0
- package/dist/mcp/toolRegistry.js +32 -31
- package/dist/neurolink.d.ts +41 -2
- package/dist/neurolink.js +1616 -1681
- package/dist/observability/otelBridge.d.ts +2 -2
- package/dist/observability/otelBridge.js +12 -3
- package/dist/providers/amazonBedrock.js +2 -4
- package/dist/providers/anthropic.d.ts +9 -5
- package/dist/providers/anthropic.js +19 -14
- package/dist/providers/anthropicBaseProvider.d.ts +3 -3
- package/dist/providers/anthropicBaseProvider.js +5 -4
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +5 -4
- package/dist/providers/googleAiStudio.js +30 -6
- package/dist/providers/googleVertex.d.ts +10 -0
- package/dist/providers/googleVertex.js +437 -423
- package/dist/providers/huggingFace.d.ts +3 -3
- package/dist/providers/huggingFace.js +6 -7
- package/dist/providers/litellm.d.ts +1 -0
- package/dist/providers/litellm.js +76 -55
- package/dist/providers/mistral.js +2 -1
- package/dist/providers/ollama.js +93 -23
- package/dist/providers/openAI.d.ts +2 -0
- package/dist/providers/openAI.js +141 -141
- package/dist/providers/openRouter.js +2 -1
- package/dist/providers/openaiCompatible.d.ts +4 -4
- package/dist/providers/openaiCompatible.js +4 -3
- package/dist/proxy/claudeFormat.d.ts +3 -2
- package/dist/proxy/claudeFormat.js +27 -14
- package/dist/proxy/cloaking/plugins/sessionIdentity.d.ts +2 -6
- package/dist/proxy/cloaking/plugins/sessionIdentity.js +9 -33
- package/dist/proxy/modelRouter.js +3 -0
- package/dist/proxy/oauthFetch.d.ts +1 -1
- package/dist/proxy/oauthFetch.js +289 -316
- package/dist/proxy/proxyConfig.js +46 -24
- package/dist/proxy/proxyEnv.d.ts +19 -0
- package/dist/proxy/proxyEnv.js +72 -0
- package/dist/proxy/proxyFetch.js +291 -217
- package/dist/proxy/proxyTracer.d.ts +133 -0
- package/dist/proxy/proxyTracer.js +644 -0
- package/dist/proxy/rawStreamCapture.d.ts +10 -0
- package/dist/proxy/rawStreamCapture.js +82 -0
- package/dist/proxy/requestLogger.d.ts +32 -5
- package/dist/proxy/requestLogger.js +503 -47
- package/dist/proxy/sseInterceptor.d.ts +97 -0
- package/dist/proxy/sseInterceptor.js +426 -0
- package/dist/proxy/usageStats.d.ts +4 -3
- package/dist/proxy/usageStats.js +25 -12
- package/dist/rag/chunkers/MarkdownChunker.js +13 -5
- package/dist/rag/chunking/markdownChunker.js +15 -6
- package/dist/server/routes/claudeProxyRoutes.d.ts +17 -3
- package/dist/server/routes/claudeProxyRoutes.js +3032 -1349
- package/dist/services/server/ai/observability/instrumentation.d.ts +7 -1
- package/dist/services/server/ai/observability/instrumentation.js +337 -161
- package/dist/tasks/backends/bullmqBackend.d.ts +1 -0
- package/dist/tasks/backends/bullmqBackend.js +35 -22
- package/dist/tasks/store/redisTaskStore.d.ts +1 -0
- package/dist/tasks/store/redisTaskStore.js +54 -39
- package/dist/tasks/taskManager.d.ts +5 -0
- package/dist/tasks/taskManager.js +158 -30
- package/dist/telemetry/index.d.ts +2 -1
- package/dist/telemetry/index.js +2 -1
- package/dist/telemetry/telemetryService.d.ts +3 -0
- package/dist/telemetry/telemetryService.js +69 -5
- package/dist/types/cli.d.ts +10 -0
- package/dist/types/proxyTypes.d.ts +160 -5
- package/dist/types/streamTypes.d.ts +25 -3
- package/dist/utils/messageBuilder.js +3 -2
- package/dist/utils/providerHealth.d.ts +19 -0
- package/dist/utils/providerHealth.js +279 -33
- package/dist/utils/providerUtils.js +18 -22
- package/dist/utils/toolChoice.d.ts +4 -0
- package/dist/utils/toolChoice.js +6 -0
- package/docs/assets/dashboards/neurolink-proxy-observability-dashboard.json +6609 -0
- package/docs/changelog.md +252 -0
- package/package.json +19 -2
- package/scripts/observability/check-proxy-telemetry.mjs +235 -0
- package/scripts/observability/docker-compose.proxy-observability.yaml +55 -0
- package/scripts/observability/import-openobserve-dashboard.mjs +240 -0
- package/scripts/observability/manage-local-openobserve.sh +215 -0
- package/scripts/observability/otel-collector.proxy-observability.yaml +78 -0
- package/scripts/observability/proxy-observability.env.example +23 -0
|
@@ -11,6 +11,7 @@ export declare class TelemetryService {
|
|
|
11
11
|
private tracerProvider?;
|
|
12
12
|
private enabled;
|
|
13
13
|
private initialized;
|
|
14
|
+
private usingExternalTracerProvider;
|
|
14
15
|
private meter?;
|
|
15
16
|
private tracer?;
|
|
16
17
|
private aiRequestCounter?;
|
|
@@ -29,6 +30,8 @@ export declare class TelemetryService {
|
|
|
29
30
|
private constructor();
|
|
30
31
|
static getInstance(): TelemetryService;
|
|
31
32
|
private isTelemetryEnabled;
|
|
33
|
+
private hasExternalTracerProvider;
|
|
34
|
+
private adoptExternalTracerProvider;
|
|
32
35
|
private initializeTelemetry;
|
|
33
36
|
private initializeMetrics;
|
|
34
37
|
initialize(): Promise<void>;
|
|
@@ -9,6 +9,7 @@ export class TelemetryService {
|
|
|
9
9
|
tracerProvider;
|
|
10
10
|
enabled = false;
|
|
11
11
|
initialized = false;
|
|
12
|
+
usingExternalTracerProvider = false;
|
|
12
13
|
meter;
|
|
13
14
|
tracer;
|
|
14
15
|
// Optional Metrics (only created when enabled)
|
|
@@ -43,11 +44,52 @@ export class TelemetryService {
|
|
|
43
44
|
return TelemetryService.instance;
|
|
44
45
|
}
|
|
45
46
|
isTelemetryEnabled() {
|
|
46
|
-
return (
|
|
47
|
+
return (this.hasExternalTracerProvider() ||
|
|
48
|
+
process.env.NEUROLINK_TELEMETRY_ENABLED === "true" ||
|
|
47
49
|
process.env.OTEL_EXPORTER_OTLP_ENDPOINT !== undefined);
|
|
48
50
|
}
|
|
51
|
+
hasExternalTracerProvider() {
|
|
52
|
+
try {
|
|
53
|
+
const provider = trace.getTracerProvider();
|
|
54
|
+
if (!provider) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const providerName = provider.constructor?.name || "";
|
|
58
|
+
if (providerName &&
|
|
59
|
+
providerName !== "ProxyTracerProvider" &&
|
|
60
|
+
providerName !== "NoopTracerProvider") {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const delegate = typeof provider.getDelegate === "function"
|
|
64
|
+
? provider.getDelegate()
|
|
65
|
+
: provider._delegate;
|
|
66
|
+
const delegateName = delegate?.constructor?.name || "";
|
|
67
|
+
return Boolean(delegateName && delegateName !== "NoopTracerProvider");
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.warn("[Telemetry] Failed checking for external TracerProvider", {
|
|
71
|
+
error: error instanceof Error ? error.message : String(error),
|
|
72
|
+
});
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
adoptExternalTracerProvider(reason) {
|
|
77
|
+
this.usingExternalTracerProvider = true;
|
|
78
|
+
this.tracerProvider = undefined;
|
|
79
|
+
this.meter = metrics.getMeter("neurolink-ai");
|
|
80
|
+
this.tracer = trace.getTracer("neurolink-ai");
|
|
81
|
+
this.initializeMetrics();
|
|
82
|
+
logger.debug("[Telemetry] Reusing externally managed TracerProvider", {
|
|
83
|
+
reason,
|
|
84
|
+
endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
49
87
|
initializeTelemetry() {
|
|
50
88
|
try {
|
|
89
|
+
if (this.hasExternalTracerProvider()) {
|
|
90
|
+
this.adoptExternalTracerProvider("global tracer provider already registered");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
51
93
|
const resource = resourceFromAttributes({
|
|
52
94
|
[ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME || "neurolink-ai",
|
|
53
95
|
[ATTR_SERVICE_VERSION]: process.env.OTEL_SERVICE_VERSION || "3.0.1",
|
|
@@ -61,13 +103,23 @@ export class TelemetryService {
|
|
|
61
103
|
resource,
|
|
62
104
|
spanProcessors: [new BatchSpanProcessor(exporter)],
|
|
63
105
|
});
|
|
64
|
-
trace.setGlobalTracerProvider(this.tracerProvider);
|
|
65
106
|
this.meter = metrics.getMeter("neurolink-ai");
|
|
66
|
-
this.tracer =
|
|
107
|
+
this.tracer = this.tracerProvider.getTracer("neurolink-ai");
|
|
67
108
|
this.initializeMetrics();
|
|
68
|
-
logger.debug("[Telemetry] Initialized
|
|
109
|
+
logger.debug("[Telemetry] Initialized local telemetry exporter", {
|
|
110
|
+
endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
111
|
+
globalTracerProviderOwnedBy: "observability/instrumentation",
|
|
112
|
+
});
|
|
69
113
|
}
|
|
70
114
|
catch (error) {
|
|
115
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
116
|
+
const isDuplicateRegistration = errorMessage.includes("duplicate registration") ||
|
|
117
|
+
errorMessage.includes("already registered") ||
|
|
118
|
+
errorMessage.includes("already set");
|
|
119
|
+
if (isDuplicateRegistration && this.hasExternalTracerProvider()) {
|
|
120
|
+
this.adoptExternalTracerProvider("duplicate global tracer registration detected");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
71
123
|
logger.error("[Telemetry] Failed to initialize:", error);
|
|
72
124
|
this.enabled = false;
|
|
73
125
|
}
|
|
@@ -105,6 +157,16 @@ export class TelemetryService {
|
|
|
105
157
|
if (!this.enabled) {
|
|
106
158
|
return;
|
|
107
159
|
}
|
|
160
|
+
if (this.usingExternalTracerProvider) {
|
|
161
|
+
this.initialized = true;
|
|
162
|
+
logger.debug("[Telemetry] External TracerProvider already initialized by host");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!this.tracerProvider) {
|
|
166
|
+
this.initialized = true;
|
|
167
|
+
logger.debug("[Telemetry] Tracer provider already prepared during constructor");
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
108
170
|
try {
|
|
109
171
|
// Register AsyncLocalStorage context manager for proper parent-child
|
|
110
172
|
// span relationships across async boundaries (required for startActiveSpan)
|
|
@@ -308,7 +370,9 @@ export class TelemetryService {
|
|
|
308
370
|
}
|
|
309
371
|
// Cleanup
|
|
310
372
|
async shutdown() {
|
|
311
|
-
if (this.enabled &&
|
|
373
|
+
if (this.enabled &&
|
|
374
|
+
this.tracerProvider &&
|
|
375
|
+
!this.usingExternalTracerProvider) {
|
|
312
376
|
try {
|
|
313
377
|
await this.tracerProvider.shutdown();
|
|
314
378
|
this.initialized = false;
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -763,6 +763,8 @@ export type ProxyStartArgs = {
|
|
|
763
763
|
quiet?: boolean;
|
|
764
764
|
debug?: boolean;
|
|
765
765
|
config?: string;
|
|
766
|
+
envFile?: string;
|
|
767
|
+
passthrough?: boolean;
|
|
766
768
|
};
|
|
767
769
|
/** Arguments accepted by `neurolink proxy status` */
|
|
768
770
|
export type ProxyStatusArgs = {
|
|
@@ -779,6 +781,11 @@ export type ProxyGuardArgs = {
|
|
|
779
781
|
pollIntervalMs?: number;
|
|
780
782
|
quiet?: boolean;
|
|
781
783
|
};
|
|
784
|
+
/** Arguments accepted by `neurolink proxy telemetry <subcommand>` */
|
|
785
|
+
export type ProxyTelemetryArgs = {
|
|
786
|
+
action?: "setup" | "start" | "stop" | "status" | "logs" | "import-dashboard";
|
|
787
|
+
quiet?: boolean;
|
|
788
|
+
};
|
|
782
789
|
/** A fallback chain entry (serialisable subset of FallbackEntry) */
|
|
783
790
|
export type FallbackInfo = {
|
|
784
791
|
provider: string;
|
|
@@ -791,12 +798,15 @@ export type ProxyState = {
|
|
|
791
798
|
host: string;
|
|
792
799
|
strategy: string;
|
|
793
800
|
startTime: string;
|
|
801
|
+
envFile?: string;
|
|
794
802
|
/** Fallback chain from proxy config (persisted at start time) */
|
|
795
803
|
fallbackChain?: FallbackInfo[];
|
|
796
804
|
/** Optional fail-open guard PID that reverts Claude settings if proxy dies */
|
|
797
805
|
guardPid?: number;
|
|
798
806
|
/** How the proxy was launched — "launchd" if installed as service, "manual" otherwise */
|
|
799
807
|
managedBy?: "launchd" | "manual";
|
|
808
|
+
/** Whether the proxy is running in transparent passthrough mode */
|
|
809
|
+
passthrough?: boolean;
|
|
800
810
|
};
|
|
801
811
|
/** Stored credentials for an authenticated provider. */
|
|
802
812
|
export type StoredCredentials = {
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* - src/lib/proxy/accountQuota.ts (quota type)
|
|
14
14
|
* - src/lib/server/routes/claudeProxyRoutes.ts (runtime state, deps)
|
|
15
15
|
*/
|
|
16
|
+
import type { Span } from "@opentelemetry/api";
|
|
17
|
+
import type { ProxyTracer } from "../proxy/proxyTracer.js";
|
|
16
18
|
/**
|
|
17
19
|
* Type describing the ModelRouter contract.
|
|
18
20
|
* Defined here to avoid a circular dependency between types and implementation.
|
|
@@ -239,10 +241,11 @@ export type ParsedClaudeRequest = {
|
|
|
239
241
|
role: string;
|
|
240
242
|
content: string;
|
|
241
243
|
}>;
|
|
242
|
-
/** Tools
|
|
244
|
+
/** Tools translated to AI SDK-compatible shape for provider fallback. */
|
|
243
245
|
tools: Record<string, {
|
|
244
|
-
description
|
|
245
|
-
|
|
246
|
+
description?: string;
|
|
247
|
+
inputSchema: unknown;
|
|
248
|
+
execute?: (...args: unknown[]) => unknown;
|
|
246
249
|
}>;
|
|
247
250
|
/**
|
|
248
251
|
* Tool choice mapping from Claude format.
|
|
@@ -360,6 +363,14 @@ export type TlsFingerprintOptions = {
|
|
|
360
363
|
/** Whether the stub should log a warning that it is a no-op. */
|
|
361
364
|
warnOnUse?: boolean;
|
|
362
365
|
};
|
|
366
|
+
/**
|
|
367
|
+
* Proxy operating mode:
|
|
368
|
+
* - "full" — managed accounts, retry, rotation, polyfill (default)
|
|
369
|
+
* - "passthrough" — no polyfill/retry/rotation, but body is still parsed and re-serialized
|
|
370
|
+
* - "transparent" — zero-mutation byte relay: raw body forwarded as-is, minimal header filtering,
|
|
371
|
+
* SSE interceptor for cache metrics only (bytes pass through unmodified)
|
|
372
|
+
*/
|
|
373
|
+
export type ProxyMode = "full" | "passthrough" | "transparent";
|
|
363
374
|
export type RouteResult = {
|
|
364
375
|
provider: string | null;
|
|
365
376
|
model: string;
|
|
@@ -421,21 +432,165 @@ export type RequestLogEntry = {
|
|
|
421
432
|
errorMessage?: string;
|
|
422
433
|
inputTokens?: number;
|
|
423
434
|
outputTokens?: number;
|
|
435
|
+
cacheCreationTokens?: number;
|
|
436
|
+
cacheReadTokens?: number;
|
|
437
|
+
/** OTel trace ID for correlation with distributed traces */
|
|
438
|
+
traceId?: string;
|
|
439
|
+
/** OTel span ID for correlation with distributed traces */
|
|
440
|
+
spanId?: string;
|
|
441
|
+
};
|
|
442
|
+
export type RequestAttemptLogEntry = {
|
|
443
|
+
timestamp: string;
|
|
444
|
+
requestId: string;
|
|
445
|
+
attempt: number;
|
|
446
|
+
method: string;
|
|
447
|
+
path: string;
|
|
448
|
+
model: string;
|
|
449
|
+
stream: boolean;
|
|
450
|
+
toolCount: number;
|
|
451
|
+
account: string;
|
|
452
|
+
accountType: string;
|
|
453
|
+
responseStatus: number;
|
|
454
|
+
responseTimeMs: number;
|
|
455
|
+
errorType?: string;
|
|
456
|
+
errorMessage?: string;
|
|
457
|
+
inputTokens?: number;
|
|
458
|
+
outputTokens?: number;
|
|
459
|
+
cacheCreationTokens?: number;
|
|
460
|
+
cacheReadTokens?: number;
|
|
461
|
+
/** OTel trace ID for correlation with distributed traces */
|
|
462
|
+
traceId?: string;
|
|
463
|
+
/** OTel span ID for correlation with distributed traces */
|
|
464
|
+
spanId?: string;
|
|
465
|
+
};
|
|
466
|
+
export type ProxyBodyCaptureInput = {
|
|
467
|
+
phase: string;
|
|
468
|
+
headers?: Record<string, string>;
|
|
469
|
+
body?: unknown;
|
|
470
|
+
bodySize?: number;
|
|
471
|
+
contentType?: string;
|
|
472
|
+
responseStatus?: number;
|
|
473
|
+
durationMs?: number;
|
|
474
|
+
account?: string;
|
|
475
|
+
accountType?: string;
|
|
476
|
+
attempt?: number;
|
|
477
|
+
metadata?: Record<string, unknown>;
|
|
478
|
+
};
|
|
479
|
+
export type ProxyBodyCaptureLogger = (capture: ProxyBodyCaptureInput) => void;
|
|
480
|
+
export type ClaudeFinalRequestLogger = (status: number, accountLabel: string, accountType: string, errorType?: string, errorMessage?: string, extra?: {
|
|
481
|
+
inputTokens?: number;
|
|
482
|
+
outputTokens?: number;
|
|
483
|
+
cacheCreationTokens?: number;
|
|
484
|
+
cacheReadTokens?: number;
|
|
485
|
+
}) => void;
|
|
486
|
+
export type ClaudeLoggedErrorBuilder = (status: number, message: string, errorType?: string, extra?: {
|
|
487
|
+
account?: string;
|
|
488
|
+
accountType?: string;
|
|
489
|
+
attempt?: number;
|
|
490
|
+
}) => ClaudeErrorResponse;
|
|
491
|
+
export type ClaudeRequestRuntimeContext = {
|
|
492
|
+
tracer?: ProxyTracer;
|
|
493
|
+
requestStartTime: number;
|
|
494
|
+
logProxyBody: ProxyBodyCaptureLogger;
|
|
495
|
+
logFinalRequest: ClaudeFinalRequestLogger;
|
|
496
|
+
buildLoggedClaudeError: ClaudeLoggedErrorBuilder;
|
|
497
|
+
};
|
|
498
|
+
export type AnthropicAttemptLogger = (status: number, errorType?: string, errorMessage?: string, extra?: {
|
|
499
|
+
inputTokens?: number;
|
|
500
|
+
outputTokens?: number;
|
|
501
|
+
cacheCreationTokens?: number;
|
|
502
|
+
cacheReadTokens?: number;
|
|
503
|
+
}) => void;
|
|
504
|
+
export type AnthropicLoopState = {
|
|
505
|
+
lastError: unknown;
|
|
506
|
+
sawRateLimit: boolean;
|
|
507
|
+
sawNetworkError: boolean;
|
|
508
|
+
sawTransientFailure: boolean;
|
|
509
|
+
invalidRequestFailure: {
|
|
510
|
+
status: number;
|
|
511
|
+
body: string;
|
|
512
|
+
contentType?: string;
|
|
513
|
+
} | null;
|
|
514
|
+
authFailureMessage: string | null;
|
|
515
|
+
attemptNumber: number;
|
|
516
|
+
};
|
|
517
|
+
export type AnthropicUpstreamBody = {
|
|
518
|
+
bodyStr: string;
|
|
519
|
+
sessionId?: string;
|
|
520
|
+
};
|
|
521
|
+
export type AnthropicUpstreamBodyBuilder = (token: string) => AnthropicUpstreamBody;
|
|
522
|
+
export type LoadedClaudeAccountContext = {
|
|
523
|
+
accounts: ProxyPassthroughAccount[];
|
|
524
|
+
enabledAccounts: ProxyPassthroughAccount[];
|
|
525
|
+
orderedAccounts: ProxyPassthroughAccount[];
|
|
526
|
+
bodyStr: string;
|
|
527
|
+
requestStart: number;
|
|
528
|
+
toolCount: number;
|
|
529
|
+
url: string;
|
|
530
|
+
clientHeaders: Record<string, string | undefined>;
|
|
531
|
+
isClaudeClientRequest: boolean;
|
|
532
|
+
};
|
|
533
|
+
export type AnthropicSuccessResult = {
|
|
534
|
+
retryNextAccount: true;
|
|
535
|
+
} | {
|
|
536
|
+
response: Response | unknown;
|
|
537
|
+
};
|
|
538
|
+
export type AnthropicAuthRetryResult = {
|
|
539
|
+
response?: Response | unknown;
|
|
540
|
+
continueLoop: boolean;
|
|
541
|
+
lastError: unknown;
|
|
542
|
+
authFailureMessage: string | null;
|
|
543
|
+
sawRateLimit: boolean;
|
|
544
|
+
sawTransientFailure: boolean;
|
|
545
|
+
sawNetworkError: boolean;
|
|
546
|
+
upstreamSpan?: Span;
|
|
547
|
+
};
|
|
548
|
+
export type AnthropicNonOkResult = {
|
|
549
|
+
response?: Response | unknown;
|
|
550
|
+
continueLoop: boolean;
|
|
551
|
+
lastError: unknown;
|
|
552
|
+
authFailureMessage: string | null;
|
|
553
|
+
sawTransientFailure: boolean;
|
|
554
|
+
invalidRequestFailure: {
|
|
555
|
+
status: number;
|
|
556
|
+
body: string;
|
|
557
|
+
contentType?: string;
|
|
558
|
+
} | null;
|
|
559
|
+
upstreamSpan?: Span;
|
|
560
|
+
};
|
|
561
|
+
export type PreparedAnthropicAccountAttempt = {
|
|
562
|
+
continueLoop: boolean;
|
|
563
|
+
lastError: unknown;
|
|
564
|
+
authFailureMessage: string | null;
|
|
565
|
+
headers?: Record<string, string>;
|
|
566
|
+
buildUpstreamBody?: AnthropicUpstreamBodyBuilder;
|
|
567
|
+
finalBodyStr?: string;
|
|
568
|
+
fetchStartMs?: number;
|
|
569
|
+
upstreamSpan?: Span;
|
|
570
|
+
};
|
|
571
|
+
export type AnthropicUpstreamFetchResult = {
|
|
572
|
+
continueLoop: boolean;
|
|
573
|
+
response?: Response;
|
|
574
|
+
lastError: unknown;
|
|
575
|
+
sawRateLimit: boolean;
|
|
576
|
+
sawNetworkError: boolean;
|
|
577
|
+
upstreamSpan?: Span;
|
|
424
578
|
};
|
|
425
579
|
export type AccountStats = {
|
|
426
580
|
label: string;
|
|
427
581
|
type: string;
|
|
428
|
-
|
|
582
|
+
attemptCount: number;
|
|
429
583
|
successCount: number;
|
|
430
584
|
errorCount: number;
|
|
431
585
|
rateLimitCount: number;
|
|
432
|
-
|
|
586
|
+
lastAttemptAt: number;
|
|
433
587
|
lastErrorAt?: number;
|
|
434
588
|
currentBackoffLevel: number;
|
|
435
589
|
coolingUntil?: number;
|
|
436
590
|
};
|
|
437
591
|
export type ProxyStats = {
|
|
438
592
|
startedAt: number;
|
|
593
|
+
totalAttempts: number;
|
|
439
594
|
totalRequests: number;
|
|
440
595
|
totalSuccess: number;
|
|
441
596
|
totalErrors: number;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { Tool } from "ai";
|
|
1
|
+
import type { LanguageModel, StepResult, Tool, ToolChoice } from "ai";
|
|
2
2
|
import type { AIProviderName } from "../constants/enums.js";
|
|
3
3
|
import type { EvaluationData } from "../index.js";
|
|
4
4
|
import type { RAGConfig } from "../rag/types.js";
|
|
5
5
|
import type { AnalyticsData, ToolExecutionEvent, ToolExecutionSummary } from "../types/index.js";
|
|
6
|
-
import type { MiddlewareFactoryOptions,
|
|
6
|
+
import type { MiddlewareFactoryOptions, OnChunkCallback, OnErrorCallback, OnFinishCallback } from "../types/middlewareTypes.js";
|
|
7
7
|
import type { TokenUsage } from "./analytics.js";
|
|
8
8
|
import type { JsonValue, UnknownRecord } from "./common.js";
|
|
9
9
|
import type { Content, ImageWithAltText } from "./content.js";
|
|
10
10
|
import type { ChatMessage } from "./conversation.js";
|
|
11
|
+
import type { AdditionalMemoryUser } from "./generateTypes.js";
|
|
11
12
|
import type { AIModelProviderConfig } from "./providers.js";
|
|
12
13
|
import type { TTSChunk, TTSOptions } from "./ttsTypes.js";
|
|
13
|
-
import type { AdditionalMemoryUser } from "./generateTypes.js";
|
|
14
14
|
import type { StandardRecord, ValidationSchema } from "./typeAliases.js";
|
|
15
15
|
/**
|
|
16
16
|
* Progress tracking and metadata for streaming operations
|
|
@@ -326,12 +326,34 @@ export type StreamOptions = {
|
|
|
326
326
|
abortSignal?: AbortSignal;
|
|
327
327
|
disableTools?: boolean;
|
|
328
328
|
maxSteps?: number;
|
|
329
|
+
/**
|
|
330
|
+
* Tool choice configuration for streaming generation.
|
|
331
|
+
* Mirrors generate() so translated/fallback requests can preserve forced tool use.
|
|
332
|
+
*/
|
|
333
|
+
toolChoice?: ToolChoice<Record<string, Tool>>;
|
|
334
|
+
/**
|
|
335
|
+
* Optional callback that runs before each stream step in a multi-step generation.
|
|
336
|
+
*/
|
|
337
|
+
prepareStep?: (options: {
|
|
338
|
+
steps: StepResult<Record<string, Tool>>[];
|
|
339
|
+
stepNumber: number;
|
|
340
|
+
maxSteps: number;
|
|
341
|
+
model: LanguageModel;
|
|
342
|
+
}) => PromiseLike<{
|
|
343
|
+
toolChoice?: ToolChoice<Record<string, Tool>>;
|
|
344
|
+
activeTools?: Record<string, Tool>;
|
|
345
|
+
} | undefined>;
|
|
329
346
|
/** Include only these tools by name (whitelist). If set, only matching tools are available. */
|
|
330
347
|
toolFilter?: string[];
|
|
331
348
|
/** Exclude these tools by name (blacklist). Applied after toolFilter. */
|
|
332
349
|
excludeTools?: string[];
|
|
333
350
|
/** Disable tool result caching for this request (overrides global mcp.cache.enabled) */
|
|
334
351
|
disableToolCache?: boolean;
|
|
352
|
+
/**
|
|
353
|
+
* Disable NeuroLink's internal provider fallback for this request.
|
|
354
|
+
* Used by the Claude proxy so the proxy itself can own fallback order.
|
|
355
|
+
*/
|
|
356
|
+
disableInternalFallback?: boolean;
|
|
335
357
|
/**
|
|
336
358
|
* Skip injecting tool schemas into the system prompt.
|
|
337
359
|
* When true, tools are ONLY passed natively via the provider's `tools` parameter,
|
|
@@ -775,6 +775,7 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
|
|
|
775
775
|
return;
|
|
776
776
|
}
|
|
777
777
|
const totalFiles = options.input.files.length;
|
|
778
|
+
const files = options.input.files;
|
|
778
779
|
return withSpan({
|
|
779
780
|
name: "neurolink.file.process_all",
|
|
780
781
|
tracer: tracers.file,
|
|
@@ -787,8 +788,8 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
|
|
|
787
788
|
options.input.text = options.input.text || "";
|
|
788
789
|
let includedCount = 0;
|
|
789
790
|
const fileRegistry = options.fileRegistry;
|
|
790
|
-
for (let fileIdx = 0; fileIdx <
|
|
791
|
-
const file =
|
|
791
|
+
for (let fileIdx = 0; fileIdx < files.length; fileIdx++) {
|
|
792
|
+
const file = files[fileIdx];
|
|
792
793
|
const filename = extractFilename(file, fileIdx);
|
|
793
794
|
try {
|
|
794
795
|
// ─── Lazy file registration path ──────────────────────────────
|
|
@@ -30,6 +30,7 @@ export declare class ProviderHealthChecker {
|
|
|
30
30
|
* Check connectivity to provider endpoints
|
|
31
31
|
*/
|
|
32
32
|
private static checkConnectivity;
|
|
33
|
+
private static getConnectivityHeaders;
|
|
33
34
|
/**
|
|
34
35
|
* Check model availability (if possible without making API calls)
|
|
35
36
|
*/
|
|
@@ -98,6 +99,20 @@ export declare class ProviderHealthChecker {
|
|
|
98
99
|
* Check Azure OpenAI configuration
|
|
99
100
|
*/
|
|
100
101
|
private static checkAzureConfig;
|
|
102
|
+
private static getLiteLLMBaseUrl;
|
|
103
|
+
private static getLiteLLMModelsUrl;
|
|
104
|
+
private static getConfiguredLiteLLMModel;
|
|
105
|
+
private static getOllamaBaseUrl;
|
|
106
|
+
private static getOllamaTagsUrl;
|
|
107
|
+
private static getConfiguredOllamaModel;
|
|
108
|
+
private static fetchJsonWithTimeout;
|
|
109
|
+
private static normalizeModelList;
|
|
110
|
+
private static hasRequestedModel;
|
|
111
|
+
private static getOllamaAvailableModels;
|
|
112
|
+
private static getLiteLLMAvailableModels;
|
|
113
|
+
private static checkOllamaAvailability;
|
|
114
|
+
private static checkLiteLLMAvailability;
|
|
115
|
+
private static checkLiteLLMConfig;
|
|
101
116
|
/**
|
|
102
117
|
* Check Ollama configuration
|
|
103
118
|
*/
|
|
@@ -169,6 +184,10 @@ export declare class ProviderHealthChecker {
|
|
|
169
184
|
* Clear health cache for a provider or all providers
|
|
170
185
|
*/
|
|
171
186
|
static clearHealthCache(providerName?: AIProviderName): void;
|
|
187
|
+
static checkFallbackProviderAvailability(providerName: string, model: string): Promise<{
|
|
188
|
+
available: boolean;
|
|
189
|
+
reason?: string;
|
|
190
|
+
}>;
|
|
172
191
|
/**
|
|
173
192
|
* Get the best healthy provider from a list of options (NON-BLOCKING)
|
|
174
193
|
* Prioritizes healthy providers over configured but unhealthy ones
|