@juspay/neurolink 9.92.3 → 9.93.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/dist/browser/neurolink.min.js +287 -287
- package/dist/cli/commands/proxy.d.ts +2 -1
- package/dist/cli/commands/proxy.js +157 -27
- package/dist/lib/proxy/proxyActivity.d.ts +2 -2
- package/dist/lib/proxy/proxyActivity.js +49 -9
- package/dist/lib/proxy/proxyLifecycle.d.ts +8 -0
- package/dist/lib/proxy/proxyLifecycle.js +333 -0
- package/dist/lib/proxy/requestLogger.js +6 -0
- package/dist/lib/server/routes/claudeProxyRoutes.js +23 -18
- package/dist/lib/types/proxy.d.ts +82 -0
- package/dist/proxy/proxyActivity.d.ts +2 -2
- package/dist/proxy/proxyActivity.js +49 -9
- package/dist/proxy/proxyLifecycle.d.ts +8 -0
- package/dist/proxy/proxyLifecycle.js +332 -0
- package/dist/proxy/requestLogger.js +6 -0
- package/dist/server/routes/claudeProxyRoutes.js +23 -18
- package/dist/types/proxy.d.ts +82 -0
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* (generate/stream), with an optional ModelRouter for model remapping.
|
|
11
11
|
*/
|
|
12
12
|
import type { CommandModule } from "yargs";
|
|
13
|
+
import type { Hono } from "hono";
|
|
13
14
|
import type { AccountAllowlist, LoadedProxyConfig, ModelRouterInterface, ProxyGuardArgs, ProxyNeurolinkRuntime, ProxyStartArgs, ProxyStartStrategy, ProxyStatusArgs, ProxyTelemetryArgs } from "../../lib/types/index.js";
|
|
14
15
|
import { ProxyRuntimeConfigStore } from "../../lib/proxy/runtimeConfig.js";
|
|
15
16
|
export declare function mapClaudeErrorTypeToStatus(errorType?: string): number;
|
|
@@ -25,7 +26,7 @@ export declare function createProxyStartApp(params: {
|
|
|
25
26
|
accountAllowlist: AccountAllowlist | undefined;
|
|
26
27
|
runtimeConfigStore?: ProxyRuntimeConfigStore;
|
|
27
28
|
}): Promise<{
|
|
28
|
-
app:
|
|
29
|
+
app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
29
30
|
readiness: import("../../lib/types/proxy.js").ProxyReadinessState;
|
|
30
31
|
}>;
|
|
31
32
|
export declare const proxyStartCommand: CommandModule<object, ProxyStartArgs>;
|
|
@@ -16,11 +16,13 @@ import chalk from "chalk";
|
|
|
16
16
|
import ora from "ora";
|
|
17
17
|
import { buildProxyHealthResponse, createProxyReadinessState, markProxyReady, waitForProxyReadiness, } from "../../lib/proxy/proxyHealth.js";
|
|
18
18
|
import { logger } from "../../lib/utils/logger.js";
|
|
19
|
+
import { withTimeout } from "../../lib/utils/async/withTimeout.js";
|
|
19
20
|
import { formatUptime, isProcessRunning, StateFileManager, } from "../utils/serverUtils.js";
|
|
20
21
|
import { configureProxyKeepAliveDispatcher } from "../../lib/proxy/proxyDispatcher.js";
|
|
21
22
|
import { ProxyRuntimeConfigStore } from "../../lib/proxy/runtimeConfig.js";
|
|
22
23
|
import { anthropicAccountKeysEqual, createAccountAllowlist, ENV_ANTHROPIC_ACCOUNT_KEY, isAccountAllowed, LEGACY_ANTHROPIC_ACCOUNT_KEY, normalizeAnthropicAccountKey, shouldLoadFallbackCredential, } from "../../lib/proxy/accountSelection.js";
|
|
23
24
|
import { beginProxyRequest, getProxyActivitySnapshot, trackProxyResponse, } from "../../lib/proxy/proxyActivity.js";
|
|
25
|
+
import { flushProxyLifecycleEvents, getProxyLifecycleLoggerSnapshot, hashProxyLifecycleSessionId, logProxyLifecycleEvent, } from "../../lib/proxy/proxyLifecycle.js";
|
|
24
26
|
import { describeInstallFailure, getGlobalInstallArgs, resolveGlobalInstaller, validateInstalledVersion, } from "../../lib/proxy/globalInstaller.js";
|
|
25
27
|
import { startUpdaterWorkerSupervisor } from "../../lib/proxy/updaterSupervisor.js";
|
|
26
28
|
import { abandonPendingUpdate, isVersionSuppressed, loadUpdateState, recordCheck, recordSuccessfulUpdate, recordUpdateFailure, recordUpdateInstalled, suppressVersion, } from "../../lib/proxy/updateState.js";
|
|
@@ -31,6 +33,7 @@ import packageJson from "../../../package.json" with { type: "json" };
|
|
|
31
33
|
const _require = createRequire(import.meta.url);
|
|
32
34
|
const PROXY_VERSION = packageJson.version;
|
|
33
35
|
const PROXY_TELEMETRY_SCRIPT_PATH = fileURLToPath(new URL("../../../scripts/observability/manage-local-openobserve.sh", import.meta.url));
|
|
36
|
+
const PROXY_LIFECYCLE_SHUTDOWN_TIMEOUT_MS = 5_000;
|
|
34
37
|
// =============================================================================
|
|
35
38
|
// STATE MANAGEMENT
|
|
36
39
|
// =============================================================================
|
|
@@ -643,6 +646,20 @@ export function mapClaudeErrorTypeToStatus(errorType) {
|
|
|
643
646
|
return 502;
|
|
644
647
|
}
|
|
645
648
|
}
|
|
649
|
+
function getProxyRuntimeErrorCode(error) {
|
|
650
|
+
let current = error;
|
|
651
|
+
for (let depth = 0; depth < 3; depth += 1) {
|
|
652
|
+
if (!current || typeof current !== "object") {
|
|
653
|
+
return undefined;
|
|
654
|
+
}
|
|
655
|
+
const code = current.code;
|
|
656
|
+
if (typeof code === "string") {
|
|
657
|
+
return code;
|
|
658
|
+
}
|
|
659
|
+
current = current.cause;
|
|
660
|
+
}
|
|
661
|
+
return undefined;
|
|
662
|
+
}
|
|
646
663
|
async function ensureProxyStartAllowed(spinner) {
|
|
647
664
|
const ignoreLaunchd = process.env.NEUROLINK_PROXY_IGNORE_LAUNCHD === "1" ||
|
|
648
665
|
process.env.NEUROLINK_PROXY_IGNORE_LAUNCHD === "true";
|
|
@@ -710,6 +727,125 @@ async function createProxyNeurolinkRuntime(logsDir) {
|
|
|
710
727
|
cleanupLogs(7, 500);
|
|
711
728
|
return { neurolink, cleanupLogs };
|
|
712
729
|
}
|
|
730
|
+
function registerProxyRequestTracking(app, requestMetadata) {
|
|
731
|
+
app.use("/v1/*", async (c, next) => {
|
|
732
|
+
const startedMonotonicMs = performance.now();
|
|
733
|
+
const contentLengthHeader = c.req.raw.headers.get("content-length");
|
|
734
|
+
const rawContentLength = contentLengthHeader === null ? Number.NaN : Number(contentLengthHeader);
|
|
735
|
+
const requestBytes = Number.isFinite(rawContentLength) && rawContentLength >= 0
|
|
736
|
+
? rawContentLength
|
|
737
|
+
: undefined;
|
|
738
|
+
const sessionId = c.req.raw.headers.get("x-neurolink-session-id") ??
|
|
739
|
+
c.req.raw.headers.get("x-claude-code-session-id") ??
|
|
740
|
+
undefined;
|
|
741
|
+
const sessionHash = hashProxyLifecycleSessionId(sessionId);
|
|
742
|
+
const metadata = {
|
|
743
|
+
requestId: crypto.randomUUID(),
|
|
744
|
+
method: c.req.method,
|
|
745
|
+
path: c.req.path,
|
|
746
|
+
startedAt: Date.now(),
|
|
747
|
+
model: "-",
|
|
748
|
+
stream: false,
|
|
749
|
+
toolCount: 0,
|
|
750
|
+
};
|
|
751
|
+
requestMetadata.set(c.req.raw, metadata);
|
|
752
|
+
const finishActivity = beginProxyRequest();
|
|
753
|
+
const finish = () => {
|
|
754
|
+
finishActivity();
|
|
755
|
+
requestMetadata.delete(c.req.raw);
|
|
756
|
+
};
|
|
757
|
+
// The route adapter populates model/stream/toolCount after parsing. Omit
|
|
758
|
+
// them at acceptance instead of publishing misleading placeholder values;
|
|
759
|
+
// subsequent events carry the parsed metadata under the same request ID.
|
|
760
|
+
logProxyLifecycleEvent({
|
|
761
|
+
event: "request_accepted",
|
|
762
|
+
requestId: metadata.requestId,
|
|
763
|
+
method: metadata.method,
|
|
764
|
+
path: metadata.path,
|
|
765
|
+
sessionHash,
|
|
766
|
+
requestBytes,
|
|
767
|
+
elapsedMs: 0,
|
|
768
|
+
monotonicMs: startedMonotonicMs,
|
|
769
|
+
});
|
|
770
|
+
try {
|
|
771
|
+
await next();
|
|
772
|
+
const responseStatus = c.res.status;
|
|
773
|
+
logProxyLifecycleEvent({
|
|
774
|
+
event: "response_headers",
|
|
775
|
+
requestId: metadata.requestId,
|
|
776
|
+
method: metadata.method,
|
|
777
|
+
path: metadata.path,
|
|
778
|
+
model: metadata.model,
|
|
779
|
+
stream: metadata.stream,
|
|
780
|
+
toolCount: metadata.toolCount,
|
|
781
|
+
sessionHash,
|
|
782
|
+
requestBytes,
|
|
783
|
+
responseStatus,
|
|
784
|
+
elapsedMs: performance.now() - startedMonotonicMs,
|
|
785
|
+
});
|
|
786
|
+
c.res = trackProxyResponse(c.res, finish, {
|
|
787
|
+
onFirstChunk: ({ observedBodyBytes, responseChunks }) => {
|
|
788
|
+
logProxyLifecycleEvent({
|
|
789
|
+
event: "response_first_chunk",
|
|
790
|
+
requestId: metadata.requestId,
|
|
791
|
+
method: metadata.method,
|
|
792
|
+
path: metadata.path,
|
|
793
|
+
model: metadata.model,
|
|
794
|
+
stream: metadata.stream,
|
|
795
|
+
toolCount: metadata.toolCount,
|
|
796
|
+
sessionHash,
|
|
797
|
+
requestBytes,
|
|
798
|
+
responseStatus,
|
|
799
|
+
observedBodyBytes,
|
|
800
|
+
responseChunks,
|
|
801
|
+
elapsedMs: performance.now() - startedMonotonicMs,
|
|
802
|
+
});
|
|
803
|
+
},
|
|
804
|
+
onTerminal: ({ outcome, observedBodyBytes, responseChunks }) => {
|
|
805
|
+
logProxyLifecycleEvent({
|
|
806
|
+
event: "request_terminal",
|
|
807
|
+
requestId: metadata.requestId,
|
|
808
|
+
method: metadata.method,
|
|
809
|
+
path: metadata.path,
|
|
810
|
+
model: metadata.model,
|
|
811
|
+
stream: metadata.stream,
|
|
812
|
+
toolCount: metadata.toolCount,
|
|
813
|
+
sessionHash,
|
|
814
|
+
requestBytes,
|
|
815
|
+
responseStatus,
|
|
816
|
+
observedBodyBytes,
|
|
817
|
+
responseChunks,
|
|
818
|
+
elapsedMs: performance.now() - startedMonotonicMs,
|
|
819
|
+
terminalOutcome: outcome,
|
|
820
|
+
errorType: metadata.terminalErrorType,
|
|
821
|
+
errorCode: metadata.terminalErrorCode,
|
|
822
|
+
});
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
catch (error) {
|
|
827
|
+
// Keep metadata available to app.onError, which records the client-facing
|
|
828
|
+
// failure with the same request ID before deleting the WeakMap entry.
|
|
829
|
+
finishActivity();
|
|
830
|
+
logProxyLifecycleEvent({
|
|
831
|
+
event: "request_terminal",
|
|
832
|
+
requestId: metadata.requestId,
|
|
833
|
+
method: metadata.method,
|
|
834
|
+
path: metadata.path,
|
|
835
|
+
model: metadata.model,
|
|
836
|
+
stream: metadata.stream,
|
|
837
|
+
toolCount: metadata.toolCount,
|
|
838
|
+
sessionHash,
|
|
839
|
+
requestBytes,
|
|
840
|
+
elapsedMs: performance.now() - startedMonotonicMs,
|
|
841
|
+
terminalOutcome: "handler_error",
|
|
842
|
+
errorType: error instanceof Error ? error.name : "unknown_error",
|
|
843
|
+
errorCode: getProxyRuntimeErrorCode(error),
|
|
844
|
+
});
|
|
845
|
+
throw error;
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
713
849
|
export async function createProxyStartApp(params) {
|
|
714
850
|
const { createClaudeProxyRoutes } = await import("../../lib/server/routes/claudeProxyRoutes.js");
|
|
715
851
|
const { createOpenAIProxyRoutes } = await import("../../lib/server/routes/openaiProxyRoutes.js");
|
|
@@ -719,7 +855,9 @@ export async function createProxyStartApp(params) {
|
|
|
719
855
|
const app = new Hono();
|
|
720
856
|
const readiness = createProxyReadinessState();
|
|
721
857
|
const requestMetadata = new WeakMap();
|
|
722
|
-
const recordRuntimeError = async (metadata, status, errorType, errorMessage,
|
|
858
|
+
const recordRuntimeError = async (metadata, status, errorType, errorMessage, options) => {
|
|
859
|
+
const clientMessage = options?.clientMessage ?? errorMessage;
|
|
860
|
+
const clientErrorType = options?.clientErrorType ?? errorType;
|
|
723
861
|
recordFinalError(status);
|
|
724
862
|
await Promise.all([
|
|
725
863
|
logRequest({
|
|
@@ -736,6 +874,7 @@ export async function createProxyStartApp(params) {
|
|
|
736
874
|
responseTimeMs: Date.now() - metadata.startedAt,
|
|
737
875
|
errorType,
|
|
738
876
|
errorMessage,
|
|
877
|
+
...(options?.errorCode ? { errorCode: options.errorCode } : {}),
|
|
739
878
|
}),
|
|
740
879
|
logBodyCapture({
|
|
741
880
|
timestamp: new Date().toISOString(),
|
|
@@ -769,7 +908,13 @@ export async function createProxyStartApp(params) {
|
|
|
769
908
|
stream: false,
|
|
770
909
|
toolCount: 0,
|
|
771
910
|
};
|
|
772
|
-
|
|
911
|
+
metadata.terminalErrorType = "unhandled_proxy_error";
|
|
912
|
+
metadata.terminalErrorCode = getProxyRuntimeErrorCode(err);
|
|
913
|
+
await recordRuntimeError(metadata, 502, "unhandled_proxy_error", errMsg, {
|
|
914
|
+
clientMessage: "Proxy internal error",
|
|
915
|
+
clientErrorType: "api_error",
|
|
916
|
+
errorCode: metadata.terminalErrorCode,
|
|
917
|
+
});
|
|
773
918
|
requestMetadata.delete(c.req.raw);
|
|
774
919
|
return c.json({
|
|
775
920
|
type: "error",
|
|
@@ -779,31 +924,7 @@ export async function createProxyStartApp(params) {
|
|
|
779
924
|
},
|
|
780
925
|
}, 502);
|
|
781
926
|
});
|
|
782
|
-
app
|
|
783
|
-
const metadata = {
|
|
784
|
-
requestId: crypto.randomUUID(),
|
|
785
|
-
method: c.req.method,
|
|
786
|
-
path: c.req.path,
|
|
787
|
-
startedAt: Date.now(),
|
|
788
|
-
model: "-",
|
|
789
|
-
stream: false,
|
|
790
|
-
toolCount: 0,
|
|
791
|
-
};
|
|
792
|
-
requestMetadata.set(c.req.raw, metadata);
|
|
793
|
-
const finishActivity = beginProxyRequest();
|
|
794
|
-
const finish = () => {
|
|
795
|
-
finishActivity();
|
|
796
|
-
requestMetadata.delete(c.req.raw);
|
|
797
|
-
};
|
|
798
|
-
try {
|
|
799
|
-
await next();
|
|
800
|
-
c.res = trackProxyResponse(c.res, finish);
|
|
801
|
-
}
|
|
802
|
-
catch (error) {
|
|
803
|
-
finishActivity();
|
|
804
|
-
throw error;
|
|
805
|
-
}
|
|
806
|
-
});
|
|
927
|
+
registerProxyRequestTracking(app, requestMetadata);
|
|
807
928
|
const runtimeConfigStore = params.runtimeConfigStore;
|
|
808
929
|
const runtimeConfigProvider = runtimeConfigStore
|
|
809
930
|
? () => runtimeConfigStore.getSnapshot()
|
|
@@ -1042,6 +1163,9 @@ export async function createProxyStartApp(params) {
|
|
|
1042
1163
|
lastActivityAt: activity.lastActivityAt?.toISOString() ?? null,
|
|
1043
1164
|
};
|
|
1044
1165
|
})(),
|
|
1166
|
+
observability: {
|
|
1167
|
+
lifecycle: getProxyLifecycleLoggerSnapshot(),
|
|
1168
|
+
},
|
|
1045
1169
|
autoUpdate: {
|
|
1046
1170
|
enabled: isProxyAutoUpdateEnabled(),
|
|
1047
1171
|
updaterPid: runtimeState?.updaterPid ?? null,
|
|
@@ -1339,6 +1463,12 @@ function registerProxyShutdownHandlers(params) {
|
|
|
1339
1463
|
exitCode = 1;
|
|
1340
1464
|
logger.error(`[proxy] failed to drain server during shutdown: ${error instanceof Error ? error.message : String(error)}`);
|
|
1341
1465
|
}
|
|
1466
|
+
try {
|
|
1467
|
+
await withTimeout(flushProxyLifecycleEvents(), PROXY_LIFECYCLE_SHUTDOWN_TIMEOUT_MS, "Timed out flushing proxy lifecycle metadata during shutdown");
|
|
1468
|
+
}
|
|
1469
|
+
catch (error) {
|
|
1470
|
+
logger.debug(`[proxy] lifecycle metadata flush failed during shutdown: ${error instanceof Error ? error.message : String(error)}`);
|
|
1471
|
+
}
|
|
1342
1472
|
try {
|
|
1343
1473
|
const { flushOpenTelemetry, shutdownOpenTelemetry } = await import("../../lib/services/server/ai/observability/instrumentation.js");
|
|
1344
1474
|
await flushOpenTelemetry();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ProxyActivitySnapshot } from "../types/index.js";
|
|
1
|
+
import type { ProxyActivitySnapshot, ProxyResponseTrackingObserver } from "../types/index.js";
|
|
2
2
|
/** Track one client-facing proxy request until its response body settles. */
|
|
3
3
|
export declare function beginProxyRequest(): () => void;
|
|
4
4
|
export declare function getProxyActivitySnapshot(): ProxyActivitySnapshot;
|
|
5
5
|
export declare function isProxyActivityQuiet(snapshot: ProxyActivitySnapshot, quietThresholdMs: number, nowMs?: number): boolean;
|
|
6
6
|
/** Keep activity open until the response body completes, errors, or is cancelled. */
|
|
7
|
-
export declare function trackProxyResponse(response: Response, finishRequest: () => void): Response;
|
|
7
|
+
export declare function trackProxyResponse(response: Response, finishRequest: () => void, observer?: ProxyResponseTrackingObserver): Response;
|
|
8
8
|
export declare function resetProxyActivityForTests(): void;
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
import { withTimeout } from "../utils/async/withTimeout.js";
|
|
2
|
+
import { logger } from "../utils/logger.js";
|
|
3
|
+
const PROXY_RESPONSE_CANCEL_TIMEOUT_MS = 1_000;
|
|
1
4
|
let activeRequests = 0;
|
|
2
5
|
let lastActivityAtMs = null;
|
|
3
6
|
function touchActivity() {
|
|
4
7
|
lastActivityAtMs = Date.now();
|
|
5
8
|
}
|
|
9
|
+
function safelyNotifyObserver(callback) {
|
|
10
|
+
try {
|
|
11
|
+
callback?.();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
// Observability must never alter response handling.
|
|
15
|
+
if (logger.shouldLog("debug")) {
|
|
16
|
+
logger.debug("[proxy] response lifecycle observer failed", {
|
|
17
|
+
error: error instanceof Error ? error.message : String(error),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
6
22
|
/** Track one client-facing proxy request until its response body settles. */
|
|
7
23
|
export function beginProxyRequest() {
|
|
8
24
|
activeRequests += 1;
|
|
@@ -33,35 +49,59 @@ export function isProxyActivityQuiet(snapshot, quietThresholdMs, nowMs = Date.no
|
|
|
33
49
|
return nowMs - snapshot.lastActivityAt.getTime() >= quietThresholdMs;
|
|
34
50
|
}
|
|
35
51
|
/** Keep activity open until the response body completes, errors, or is cancelled. */
|
|
36
|
-
export function trackProxyResponse(response, finishRequest) {
|
|
52
|
+
export function trackProxyResponse(response, finishRequest, observer) {
|
|
37
53
|
if (!response.body) {
|
|
38
54
|
finishRequest();
|
|
55
|
+
safelyNotifyObserver(() => observer?.onTerminal?.({
|
|
56
|
+
outcome: "bodyless",
|
|
57
|
+
observedBodyBytes: 0,
|
|
58
|
+
responseChunks: 0,
|
|
59
|
+
}));
|
|
39
60
|
return response;
|
|
40
61
|
}
|
|
41
62
|
const reader = response.body.getReader();
|
|
63
|
+
let observedBodyBytes = 0;
|
|
64
|
+
let responseChunks = 0;
|
|
65
|
+
let settled = false;
|
|
66
|
+
const settle = (outcome) => {
|
|
67
|
+
if (settled) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
settled = true;
|
|
71
|
+
finishRequest();
|
|
72
|
+
safelyNotifyObserver(() => observer?.onTerminal?.({
|
|
73
|
+
outcome,
|
|
74
|
+
observedBodyBytes,
|
|
75
|
+
responseChunks,
|
|
76
|
+
}));
|
|
77
|
+
};
|
|
42
78
|
const trackedBody = new ReadableStream({
|
|
43
79
|
async pull(controller) {
|
|
44
80
|
try {
|
|
45
81
|
const { value, done } = await reader.read();
|
|
46
82
|
if (done) {
|
|
47
|
-
|
|
83
|
+
settle("completed");
|
|
48
84
|
controller.close();
|
|
49
85
|
return;
|
|
50
86
|
}
|
|
51
87
|
controller.enqueue(value);
|
|
88
|
+
observedBodyBytes += value.byteLength;
|
|
89
|
+
responseChunks += 1;
|
|
90
|
+
if (responseChunks === 1) {
|
|
91
|
+
safelyNotifyObserver(() => observer?.onFirstChunk?.({
|
|
92
|
+
observedBodyBytes,
|
|
93
|
+
responseChunks: 1,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
52
96
|
}
|
|
53
97
|
catch (error) {
|
|
54
|
-
|
|
98
|
+
settle("stream_error");
|
|
55
99
|
controller.error(error);
|
|
56
100
|
}
|
|
57
101
|
},
|
|
58
102
|
async cancel(reason) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
finishRequest();
|
|
64
|
-
}
|
|
103
|
+
settle("client_cancelled");
|
|
104
|
+
await withTimeout(reader.cancel(reason), PROXY_RESPONSE_CANCEL_TIMEOUT_MS, "Timed out cancelling the upstream proxy response");
|
|
65
105
|
},
|
|
66
106
|
});
|
|
67
107
|
return new Response(trackedBody, {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProxyLifecycleEventInput, ProxyLifecycleLoggerOptions, ProxyLifecycleLoggerSnapshot } from "../types/index.js";
|
|
2
|
+
export declare function hashProxyLifecycleSessionId(sessionId: string | undefined): string | undefined;
|
|
3
|
+
export declare function configureProxyLifecycleLogger(options: ProxyLifecycleLoggerOptions): void;
|
|
4
|
+
/** Enqueue fixed-size lifecycle metadata without awaiting filesystem work. */
|
|
5
|
+
export declare function logProxyLifecycleEvent(input: ProxyLifecycleEventInput): void;
|
|
6
|
+
export declare function flushProxyLifecycleEvents(): Promise<void>;
|
|
7
|
+
export declare function getProxyLifecycleLoggerSnapshot(): ProxyLifecycleLoggerSnapshot;
|
|
8
|
+
export declare function resetProxyLifecycleLoggerForTests(): void;
|