@juspay/neurolink 10.12.2 → 10.12.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
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [10.12.3](https://github.com/juspay/neurolink/compare/v10.12.2...v10.12.3) (2026-08-14)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **(proxy):** attribute runtime errors internally ([258ca34](https://github.com/juspay/neurolink/commit/258ca3435e4fe0d52abbb327c59a599444ffd302))
|
|
6
|
+
- **(proxy):** diagnose updater health probe failures ([41e3c9e](https://github.com/juspay/neurolink/commit/41e3c9e94d84d89d8c4ad3ff9b020bdb9cb475e4))
|
|
7
|
+
|
|
1
8
|
## [10.12.2](https://github.com/juspay/neurolink/compare/v10.12.1...v10.12.2) (2026-08-14)
|
|
2
9
|
|
|
3
10
|
### Bug Fixes
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { CommandModule } from "yargs";
|
|
13
13
|
import type { Hono } from "hono";
|
|
14
|
-
import type { AccountAllowlist, LoadedProxyConfig, ModelRouterInterface, ProxyGuardArgs, ProxyNeurolinkRuntime, ProxyStartArgs, ProxyStartStrategy, ProxySupervisorState, ProxyStatusArgs, ProxyTelemetryArgs, ProxyReadinessState } from "../../lib/types/index.js";
|
|
14
|
+
import type { AccountAllowlist, LoadedProxyConfig, ModelRouterInterface, ProxyGuardArgs, ProxyHealthProbe, ProxyNeurolinkRuntime, ProxyStartArgs, ProxyStartStrategy, ProxySupervisorState, ProxyStatusArgs, ProxyTelemetryArgs, ProxyReadinessState } from "../../lib/types/index.js";
|
|
15
15
|
import { ProxyRuntimeConfigStore } from "../../lib/proxy/runtimeConfig.js";
|
|
16
16
|
/**
|
|
17
17
|
* Drop a supervisor `version` that is not a string.
|
|
@@ -58,6 +58,7 @@ export declare function isRollingHandoffCapable(state: ProxySupervisorState | nu
|
|
|
58
58
|
* confirm a mismatch" and falls through to the args-only result.
|
|
59
59
|
*/
|
|
60
60
|
export declare function processLooksLikeProxySupervisor(pid: number, expectedStartTimeIso?: string): Promise<boolean>;
|
|
61
|
+
export declare function probeProxyHealth(host: string, port: number, timeoutMs: number): Promise<ProxyHealthProbe>;
|
|
61
62
|
export declare function mapClaudeErrorTypeToStatus(errorType?: string): number;
|
|
62
63
|
export declare function createProxyStartApp(params: {
|
|
63
64
|
neurolink: ProxyNeurolinkRuntime["neurolink"];
|
|
@@ -41,6 +41,7 @@ import packageJson from "../../../package.json" with { type: "json" };
|
|
|
41
41
|
const _require = createRequire(import.meta.url);
|
|
42
42
|
const PROXY_VERSION = packageJson.version;
|
|
43
43
|
const PROXY_INTERNAL_ACCOUNT_LABEL = "proxy/internal";
|
|
44
|
+
const PROXY_INTERNAL_ACCOUNT_TYPE = "internal";
|
|
44
45
|
const PROXY_TELEMETRY_SCRIPT_PATH = fileURLToPath(new URL("../../../scripts/observability/manage-local-openobserve.sh", import.meta.url));
|
|
45
46
|
const PROXY_LIFECYCLE_SHUTDOWN_TIMEOUT_MS = 5_000;
|
|
46
47
|
const LEGACY_STATUS_ACCOUNT_CACHE_TTL_MS = 5_000;
|
|
@@ -623,17 +624,51 @@ async function clearOpenCodeProxySettings(expectedBaseUrl) {
|
|
|
623
624
|
fs.writeFileSync(OPENCODE_CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
624
625
|
return hadNeurolink;
|
|
625
626
|
}
|
|
626
|
-
async function
|
|
627
|
+
export async function probeProxyHealth(host, port, timeoutMs) {
|
|
628
|
+
const startedAt = Date.now();
|
|
627
629
|
try {
|
|
628
630
|
const response = await fetch(`http://${host}:${port}/health`, {
|
|
629
631
|
signal: AbortSignal.timeout(timeoutMs),
|
|
630
632
|
});
|
|
631
|
-
return
|
|
633
|
+
return {
|
|
634
|
+
healthy: response.ok,
|
|
635
|
+
durationMs: Date.now() - startedAt,
|
|
636
|
+
failure: response.ok ? null : "http_status",
|
|
637
|
+
statusCode: response.status,
|
|
638
|
+
errorCode: null,
|
|
639
|
+
};
|
|
632
640
|
}
|
|
633
|
-
catch {
|
|
634
|
-
|
|
641
|
+
catch (error) {
|
|
642
|
+
const candidate = error;
|
|
643
|
+
const cause = candidate?.cause;
|
|
644
|
+
const errorCode = typeof candidate?.code === "string"
|
|
645
|
+
? candidate.code
|
|
646
|
+
: typeof cause?.code === "string"
|
|
647
|
+
? cause.code
|
|
648
|
+
: typeof candidate?.name === "string"
|
|
649
|
+
? candidate.name
|
|
650
|
+
: null;
|
|
651
|
+
const isTimeout = candidate?.name === "TimeoutError" || candidate?.name === "AbortError";
|
|
652
|
+
return {
|
|
653
|
+
healthy: false,
|
|
654
|
+
durationMs: Date.now() - startedAt,
|
|
655
|
+
failure: isTimeout ? "timeout" : "network",
|
|
656
|
+
statusCode: null,
|
|
657
|
+
errorCode,
|
|
658
|
+
};
|
|
635
659
|
}
|
|
636
660
|
}
|
|
661
|
+
function formatProxyHealthProbe(probe) {
|
|
662
|
+
const details = [
|
|
663
|
+
`reason=${probe.failure ?? "none"}`,
|
|
664
|
+
`durationMs=${probe.durationMs}`,
|
|
665
|
+
probe.statusCode === null ? null : `status=${probe.statusCode}`,
|
|
666
|
+
probe.errorCode === null
|
|
667
|
+
? null
|
|
668
|
+
: `errorCode=${sanitizeForLog(probe.errorCode)}`,
|
|
669
|
+
].filter((detail) => detail !== null);
|
|
670
|
+
return details.join(" ");
|
|
671
|
+
}
|
|
637
672
|
async function getProxyRuntimeActivity(host, port, timeoutMs = 3_000) {
|
|
638
673
|
try {
|
|
639
674
|
const response = await fetch(`http://${host}:${port}/status`, {
|
|
@@ -1312,7 +1347,7 @@ export async function createProxyStartApp(params) {
|
|
|
1312
1347
|
const recordRuntimeError = async (metadata, status, errorType, errorMessage, options) => {
|
|
1313
1348
|
const clientMessage = options?.clientMessage ?? errorMessage;
|
|
1314
1349
|
const clientErrorType = options?.clientErrorType ?? errorType;
|
|
1315
|
-
recordFinalError(status,
|
|
1350
|
+
recordFinalError(status, PROXY_INTERNAL_ACCOUNT_LABEL, PROXY_INTERNAL_ACCOUNT_TYPE, {
|
|
1316
1351
|
requestId: metadata.requestId,
|
|
1317
1352
|
errorType,
|
|
1318
1353
|
errorCode: options?.errorCode,
|
|
@@ -3730,19 +3765,23 @@ export const proxyGuardCommand = {
|
|
|
3730
3765
|
const startedAt = Date.now();
|
|
3731
3766
|
let parentStatus = getProcessStatus(parentPid);
|
|
3732
3767
|
let consecutiveUnhealthy = 0;
|
|
3768
|
+
let lastUnhealthyProbe = null;
|
|
3733
3769
|
// Keep monitoring for as long as the parent can affect Claude settings.
|
|
3734
3770
|
while (true) {
|
|
3735
|
-
const
|
|
3771
|
+
const healthProbe = await probeProxyHealth(host, port, 1_500);
|
|
3772
|
+
const healthy = healthProbe.healthy;
|
|
3736
3773
|
if (healthy) {
|
|
3737
3774
|
if (updaterOnly && consecutiveUnhealthy >= failureThreshold) {
|
|
3738
|
-
logger.always(`[updater] proxy health recovered after ${consecutiveUnhealthy} failed checks`);
|
|
3775
|
+
logger.always(`[updater] proxy health recovered after ${consecutiveUnhealthy} failed checks; ${formatProxyHealthProbe(lastUnhealthyProbe ?? healthProbe)}`);
|
|
3739
3776
|
}
|
|
3740
3777
|
consecutiveUnhealthy = 0;
|
|
3778
|
+
lastUnhealthyProbe = null;
|
|
3741
3779
|
}
|
|
3742
3780
|
else {
|
|
3743
3781
|
consecutiveUnhealthy += 1;
|
|
3782
|
+
lastUnhealthyProbe = healthProbe;
|
|
3744
3783
|
if (updaterOnly && consecutiveUnhealthy === failureThreshold) {
|
|
3745
|
-
logger.always(`[updater] proxy health unavailable after ${consecutiveUnhealthy} checks; worker remains active`);
|
|
3784
|
+
logger.always(`[updater] proxy health unavailable after ${consecutiveUnhealthy} checks; worker remains active; ${formatProxyHealthProbe(healthProbe)}`);
|
|
3746
3785
|
}
|
|
3747
3786
|
}
|
|
3748
3787
|
if (parentStatus === "not_running" && !updateRestartInProgress) {
|
|
@@ -1861,6 +1861,14 @@ export type UpdateCheckResult = {
|
|
|
1861
1861
|
latestVersion: string;
|
|
1862
1862
|
updateAvailable: boolean;
|
|
1863
1863
|
};
|
|
1864
|
+
/** Result of one local proxy health probe by the updater or fail-open guard. */
|
|
1865
|
+
export type ProxyHealthProbe = {
|
|
1866
|
+
healthy: boolean;
|
|
1867
|
+
durationMs: number;
|
|
1868
|
+
failure: "http_status" | "network" | "timeout" | null;
|
|
1869
|
+
statusCode: number | null;
|
|
1870
|
+
errorCode: string | null;
|
|
1871
|
+
};
|
|
1864
1872
|
/** Parsed major.minor.patch components of a semver string. */
|
|
1865
1873
|
export type SemVer = {
|
|
1866
1874
|
major: number;
|
package/dist/types/proxy.d.ts
CHANGED
|
@@ -1861,6 +1861,14 @@ export type UpdateCheckResult = {
|
|
|
1861
1861
|
latestVersion: string;
|
|
1862
1862
|
updateAvailable: boolean;
|
|
1863
1863
|
};
|
|
1864
|
+
/** Result of one local proxy health probe by the updater or fail-open guard. */
|
|
1865
|
+
export type ProxyHealthProbe = {
|
|
1866
|
+
healthy: boolean;
|
|
1867
|
+
durationMs: number;
|
|
1868
|
+
failure: "http_status" | "network" | "timeout" | null;
|
|
1869
|
+
statusCode: number | null;
|
|
1870
|
+
errorCode: string | null;
|
|
1871
|
+
};
|
|
1864
1872
|
/** Parsed major.minor.patch components of a semver string. */
|
|
1865
1873
|
export type SemVer = {
|
|
1866
1874
|
major: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "10.12.
|
|
3
|
+
"version": "10.12.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": {
|