@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
175 lines • 6.94 kB
JavaScript
import { readFile, stat } from "node:fs/promises";
import { resolve } from "node:path";
import chalk from "chalk";
import { compareProxyReplayBundle, exportProxyReplayBundle, isValidProxyReplayHeaderName, readProxyReplayBundle, writeProxyReplayDocument, } from "../../proxy/proxyReplay.js";
import { logger } from "../../utils/logger.js";
const ACTIONS = ["export", "compare"];
const MAX_BODY_OVERRIDE_BYTES = 16 * 1024 * 1024;
function requiredValue(value, option) {
if (!value) {
throw new Error(`${option} is required for this action`);
}
return value;
}
function resolveHeaderValues(mappings) {
const values = {};
for (const mapping of mappings ?? []) {
const separator = mapping.indexOf("=");
if (separator <= 0 || separator === mapping.length - 1) {
throw new Error(`Invalid --header-env value "${mapping}". Use header-name=ENV_VAR.`);
}
const header = mapping.slice(0, separator).trim().toLowerCase();
if (!isValidProxyReplayHeaderName(header)) {
throw new Error(`Invalid header name in --header-env: ${header}`);
}
const environmentName = mapping.slice(separator + 1).trim();
const value = process.env[environmentName];
if (!value) {
throw new Error(`Environment variable ${environmentName} is empty or unset for header ${header}`);
}
values[header] = value;
}
return values;
}
async function readBodyOverride(filePath) {
if (!filePath) {
return undefined;
}
const resolvedPath = resolve(filePath);
const info = await stat(resolvedPath);
if (!info.isFile() || info.size > MAX_BODY_OVERRIDE_BYTES) {
throw new Error(`Body override must be a regular file no larger than ${MAX_BODY_OVERRIDE_BYTES} bytes`);
}
return readFile(resolvedPath, "utf8");
}
function printResult(format, value) {
logger.always(format === "json"
? JSON.stringify(value)
: Object.entries(value)
.map(([key, child]) => `${key}: ${String(child)}`)
.join("\n"));
}
export const proxyReplayCommand = {
command: "replay <action>",
describe: "Export captured proxy requests or compare them directly upstream",
builder: (yargs) => yargs
.positional("action", {
type: "string",
choices: [...ACTIONS],
describe: "Replay action",
})
.option("request-id", {
type: "string",
alias: "requestId",
description: "Captured proxy request ID to export",
})
.option("attempt", {
type: "number",
description: "Specific upstream attempt to reconstruct",
})
.option("logs-dir", {
type: "string",
alias: "logsDir",
description: "Proxy log directory",
})
.option("bundle", {
type: "string",
description: "Replay bundle to compare directly upstream",
})
.option("output", {
type: "string",
alias: "o",
description: "Destination JSON file",
})
.option("execute", {
type: "boolean",
default: false,
description: "Explicitly permit the direct upstream request",
})
.option("header-env", {
type: "string",
array: true,
alias: "headerEnv",
description: "Inject a redacted header from an environment variable (header=ENV_VAR)",
})
.option("body-file", {
type: "string",
alias: "bodyFile",
description: "Complete request body override for redacted/truncated captures",
})
.option("url", {
type: "string",
description: "Explicit direct endpoint override",
})
.option("timeout-ms", {
type: "number",
alias: "timeoutMs",
default: 120_000,
description: "Direct request timeout",
})
.option("format", {
type: "string",
choices: ["text", "json"],
default: "text",
description: "Command summary format",
})
.option("quiet", {
type: "boolean",
alias: "q",
default: false,
description: "Suppress non-essential output",
})
.example("neurolink proxy replay export --request-id req-123 --output replay.json", "Create a deterministic offline replay bundle")
.example("neurolink proxy replay compare --bundle replay.json --output comparison.json --execute --header-env authorization=ANTHROPIC_AUTHORIZATION", "Execute the captured upstream request with an environment-backed credential"),
handler: async (argv) => {
try {
const output = requiredValue(argv.output, "--output");
if (argv.action === "export") {
const requestId = requiredValue(argv.requestId, "--request-id");
const bundle = await exportProxyReplayBundle({
requestId,
logsDir: argv.logsDir,
attempt: argv.attempt,
});
const written = await writeProxyReplayDocument(output, bundle);
if (!argv.quiet) {
printResult(argv.format ?? "text", {
action: "export",
output: written.path,
sha256: written.sha256,
captures: bundle.completeness.captures,
replayable: bundle.completeness.replayable,
blockers: bundle.completeness.blockers.join(",") || "none",
});
}
return;
}
const bundlePath = requiredValue(argv.bundle, "--bundle");
const bundle = await readProxyReplayBundle(bundlePath);
const comparison = await compareProxyReplayBundle(bundle, {
execute: argv.execute === true,
headerValues: resolveHeaderValues(argv.headerEnv),
bodyOverride: await readBodyOverride(argv.bodyFile),
urlOverride: argv.url,
timeoutMs: argv.timeoutMs,
});
const written = await writeProxyReplayDocument(output, comparison);
if (!argv.quiet) {
printResult(argv.format ?? "text", {
action: "compare",
output: written.path,
sha256: written.sha256,
status: comparison.direct.status,
statusMatches: comparison.comparison.statusMatches,
bodyHashMatches: comparison.comparison.bodyHashMatches,
jsonShapeMatches: comparison.comparison.jsonShapeMatches,
});
}
}
catch (error) {
logger.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
process.exitCode = 1;
}
},
};
//# sourceMappingURL=proxyReplay.js.map