@juspay/neurolink 12.17.1 → 12.17.3
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 -2
- package/dist/browser/neurolink.min.js +430 -421
- package/dist/cli/commands/proxy.js +455 -259
- package/dist/constants/contextWindows.d.ts +2 -0
- package/dist/constants/contextWindows.js +4 -0
- package/dist/neurolink.js +8 -3
- package/dist/providers/openaiChatCompletionsBase.js +60 -51
- package/dist/proxy/anthropicBudgetResponse.d.ts +3 -0
- package/dist/proxy/anthropicBudgetResponse.js +153 -0
- package/dist/proxy/bodyCaptureProcessing.d.ts +1 -0
- package/dist/proxy/bodyCaptureProcessing.js +23 -4
- package/dist/proxy/bodyCaptureWorker.js +20 -2
- package/dist/proxy/codexFallback.d.ts +10 -0
- package/dist/proxy/codexFallback.js +108 -24
- package/dist/proxy/codexUsage.js +2 -0
- package/dist/proxy/globalInstaller.d.ts +32 -1
- package/dist/proxy/globalInstaller.js +386 -3
- package/dist/proxy/otelLogSink.d.ts +3 -3
- package/dist/proxy/otelLogSink.js +137 -144
- package/dist/proxy/otlpLogTransport.d.ts +3 -0
- package/dist/proxy/otlpLogTransport.js +334 -0
- package/dist/proxy/proxyActivity.d.ts +22 -2
- package/dist/proxy/proxyActivity.js +114 -9
- package/dist/proxy/proxyAnalysis.js +82 -52
- package/dist/proxy/proxyClientCancellation.d.ts +7 -0
- package/dist/proxy/proxyClientCancellation.js +23 -0
- package/dist/proxy/proxyContextPreflight.d.ts +25 -0
- package/dist/proxy/proxyContextPreflight.js +337 -0
- package/dist/proxy/proxyFailureDetails.d.ts +19 -0
- package/dist/proxy/proxyFailureDetails.js +96 -0
- package/dist/proxy/proxyLifecycle.js +7 -0
- package/dist/proxy/proxyRouteBodyCapture.d.ts +13 -0
- package/dist/proxy/proxyRouteBodyCapture.js +112 -0
- package/dist/proxy/proxyTokenBudget.d.ts +40 -0
- package/dist/proxy/proxyTokenBudget.js +523 -0
- package/dist/proxy/proxyTracer.d.ts +3 -2
- package/dist/proxy/proxyTracer.js +46 -20
- package/dist/proxy/proxyTranslationEngine.d.ts +8 -10
- package/dist/proxy/proxyTranslationEngine.js +736 -376
- package/dist/proxy/requestLogger.d.ts +1 -0
- package/dist/proxy/requestLogger.js +107 -5
- package/dist/proxy/restartControl.js +9 -4
- package/dist/proxy/rollingWorkerProcess.js +65 -0
- package/dist/proxy/rollingWorkerSupervisor.js +7 -0
- package/dist/proxy/updateCoordinator.d.ts +14 -1
- package/dist/proxy/updateCoordinator.js +57 -2
- package/dist/server/routes/claudeProxyRoutes.d.ts +4 -5
- package/dist/server/routes/claudeProxyRoutes.js +809 -577
- package/dist/server/routes/codexProxyRoutes.js +191 -9
- package/dist/server/routes/openaiProxyRoutes.d.ts +1 -1
- package/dist/server/routes/openaiProxyRoutes.js +261 -69
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/codex.d.ts +5 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/proxy.d.ts +148 -3
- package/dist/types/proxy.js +0 -15
- package/dist/types/proxyBudget.d.ts +74 -0
- package/dist/types/proxyBudget.js +1 -0
- package/dist/types/proxyContext.d.ts +35 -0
- package/dist/types/proxyContext.js +1 -0
- package/dist/utils/fileDetector.js +28 -7
- package/dist/utils/messageBuilder.js +51 -26
- package/dist/utils/pdfProcessor.js +26 -4
- package/docs/assets/dashboards/README.md +37 -0
- package/docs/assets/dashboards/neurolink-proxy-observability-dashboard.json +197 -89
- package/docs-site/static/search-index.json +1 -1
- package/package.json +7 -2
- package/scripts/observability/NATIVE-DURABLE.md +63 -0
- package/scripts/observability/otel-collector.proxy-native-durable.yaml +93 -0
- package/scripts/observability/proxy-telemetry-backend.mjs +32 -5
- package/scripts/observability/proxy-telemetry-check.mjs +396 -61
- package/scripts/observability/query-proxy-history.mjs +34 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "12.17.
|
|
3
|
+
"version": "12.17.3",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
|
|
6
6
|
"author": {
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"test:context": "pnpm exec tsx test/continuous-test-suite-context.ts",
|
|
81
81
|
"test:evaluation": "pnpm exec tsx test/continuous-test-suite-evaluation.ts",
|
|
82
82
|
"test:handler-registry": "pnpm exec tsx test/continuous-test-suite-handler-registry.ts",
|
|
83
|
+
"test:harness-offline-timeout": "pnpm exec tsx test/continuous-test-suite-harness-offline-timeout.ts",
|
|
83
84
|
"test:resolve-request-kind": "pnpm exec tsx test/continuous-test-suite-resolve-request-kind.ts",
|
|
84
85
|
"test:mcp": "pnpm exec tsx test/continuous-test-suite-mcp-infra.ts",
|
|
85
86
|
"test:tool-resolution": "pnpm exec tsx test/continuous-test-suite-tool-resolution.ts",
|
|
@@ -132,6 +133,7 @@
|
|
|
132
133
|
"test:provider-fallback": "pnpm exec tsx test/continuous-test-suite-provider-fallback.ts",
|
|
133
134
|
"test:provider-fallback-latency": "pnpm exec tsx test/continuous-test-suite-provider-fallback-latency.ts",
|
|
134
135
|
"test:provider-wiring": "pnpm exec tsx test/continuous-test-suite-provider-wiring.ts",
|
|
136
|
+
"test:pdf-image-streaming": "pnpm exec tsx test/continuous-test-suite-pdf-image-streaming.ts",
|
|
135
137
|
"test:rag": "pnpm exec tsx test/continuous-test-suite-rag.ts",
|
|
136
138
|
"test:skills": "pnpm exec tsx test/continuous-test-suite-skills.ts",
|
|
137
139
|
"test:servers": "pnpm exec tsx test/continuous-test-suite-servers.ts",
|
|
@@ -153,6 +155,7 @@
|
|
|
153
155
|
"test:dynamic": "pnpm exec tsx test/continuous-test-suite-dynamic.ts",
|
|
154
156
|
"test:proxy": "pnpm exec tsx test/continuous-test-suite-proxy.ts",
|
|
155
157
|
"test:proxy-connect-retry": "pnpm exec tsx test/continuous-test-suite-proxy-connect-retry.ts",
|
|
158
|
+
"test:proxy-reliability": "node scripts/run-proxy-reliability.mjs",
|
|
156
159
|
"test:proxy-telemetry": "pnpm exec tsx test/continuous-test-suite-proxy-telemetry.ts",
|
|
157
160
|
"test:proxy-restart": "pnpm exec tsx test/continuous-test-suite-proxy-restart.ts",
|
|
158
161
|
"test:codex": "pnpm exec tsx test/continuous-test-suite-codex.ts",
|
|
@@ -250,7 +253,8 @@
|
|
|
250
253
|
"test:anthropic-execution-control": "tsx test/continuous-test-suite-anthropic-execution-control.ts",
|
|
251
254
|
"test:aistudio-loop-characterization": "tsx test/continuous-test-suite-aistudio-loop-characterization.ts",
|
|
252
255
|
"test:docs-mcp": "pnpm exec tsx test/continuous-test-suite-docs-mcp.ts",
|
|
253
|
-
"test:vertex-claude-characterization": "tsx test/continuous-test-suite-vertex-claude-characterization.ts"
|
|
256
|
+
"test:vertex-claude-characterization": "tsx test/continuous-test-suite-vertex-claude-characterization.ts",
|
|
257
|
+
"test:toolfree-guard-overhead": "pnpm exec tsx test/continuous-test-suite-toolfree-guard-overhead.ts"
|
|
254
258
|
},
|
|
255
259
|
"files": [
|
|
256
260
|
"dist",
|
|
@@ -391,6 +395,7 @@
|
|
|
391
395
|
"@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
|
|
392
396
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.214.0",
|
|
393
397
|
"@opentelemetry/exporter-trace-otlp-http": "^0.214.0",
|
|
398
|
+
"@opentelemetry/otlp-transformer": "^0.214.0",
|
|
394
399
|
"@opentelemetry/resources": "^2.6.0",
|
|
395
400
|
"@opentelemetry/sdk-logs": "^0.214.0",
|
|
396
401
|
"@opentelemetry/sdk-metrics": "^2.6.1",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Native collector queues and body separation
|
|
2
|
+
|
|
3
|
+
`otel-collector.proxy-native-durable.yaml` is an opt-in profile for
|
|
4
|
+
`otelcol-contrib >= 0.160.0`. It does not install, replace, or restart a service.
|
|
5
|
+
Application logs remain OTLP-only. Collector retry storage writes a bounded
|
|
6
|
+
queue to disk so records accepted into that queue survive a collector restart.
|
|
7
|
+
|
|
8
|
+
Configure these variables in the collector service environment:
|
|
9
|
+
|
|
10
|
+
- `NEUROLINK_OPENOBSERVE_OTLP_ENDPOINT`: backend API endpoint, for example
|
|
11
|
+
`http://127.0.0.1:5080/api/default` (use TLS outside loopback).
|
|
12
|
+
- `NEUROLINK_OPENOBSERVE_BASIC_AUTH`: backend authorization, supplied privately.
|
|
13
|
+
- `NEUROLINK_OTEL_QUEUE_DIRECTORY` and `NEUROLINK_OTEL_COMPACTION_DIRECTORY`:
|
|
14
|
+
private directories on a volume with an operator-managed disk quota.
|
|
15
|
+
- `NEUROLINK_PROXY_STREAM_HEADER=neurolink_proxy` and
|
|
16
|
+
`NEUROLINK_PROXY_BODY_STREAM_HEADER=neurolink_proxy_bodies`.
|
|
17
|
+
|
|
18
|
+
Configure the proxy service with `NEUROLINK_PROXY_LOG_SINK=otel`,
|
|
19
|
+
`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://127.0.0.1:14318/v1/logs` and
|
|
20
|
+
`NEUROLINK_PROXY_OTLP_BODIES_ENDPOINT=http://127.0.0.1:14319/v1/logs`.
|
|
21
|
+
Configure the doctor's environment with the same two stream variables, or point
|
|
22
|
+
`NEUROLINK_OTEL_COLLECTOR_CONFIG` at this collector's resolved configuration.
|
|
23
|
+
Without a separate body endpoint/stream, existing single-stream deployments
|
|
24
|
+
continue to work.
|
|
25
|
+
|
|
26
|
+
The profile isolates metadata and bulk body queues and backend streams. There is
|
|
27
|
+
no volatile batch processor before the persistent exporter queue: receiver
|
|
28
|
+
success follows persistent enqueue rather than a timer-buffered batch. Proxy
|
|
29
|
+
chunk batching still reduces transport calls. Queues use a 32 MiB metadata byte
|
|
30
|
+
limit per signal and a 256 MiB body byte limit, plus in-flight requests and
|
|
31
|
+
storage/index overhead. Compaction reclaims consumed pages. These are payload
|
|
32
|
+
bounds, not a hard filesystem size cap; apply a volume quota and monitor free
|
|
33
|
+
space. Backend retention should be configured separately for each stream.
|
|
34
|
+
|
|
35
|
+
Disk-full errors, queue saturation, invalid records, process crashes before
|
|
36
|
+
persistent enqueue, and permanent backend rejection can still lose records.
|
|
37
|
+
Retry queues retry transient errors indefinitely until delivered or storage
|
|
38
|
+
limits are reached. A transport acknowledgment is not proof of backend
|
|
39
|
+
persistence or exactly-once delivery; use stable event IDs to deduplicate
|
|
40
|
+
retries. Retrying after ambiguous network acknowledgment can create duplicates.
|
|
41
|
+
|
|
42
|
+
Validate a profile before an authorized activation:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
otelcol-contrib validate --config scripts/observability/otel-collector.proxy-native-durable.yaml
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The isolated recovery test starts its own collector on random loopback ports,
|
|
49
|
+
uses a temporary queue directory and a fake backend, forces an outage, kills
|
|
50
|
+
only that test-owned collector process, restarts it with the same directory,
|
|
51
|
+
and verifies replay. It never operates an installed service:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
NEUROLINK_TEST_OTELCOL_BIN=/absolute/path/to/otelcol-contrib \
|
|
55
|
+
pnpm exec tsx test/continuous-test-suite-proxy-capture-pipeline.ts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The doctor's admission reconciliation searches a bounded lookback (24 hours by
|
|
59
|
+
default), applies per-request deadlines where logged, and gives late ingestion
|
|
60
|
+
120 seconds before flagging missing endings. Use `--admission-lookback-minutes`
|
|
61
|
+
and `--max-rows` to select an explicit wider proof; exceeding row/query budgets
|
|
62
|
+
is incomplete evidence, never a green result. Request success remains separate
|
|
63
|
+
from capture admission, worker processing, publication and exporter transport.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Opt-in native collector profile (otelcol-contrib >= 0.160.0).
|
|
2
|
+
# This persists collector retry queues, never application log files. Configure a
|
|
3
|
+
# private directory and a filesystem quota; queue byte bounds exclude DB overhead.
|
|
4
|
+
receivers:
|
|
5
|
+
otlp/metadata:
|
|
6
|
+
protocols:
|
|
7
|
+
http:
|
|
8
|
+
endpoint: ${env:NEUROLINK_OTEL_METADATA_LISTEN:-127.0.0.1:14318}
|
|
9
|
+
otlp/bodies:
|
|
10
|
+
protocols:
|
|
11
|
+
http:
|
|
12
|
+
endpoint: ${env:NEUROLINK_OTEL_BODIES_LISTEN:-127.0.0.1:14319}
|
|
13
|
+
processors:
|
|
14
|
+
memory_limiter:
|
|
15
|
+
check_interval: 1s
|
|
16
|
+
limit_mib: 256
|
|
17
|
+
spike_limit_mib: 64
|
|
18
|
+
exporters:
|
|
19
|
+
otlphttp/openobserve:
|
|
20
|
+
endpoint: ${env:NEUROLINK_OPENOBSERVE_OTLP_ENDPOINT}
|
|
21
|
+
encoding: json
|
|
22
|
+
headers:
|
|
23
|
+
Authorization: ${env:NEUROLINK_OPENOBSERVE_BASIC_AUTH}
|
|
24
|
+
stream-name: ${env:NEUROLINK_PROXY_STREAM_HEADER:-neurolink_proxy}
|
|
25
|
+
retry_on_failure:
|
|
26
|
+
enabled: true
|
|
27
|
+
initial_interval: 1s
|
|
28
|
+
max_interval: 30s
|
|
29
|
+
max_elapsed_time: 0s
|
|
30
|
+
sending_queue:
|
|
31
|
+
enabled: true
|
|
32
|
+
num_consumers: 2
|
|
33
|
+
sizer: bytes
|
|
34
|
+
queue_size: 33554432
|
|
35
|
+
storage: file_storage
|
|
36
|
+
otlphttp/openobserve-bodies:
|
|
37
|
+
endpoint: ${env:NEUROLINK_OPENOBSERVE_OTLP_ENDPOINT}
|
|
38
|
+
encoding: json
|
|
39
|
+
headers:
|
|
40
|
+
Authorization: ${env:NEUROLINK_OPENOBSERVE_BASIC_AUTH}
|
|
41
|
+
stream-name: ${env:NEUROLINK_PROXY_BODY_STREAM_HEADER:-neurolink_proxy_bodies}
|
|
42
|
+
retry_on_failure:
|
|
43
|
+
enabled: true
|
|
44
|
+
initial_interval: 1s
|
|
45
|
+
max_interval: 30s
|
|
46
|
+
max_elapsed_time: 0s
|
|
47
|
+
sending_queue:
|
|
48
|
+
enabled: true
|
|
49
|
+
num_consumers: 2
|
|
50
|
+
sizer: bytes
|
|
51
|
+
queue_size: 268435456
|
|
52
|
+
storage: file_storage
|
|
53
|
+
extensions:
|
|
54
|
+
file_storage:
|
|
55
|
+
directory: ${env:NEUROLINK_OTEL_QUEUE_DIRECTORY}
|
|
56
|
+
create_directory: true
|
|
57
|
+
fsync: true
|
|
58
|
+
compaction:
|
|
59
|
+
on_start: true
|
|
60
|
+
on_rebound: true
|
|
61
|
+
directory: ${env:NEUROLINK_OTEL_COMPACTION_DIRECTORY}
|
|
62
|
+
health_check:
|
|
63
|
+
endpoint: ${env:NEUROLINK_OTEL_HEALTH_LISTEN:-127.0.0.1:14333}
|
|
64
|
+
service:
|
|
65
|
+
extensions: [file_storage, health_check]
|
|
66
|
+
pipelines:
|
|
67
|
+
logs/metadata:
|
|
68
|
+
receivers: [otlp/metadata]
|
|
69
|
+
processors: [memory_limiter]
|
|
70
|
+
exporters: [otlphttp/openobserve]
|
|
71
|
+
logs/bodies:
|
|
72
|
+
receivers: [otlp/bodies]
|
|
73
|
+
processors: [memory_limiter]
|
|
74
|
+
exporters: [otlphttp/openobserve-bodies]
|
|
75
|
+
traces:
|
|
76
|
+
receivers: [otlp/metadata]
|
|
77
|
+
processors: [memory_limiter]
|
|
78
|
+
exporters: [otlphttp/openobserve]
|
|
79
|
+
metrics:
|
|
80
|
+
receivers: [otlp/metadata]
|
|
81
|
+
processors: [memory_limiter]
|
|
82
|
+
exporters: [otlphttp/openobserve]
|
|
83
|
+
telemetry:
|
|
84
|
+
logs:
|
|
85
|
+
level: warn
|
|
86
|
+
metrics:
|
|
87
|
+
level: detailed
|
|
88
|
+
readers:
|
|
89
|
+
- pull:
|
|
90
|
+
exporter:
|
|
91
|
+
prometheus:
|
|
92
|
+
host: "127.0.0.1"
|
|
93
|
+
port: ${env:NEUROLINK_OTEL_METRICS_PORT:-14388}
|
|
@@ -37,9 +37,25 @@ export async function resolveProxyTelemetryBackend(env = process.env) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
/** Resolve collector environment substitutions without logging their values.
|
|
41
|
+
* @param {string | undefined} value
|
|
42
|
+
*/
|
|
43
|
+
const resolveCollectorValue = (value) =>
|
|
44
|
+
value?.replace(
|
|
45
|
+
/\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,
|
|
46
|
+
(_match, name, fallback) => {
|
|
47
|
+
const resolved = env[name] ?? fallback;
|
|
48
|
+
if (resolved === undefined)
|
|
49
|
+
{throw new Error(
|
|
50
|
+
`Collector environment variable ${name} is not configured`,
|
|
51
|
+
);}
|
|
52
|
+
return resolved;
|
|
53
|
+
},
|
|
54
|
+
);
|
|
40
55
|
const exporter = native?.exporters?.["otlphttp/openobserve"];
|
|
41
|
-
const
|
|
42
|
-
|
|
56
|
+
const configuredEndpoint = resolveCollectorValue(exporter?.endpoint);
|
|
57
|
+
const destination = configuredEndpoint
|
|
58
|
+
? new URL(configuredEndpoint)
|
|
43
59
|
: undefined;
|
|
44
60
|
const nativeOrg = destination?.pathname.match(
|
|
45
61
|
/^\/api\/([a-zA-Z0-9_-]+)\/?$/,
|
|
@@ -48,7 +64,9 @@ export async function resolveProxyTelemetryBackend(env = process.env) {
|
|
|
48
64
|
env.NEUROLINK_OPENOBSERVE_BASIC_AUTH ??
|
|
49
65
|
(env.NEUROLINK_OPENOBSERVE_USER && env.NEUROLINK_OPENOBSERVE_PASSWORD
|
|
50
66
|
? `Basic ${Buffer.from(`${env.NEUROLINK_OPENOBSERVE_USER}:${env.NEUROLINK_OPENOBSERVE_PASSWORD}`).toString("base64")}`
|
|
51
|
-
: (
|
|
67
|
+
: resolveCollectorValue(
|
|
68
|
+
exporter?.headers?.Authorization ?? exporter?.headers?.authorization,
|
|
69
|
+
));
|
|
52
70
|
return {
|
|
53
71
|
baseUrl:
|
|
54
72
|
env.NEUROLINK_OPENOBSERVE_URL ??
|
|
@@ -57,8 +75,15 @@ export async function resolveProxyTelemetryBackend(env = process.env) {
|
|
|
57
75
|
organization: env.NEUROLINK_OPENOBSERVE_ORG ?? nativeOrg ?? "default",
|
|
58
76
|
stream:
|
|
59
77
|
env.NEUROLINK_PROXY_STREAM_HEADER ??
|
|
60
|
-
exporter?.headers?.["stream-name"] ??
|
|
78
|
+
resolveCollectorValue(exporter?.headers?.["stream-name"]) ??
|
|
61
79
|
"neurolink_proxy",
|
|
80
|
+
bodyStream:
|
|
81
|
+
env.NEUROLINK_PROXY_BODY_STREAM_HEADER ??
|
|
82
|
+
resolveCollectorValue(
|
|
83
|
+
native?.exporters?.["otlphttp/openobserve-bodies"]?.headers?.[
|
|
84
|
+
"stream-name"
|
|
85
|
+
],
|
|
86
|
+
),
|
|
62
87
|
authorization,
|
|
63
88
|
collectorMetricsUrl:
|
|
64
89
|
env.NEUROLINK_OTEL_COLLECTOR_METRICS_URL ??
|
|
@@ -72,7 +97,9 @@ export async function resolveProxyTelemetryBackend(env = process.env) {
|
|
|
72
97
|
export function validateProxyTelemetryBackend(backend) {
|
|
73
98
|
if (
|
|
74
99
|
!/^[a-zA-Z0-9_-]+$/.test(backend.organization) ||
|
|
75
|
-
!/^[a-zA-Z0-9_]+$/.test(backend.stream)
|
|
100
|
+
!/^[a-zA-Z0-9_]+$/.test(backend.stream) ||
|
|
101
|
+
(backend.bodyStream !== undefined &&
|
|
102
|
+
!/^[a-zA-Z0-9_]+$/.test(backend.bodyStream))
|
|
76
103
|
) {
|
|
77
104
|
throw new Error("Invalid telemetry organization or stream");
|
|
78
105
|
}
|