@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
1,082 lines (1,081 loc) • 34.1 kB
TypeScript
/**
* Proxy type definitions for NeuroLink
*
* Consolidates all proxy-related types from:
* - src/lib/proxy/claudeFormat.ts (Claude API types, SSE types, internal result)
* - src/lib/proxy/cloaking/types.ts (cloaking pipeline types)
* - src/lib/proxy/cloaking/plugins/ (plugin option types)
* - src/lib/proxy/modelRouter.ts (routing types)
* - src/lib/proxy/proxyConfig.ts (config file types)
* - src/lib/proxy/requestLogger.ts (log entry type)
* - src/lib/proxy/usageStats.ts (stats types)
* - src/lib/proxy/tokenRefresh.ts (refresh types)
* - src/lib/proxy/accountQuota.ts (quota type)
* - src/lib/server/routes/claudeProxyRoutes.ts (runtime state, deps)
*/
import type { Counter, Histogram, Span } from "@opentelemetry/api";
import type { Hono } from "hono";
import type { Ora } from "ora";
import type { MCPToolRegistry } from "../mcp/toolRegistry.js";
import type { ProxyTracer } from "../proxy/proxyTracer.js";
import type { FallbackEntry, ProxyRoutingConfig, CloakingConfig } from "./subscription.js";
import type { RouteDeprecation } from "./server.js";
/**
* Type describing the ModelRouter contract.
* Defined here to avoid a circular dependency between types and implementation.
*/
export type ModelRouterInterface = {
resolve(requestedModel: string): RouteResult;
isClaudeTarget(requestedModel: string): boolean;
getFallbackChain(): FallbackEntry[];
};
/** A single text block in a Claude content array. */
export type ClaudeTextBlock = {
type: "text";
text: string;
};
/** A single image block in a Claude content array. */
export type ClaudeImageBlock = {
type: "image";
source: {
type: "base64" | "url";
media_type?: string;
data?: string;
url?: string;
};
};
/** Tool-use block returned by Claude in assistant messages. */
export type ClaudeToolUseBlock = {
type: "tool_use";
id: string;
name: string;
input: Record<string, unknown>;
};
/** Tool-result block sent back by the caller. */
export type ClaudeToolResultBlock = {
type: "tool_result";
tool_use_id: string;
content: string | ClaudeContentBlock[];
};
/** A thinking/reasoning block in a Claude content array. */
export type ClaudeThinkingBlock = {
type: "thinking";
thinking: string;
};
export type ClaudeContentBlock = ClaudeTextBlock | ClaudeImageBlock | ClaudeToolUseBlock | ClaudeToolResultBlock | ClaudeThinkingBlock;
/** A single message in a Claude conversation. */
export type ClaudeMessage = {
role: "user" | "assistant";
content: string | ClaudeContentBlock[];
};
/** Tool definition in the Claude Messages API format. */
export type ClaudeTool = {
name: string;
description?: string;
input_schema: Record<string, unknown>;
};
/** Metadata attached to a Claude Messages API request. */
export type ClaudeMetadata = {
user_id?: string;
};
/**
* Inbound Claude Messages API request body.
* Matches POST /v1/messages.
*/
export type ClaudeRequest = {
model: string;
messages: ClaudeMessage[];
max_tokens: number;
system?: string | Array<{
type: "text";
text: string;
}>;
temperature?: number;
top_p?: number;
top_k?: number;
stop_sequences?: string[];
stream?: boolean;
tools?: ClaudeTool[];
tool_choice?: {
type: "auto" | "any" | "none";
} | {
type: "tool";
name: string;
};
thinking?: {
type: string;
budget_tokens?: number;
};
metadata?: ClaudeMetadata;
};
/** Usage counters returned in a Claude response. */
export type ClaudeUsage = {
input_tokens: number;
output_tokens: number;
cache_creation_input_tokens?: number;
cache_read_input_tokens?: number;
};
/** Non-streaming response matching the Claude Messages API. */
export type ClaudeResponse = {
id: string;
type: "message";
role: "assistant";
content: ClaudeContentBlock[];
model: string;
stop_reason: string | null;
stop_sequence: string | null;
usage: ClaudeUsage;
};
/** Claude API error envelope. */
export type ClaudeErrorResponse = {
type: "error";
error: {
type: string;
message: string;
};
};
/** Content block descriptor for content_block_start events. */
export type SSEContentBlockDescriptor = {
type: "text";
text: "";
} | {
type: "thinking";
thinking: "";
} | {
type: "tool_use";
id: string;
name: string;
input: "";
};
/** Delta descriptor for content_block_delta events. */
export type SSEDeltaDescriptor = {
type: "text_delta";
text: string;
} | {
type: "thinking_delta";
thinking: string;
} | {
type: "input_json_delta";
partial_json: string;
};
export type SSEMessageStart = {
type: "message_start";
message: Omit<ClaudeResponse, "content"> & {
content: [];
};
};
export type SSEContentBlockStart = {
type: "content_block_start";
index: number;
content_block: SSEContentBlockDescriptor;
};
export type SSEContentBlockDelta = {
type: "content_block_delta";
index: number;
delta: SSEDeltaDescriptor;
};
export type SSEContentBlockStop = {
type: "content_block_stop";
index: number;
};
export type SSEMessageDelta = {
type: "message_delta";
delta: {
stop_reason: string | null;
stop_sequence: string | null;
};
usage: {
output_tokens: number;
};
};
export type SSEMessageStop = {
type: "message_stop";
};
export type SSEPing = {
type: "ping";
};
export type SSEEvent = SSEMessageStart | SSEContentBlockStart | SSEContentBlockDelta | SSEContentBlockStop | SSEMessageDelta | SSEMessageStop | SSEPing;
/**
* Minimal subset of NeuroLink's GenerateResult that the proxy layer consumes.
* Kept intentionally narrow so the proxy layer does not depend on every
* field of the full type.
*/
export type InternalResult = {
content: string;
model?: string;
finishReason?: string;
/** Thinking/reasoning text from provider (Anthropic thinking blocks, Gemini thought parts) */
reasoning?: string;
usage?: {
input: number;
output: number;
total: number;
cacheCreationTokens?: number;
cacheReadTokens?: number;
};
toolCalls?: Array<{
toolCallId: string;
toolName: string;
args: Record<string, unknown>;
}>;
};
/**
* Parsed representation of a Claude request, ready for NeuroLink's
* generate() / stream() pipeline.
*/
export type ParsedClaudeRequest = {
model: string;
maxTokens: number;
temperature?: number;
topP?: number;
topK?: number;
systemPrompt?: string | Array<{
type: string;
text: string;
}>;
stream: boolean;
/** Flat prompt string derived from the last user message. */
prompt: string;
/** Images extracted from content blocks (base64 data URIs or URLs). */
images: string[];
/**
* Full conversation history converted to NeuroLink's ChatMessage shape.
* Includes all messages, not just the last one.
*/
conversationMessages: Array<{
role: string;
content: string;
}>;
/** Tools translated to AI SDK-compatible shape for provider fallback. */
tools: Record<string, {
description?: string;
inputSchema: unknown;
execute?: (...args: unknown[]) => unknown;
}>;
/**
* Tool choice mapping from Claude format.
* - "auto" -> let the model decide
* - "required" -> force tool use (any tool)
* - "none" -> no tool use
*/
toolChoice?: "auto" | "required" | "none";
/** When toolChoice came from `{type: "tool", name: "..."}`, the tool name. */
toolChoiceName?: string;
/** Thinking configuration parsed from the request. */
thinkingConfig?: {
enabled: boolean;
budgetTokens?: number;
thinkingLevel?: "minimal" | "low" | "medium" | "high";
};
/** Original request metadata (if any). */
metadata?: ClaudeMetadata;
/** Stop sequences from the original request. */
stopSequences?: string[];
};
/** Lifecycle state for the SSE serializer. */
export type StreamLifecycleState = "idle" | "streaming" | "done" | "error";
/** The type of content block currently being streamed. */
export type ContentBlockType = "text" | "thinking" | "tool_use" | null;
/** Minimal account shape needed by the cloaking pipeline. */
export type CloakingAccount = {
id: string;
type: "api_key" | "oauth";
status: "healthy" | "quota_exceeded" | "error";
consecutiveFailures: number;
requestCount: number;
lastUsed: number;
apiKey?: string;
};
/** Request envelope for cloaking pipeline. */
export type CloakingRequest = {
headers: Record<string, string | undefined>;
body: {
messages: Array<{
role: string;
content: string | Array<Record<string, unknown>>;
}>;
system?: string | Array<{
type: string;
text: string;
}>;
metadata?: Record<string, unknown>;
[key: string]: unknown;
};
url: string;
};
/** Response envelope for cloaking pipeline. */
export type CloakingResponse = {
headers: Record<string, string | undefined>;
body: Record<string, unknown>;
status: number;
};
/** Cloaking mode configuration. */
export type CloakingMode = "auto" | "always" | "never";
/** Context passed through the cloaking pipeline. */
export type CloakingContext = {
request: CloakingRequest;
account: CloakingAccount;
config: {
mode: CloakingMode;
plugins: Record<string, unknown>;
};
response?: {
headers: Record<string, string>;
body: unknown;
};
};
/** Plugin interface for cloaking pipeline. */
export type CloakingPlugin = {
/** Human-readable name for logging / debugging. */
name: string;
/** Execution order -- lower numbers run first in processRequest. */
order: number;
/** Whether this plugin is active. Disabled plugins are skipped. */
enabled: boolean;
/**
* Transform the outgoing request before it reaches the upstream API.
* Must return a (possibly mutated) context.
*/
transformRequest: (ctx: CloakingContext) => Promise<CloakingContext>;
/**
* Transform the incoming response before it reaches the client.
* Optional -- plugins that only touch requests can skip this.
*/
transformResponse?: (ctx: CloakingContext) => Promise<CloakingContext>;
};
/** Options for the HeaderScrubber cloaking plugin. */
export type HeaderScrubberOptions = {
/** Additional header names (lower-cased) to strip. */
extraHeaders?: string[];
};
/** Options for the SystemPromptInjector cloaking plugin. */
export type SystemPromptInjectorOptions = {
/** IDE name to inject (default: "vscode"). */
ide?: string;
/** IDE version (default: "1.96.2"). */
ideVersion?: string;
/** Platform string (default: "darwin"). */
platform?: string;
/** Working directory to inject (default: "/home/user/project"). */
cwd?: string;
/** Extra preamble to prepend. */
preamble?: string;
};
/** Options for the TlsFingerprint cloaking plugin. */
export type TlsFingerprintOptions = {
/** Target fingerprint profile (e.g. "chrome-131", "node-22", "claude-code"). */
profile?: string;
/** Whether the stub should log a warning that it is a no-op. */
warnOnUse?: boolean;
};
/**
* Proxy operating mode:
* - "full" — managed accounts, retry, rotation, polyfill (default)
* - "passthrough" — no polyfill/retry/rotation, but body is still parsed and re-serialized
* - "transparent" — zero-mutation byte relay: raw body forwarded as-is, minimal header filtering,
* SSE interceptor for cache metrics only (bytes pass through unmodified)
*/
export type ProxyMode = "full" | "passthrough" | "transparent";
export type RouteResult = {
provider: string | null;
model: string;
};
/** Individual account configuration within a proxy config file. */
export type ProxyAccountConfig = {
/** Human-readable name for the account */
name: string;
/** API key or token (may contain env var references) */
apiKey: string;
/** Base URL override for the provider endpoint */
baseUrl?: string;
/** Organization ID (e.g., OpenAI orgs) */
orgId?: string;
/** Weight for weighted round-robin selection (default: 1) */
weight?: number;
/** Whether this account is currently enabled (default: true) */
enabled?: boolean;
/** Maximum requests per minute for this account */
rateLimit?: number;
/** Arbitrary metadata attached to the account */
metadata?: Record<string, unknown>;
};
/** Top-level proxy configuration structure. */
export type ProxyConfigFile = {
/** Configuration schema version */
version?: number;
/** Default provider name to apply when not specified per-account */
defaultProvider?: string;
/** Default base URL applied to accounts that omit baseUrl */
defaultBaseUrl?: string;
/** Map of provider names to their account lists */
accounts: Record<string, ProxyAccountConfig[]>;
/** Routing configuration (strategy, model mappings, fallback chain) */
routing?: Partial<ProxyRoutingConfig>;
/** Cloaking plugin configuration */
cloaking?: CloakingConfig;
};
/** Options for loadProxyConfig. */
export type LoadProxyConfigOptions = {
/** Resolve environment variables in string values (default: true) */
resolveEnv?: boolean;
/** Custom environment object (defaults to process.env) */
env?: Record<string, string | undefined>;
};
export type RequestLogEntry = {
timestamp: string;
requestId: string;
method: string;
path: string;
model: string;
stream: boolean;
toolCount: number;
account: string;
accountType: string;
responseStatus: number;
responseTimeMs: number;
errorType?: string;
errorMessage?: string;
inputTokens?: number;
outputTokens?: number;
cacheCreationTokens?: number;
cacheReadTokens?: number;
/** OTel trace ID for correlation with distributed traces */
traceId?: string;
/** OTel span ID for correlation with distributed traces */
spanId?: string;
};
export type RequestAttemptLogEntry = {
timestamp: string;
requestId: string;
attempt: number;
method: string;
path: string;
model: string;
stream: boolean;
toolCount: number;
account: string;
accountType: string;
responseStatus: number;
responseTimeMs: number;
errorType?: string;
errorMessage?: string;
inputTokens?: number;
outputTokens?: number;
cacheCreationTokens?: number;
cacheReadTokens?: number;
/** OTel trace ID for correlation with distributed traces */
traceId?: string;
/** OTel span ID for correlation with distributed traces */
spanId?: string;
};
export type ProxyBodyCaptureInput = {
phase: string;
headers?: Record<string, string>;
body?: unknown;
bodySize?: number;
contentType?: string;
responseStatus?: number;
durationMs?: number;
account?: string;
accountType?: string;
attempt?: number;
metadata?: Record<string, unknown>;
};
export type ProxyBodyCaptureLogger = (capture: ProxyBodyCaptureInput) => void;
export type ClaudeFinalRequestLogger = (status: number, accountLabel: string, accountType: string, errorType?: string, errorMessage?: string, extra?: {
inputTokens?: number;
outputTokens?: number;
cacheCreationTokens?: number;
cacheReadTokens?: number;
}) => void;
export type ClaudeLoggedErrorBuilder = (status: number, message: string, errorType?: string, extra?: {
account?: string;
accountType?: string;
attempt?: number;
}) => ClaudeErrorResponse;
export type ClaudeRequestRuntimeContext = {
tracer?: ProxyTracer;
requestStartTime: number;
logProxyBody: ProxyBodyCaptureLogger;
logFinalRequest: ClaudeFinalRequestLogger;
buildLoggedClaudeError: ClaudeLoggedErrorBuilder;
};
export type AnthropicAttemptLogger = (status: number, errorType?: string, errorMessage?: string, extra?: {
inputTokens?: number;
outputTokens?: number;
cacheCreationTokens?: number;
cacheReadTokens?: number;
}) => void;
export type AnthropicLoopState = {
lastError: unknown;
sawRateLimit: boolean;
sawNetworkError: boolean;
sawTransientFailure: boolean;
invalidRequestFailure: {
status: number;
body: string;
contentType?: string;
} | null;
authFailureMessage: string | null;
attemptNumber: number;
};
export type AnthropicUpstreamBody = {
bodyStr: string;
sessionId?: string;
};
export type AnthropicUpstreamBodyBuilder = (token: string) => AnthropicUpstreamBody;
export type LoadedClaudeAccountContext = {
accounts: ProxyPassthroughAccount[];
enabledAccounts: ProxyPassthroughAccount[];
orderedAccounts: ProxyPassthroughAccount[];
bodyStr: string;
requestStart: number;
toolCount: number;
url: string;
clientHeaders: Record<string, string | undefined>;
isClaudeClientRequest: boolean;
};
export type AnthropicSuccessResult = {
retryNextAccount: true;
} | {
response: Response | unknown;
};
export type AnthropicAuthRetryResult = {
response?: Response | unknown;
continueLoop: boolean;
lastError: unknown;
authFailureMessage: string | null;
sawRateLimit: boolean;
sawTransientFailure: boolean;
sawNetworkError: boolean;
upstreamSpan?: Span;
};
export type AnthropicNonOkResult = {
response?: Response | unknown;
continueLoop: boolean;
retrySameAccount?: boolean;
lastError: unknown;
authFailureMessage: string | null;
sawTransientFailure: boolean;
invalidRequestFailure: {
status: number;
body: string;
contentType?: string;
} | null;
upstreamSpan?: Span;
};
export type PreparedAnthropicAccountAttempt = {
continueLoop: boolean;
lastError: unknown;
authFailureMessage: string | null;
headers?: Record<string, string>;
buildUpstreamBody?: AnthropicUpstreamBodyBuilder;
finalBodyStr?: string;
fetchStartMs?: number;
upstreamSpan?: Span;
};
export type AnthropicUpstreamFetchResult = {
continueLoop: boolean;
retrySameAccount?: boolean;
/** When set, the caller should wait this many ms before retrying (from upstream retry-after). */
retryAfterMs?: number;
response?: Response;
lastError: unknown;
sawRateLimit: boolean;
sawNetworkError: boolean;
upstreamSpan?: Span;
};
export type AccountStats = {
label: string;
type: string;
attemptCount: number;
successCount: number;
errorCount: number;
rateLimitCount: number;
lastAttemptAt: number;
lastErrorAt?: number;
};
export type ProxyStats = {
startedAt: number;
totalAttempts: number;
totalRequests: number;
totalSuccess: number;
totalErrors: number;
totalRateLimits: number;
accounts: Record<string, AccountStats>;
};
export type RefreshableAccount = {
token: string;
refreshToken?: string;
expiresAt?: number;
label: string;
};
export type RefreshResult = {
success: boolean;
error?: string;
status?: number;
};
export type TokenPersistTarget = string | {
credPath: string;
} | {
providerKey: string;
};
export type AccountQuota = {
/** 0.0-1.0 (from unified-5h-utilization) */
sessionUsed: number;
/** "allowed" | "throttled" | "rejected" */
sessionStatus: string;
/** Unix timestamp (seconds) when the 5h window resets */
sessionResetAt: number;
/** 0.0-1.0 (from unified-7d-utilization) */
weeklyUsed: number;
/** "allowed" | "throttled" | "rejected" */
weeklyStatus: string;
/** Unix timestamp (seconds) when the 7d window resets */
weeklyResetAt: number;
/** 0.0-1.0 (from fallback-percentage) */
fallbackPercentage: number;
/** "allowed" | "rejected" */
overageStatus: string;
/** Epoch ms when we last captured this data */
lastUpdated: number;
};
/** Runtime state for a proxy account. */
export type RuntimeAccountState = {
consecutiveRefreshFailures: number;
permanentlyDisabled: boolean;
lastToken?: string;
lastRefreshToken?: string;
/** Epoch-ms timestamp until which the account should not be used for new
* requests (set after 429 retries are exhausted). Other requests arriving
* during this window will skip the account rather than hammering it again. */
coolingUntil?: number;
};
/** A passthrough account used in the proxy route handler. */
export type ProxyPassthroughAccount = {
key: string;
label: string;
token: string;
refreshToken?: string;
expiresAt?: number;
type: "oauth" | "api_key";
persistTarget?: TokenPersistTarget;
};
/** Dependencies for creating Claude proxy routes. */
export type ClaudeProxyDeps = {
modelRouter?: ModelRouterInterface;
};
/** Rate limit store entry (Koa adapter). */
export type KoaRateLimitEntry = {
count: number;
resetAt: number;
};
/** Rate limit context (Fastify adapter). */
export type FastifyRateLimitContext = {
ttl: number;
ban?: boolean;
};
/** Rate limit store entry (Hono adapter). */
export type HonoRateLimitEntry = {
count: number;
resetAt: number;
};
/** Information about a deprecated route. */
export type DeprecatedRouteInfo = {
method: string;
path: string;
deprecation: RouteDeprecation;
};
/** Cache entry for response caching middleware. */
export type ResponseCacheEntry<T = unknown> = {
value: T;
expiresAt: number;
};
/** Close handler for data stream writers. */
export type CloseHandler = () => void;
/** Cached session entry with TTL for the SessionIdentity cloaking plugin. */
export type CachedSession = {
userId: string;
expiresAt: number;
};
/** Model tier classification for proxy routing decisions. */
export type ClaudeProxyModelTier = "opus" | "sonnet" | "haiku" | "other";
/** A single provider attempt in the proxy translation plan. */
export type ProxyTranslationAttempt = {
provider?: string;
model?: string;
label: string;
};
/** Ordered plan of provider attempts for a proxy request. */
export type ProxyTranslationPlan = {
requestedModel: string;
modelTier: ClaudeProxyModelTier;
attempts: ProxyTranslationAttempt[];
skipped: never[];
};
/** Mutable readiness state tracked by the proxy process. */
export type ProxyReadinessState = {
startTimeMs: number;
acceptingConnections: boolean;
ready: boolean;
readyAtMs?: number;
};
/** Structured response returned by the proxy /health endpoint. */
export type ProxyHealthResponse = {
status: "ok" | "starting";
ready: boolean;
acceptingConnections: boolean;
strategy: string;
passthrough: boolean;
version: string;
startedAt: string;
readyAt: string | null;
uptime: number;
healthPath: "/health";
statusPath: "/status";
};
export type ProxyPaths = {
/** Base directory for proxy state files */
stateDir: string;
/** logs/ — request/response logs */
logsDir: string;
/** account-quotas.json — per-account rate limit state */
quotaFile: string;
/** Whether this is a dev-mode isolated instance */
isDev: boolean;
};
/** OTel metric instruments used by the proxy tracer. */
export type ProxyMetrics = {
requestsTotal: Counter;
requestDuration: Histogram;
tokensInput: Counter;
tokensOutput: Counter;
tokensCacheRead: Counter;
tokensCacheCreation: Counter;
tokensReasoning: Counter;
costTotal: Counter;
errorsTotal: Counter;
retriesTotal: Counter;
modelSubstitutionTotal: Counter;
requestBodySize: Histogram;
responseBodySize: Histogram;
fallbackAttemptsTotal: Counter;
fallbackSuccessTotal: Counter;
fallbackFailureTotal: Counter;
};
/** Context for a proxy request at the root span level. */
export type ProxyRequestContext = {
requestId: string;
method: string;
path: string;
model: string;
stream: boolean;
toolCount: number;
sessionId?: string;
userAgent?: string;
clientApp?: string;
};
/** Context recorded when an account is selected for a proxy request. */
export type AccountSelectionContext = {
strategy: string;
accountsTotal: number;
accountsHealthy: number;
selectedAccount: string;
accountType: string;
rateLimitBefore5h?: number;
rateLimitBefore7d?: number;
};
/** Context for a single upstream attempt (one per retry). */
export type UpstreamAttemptContext = {
attempt: number;
account: string;
polyfillHeaders: boolean;
polyfillBody: boolean;
upstreamUrl: string;
};
/** Token usage and rate-limit utilisation recorded at end of request. */
export type UsageContext = {
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
reasoningTokens?: number;
rateLimitAfter5h?: number;
rateLimitAfter7d?: number;
};
/** Where a proxy env file path was sourced from. */
export type ProxyEnvSource = "cli" | "environment" | "default" | "none";
/** Result of resolving which proxy env file to load. */
export type ProxyEnvResolution = {
path?: string;
source: ProxyEnvSource;
required: boolean;
};
/** Result of loading the proxy env file. */
export type ProxyEnvLoadResult = {
loaded: boolean;
path?: string;
source: ProxyEnvSource;
};
/** Options controlling proxy env file resolution. */
export type ProxyEnvOptions = {
explicitEnvFile?: string;
env?: NodeJS.ProcessEnv;
homeDir?: string;
};
/** Snapshot of proxy-related environment variables captured at startup. */
export type ProxyEnvironmentSnapshot = {
httpsProxy?: string;
httpProxy?: string;
allProxy?: string;
socksProxy?: string;
noProxy?: string;
};
/** Result of a traffic-quiet check. */
export type QuietStatus = {
isQuiet: boolean;
lastActivityAt: Date | null;
silenceDurationMs: number;
};
/** Accumulated upstream body capture from a raw stream. */
export type RawStreamCapture = {
totalBytes: number;
text: string;
truncated: boolean;
};
/** Transformed stream pair used to capture upstream bodies without buffering. */
export type RawStreamCaptureResult = {
stream: TransformStream<Uint8Array, Uint8Array>;
capture: Promise<RawStreamCapture>;
};
/** Single captured body/headers entry written to disk by the proxy logger. */
export type ProxyBodyCaptureEntry = {
timestamp: string;
requestId: string;
phase: string;
model: string;
stream: boolean;
headers?: Record<string, string>;
body?: unknown;
bodySize?: number;
contentType?: string;
responseStatus?: number;
durationMs?: number;
account?: string;
accountType?: string;
attempt?: number;
traceId?: string;
spanId?: string;
metadata?: Record<string, unknown>;
};
/** Persisted artifact produced when a body is stored to disk. */
export type StoredBodyArtifact = {
bodyPath?: string;
bodySha256?: string;
redactedBodyBytes?: number;
storedFileBytes?: number;
redactedBody?: string;
bodyTruncated?: boolean;
};
/** File the proxy logger tracks for rotation and cleanup. */
export type ManagedLogFile = {
path: string;
mtime: number;
size: number;
};
/** Individual content block observed during an SSE stream. */
export type SSEContentBlock = {
index: number;
type: "text" | "thinking" | "tool_use" | "tool_result";
/** Accumulated text for text blocks. Capped at MAX_BLOCK_CONTENT_BYTES. */
text?: string;
/** Accumulated thinking content. Capped at MAX_BLOCK_CONTENT_BYTES. */
thinking?: string;
/** Tool name for tool_use blocks. */
toolName?: string;
/** Tool call id for tool_use blocks. */
toolId?: string;
/** Accumulated partial JSON input for tool_use blocks. Capped at MAX_BLOCK_CONTENT_BYTES. */
toolInput?: string;
};
/** Aggregated telemetry resolved when an SSE stream completes. */
export type SSETelemetry = {
messageId: string;
model: string;
usage: {
inputTokens: number;
outputTokens: number;
cacheCreationInputTokens: number;
cacheReadInputTokens: number;
totalTokens: number;
};
contentBlocks: SSEContentBlock[];
stopReason: string | null;
stopSequence: string | null;
eventCount: number;
streamDurationMs: number;
totalBytesReceived: number;
events: Array<{
type: string;
timestamp: number;
data: string;
}>;
rawText?: string;
};
/** Mutable accumulator the SSE interceptor uses internally. */
export type TelemetryAccumulator = {
messageId: string;
model: string;
inputTokens: number;
outputTokens: number;
cacheCreationInputTokens: number;
cacheReadInputTokens: number;
contentBlocks: SSEContentBlock[];
blockByteCounts: Map<number, number>;
stopReason: string | null;
stopSequence: string | null;
eventCount: number;
startTime: number;
totalBytesReceived: number;
events: Array<{
type: string;
timestamp: number;
data: string;
}>;
rawTextChunks?: string[];
rawTextBytes: number;
rawTextTruncated: boolean;
eventLogTruncated: boolean;
};
/** Result of createSSEInterceptor: the pass-through stream and a telemetry promise. */
export type SSEInterceptorResult = {
stream: TransformStream<Uint8Array, Uint8Array>;
telemetry: Promise<SSETelemetry>;
};
/** Options for createSSEInterceptor. */
export type SSEInterceptorOptions = {
captureRawText?: boolean;
};
/** Outcome of a proxy auto-update version check against npm. */
export type UpdateCheckResult = {
currentVersion: string;
latestVersion: string;
updateAvailable: boolean;
};
/** Parsed major.minor.patch components of a semver string. */
export type SemVer = {
major: number;
minor: number;
patch: number;
};
/** Entry describing a version suppressed from auto-update. */
export type SuppressedVersion = {
suppressedAt: string;
reason: string;
};
/** Persisted state for the proxy auto-update feature. */
export type UpdateState = {
lastCheckAt: string;
lastCheckVersion: string;
suppressedVersions: Record<string, SuppressedVersion>;
lastUpdateAt: string | null;
lastUpdateVersion: string | null;
};
/** Shape of the dynamically-imported js-yaml module. `dump` is optional —
* read-only consumers (proxy config loader) only need `load`; writers
* (CLI primary-account commands) check `dump` before calling. */
export type YamlModule = {
load(content: string): unknown;
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
default?: {
load(content: string): unknown;
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
};
};
/** Snapshot of a parsed proxy config file used by CLI primary-account
* read/edit/write helpers. Tracks the original format and whether comments
* were present (so the CLI can warn that comments will not round-trip). */
export type CliProxyConfigDoc = {
data: Record<string, unknown>;
format: "yaml" | "json";
hadComments: boolean;
};
/** Primary-account info exposed by the proxy `/status` endpoint.
* `source` is "configured" when the operator's `routing.primaryAccount` is
* authenticated and enabled, otherwise "fallback" — either no primary set
* or the configured one is missing/disabled. */
export type ProxyStatusPrimaryAccount = {
configured: string | null;
key: string | null;
label: string | null;
source: "configured" | "fallback";
};
/** Parsed fields captured from a Claude Code client request body. */
export type ClaudeSnapshotBody = {
metadataUserId?: string;
billingHeader?: string;
agentBlock?: string;
sessionId?: string;
};
/** Snapshot of headers and body from a Claude Code request, used for polyfill. */
export type ClaudeSnapshot = {
accountKey: string;
capturedAt: string;
source: "claude-code";
headers: Record<string, string>;
body?: ClaudeSnapshotBody;
};
/** Parsed shape of a Claude API error body. */
export type ParsedClaudeError = {
errorType?: string;
message?: string;
};
/** ora spinner instance held by proxy CLI commands, nullable when --quiet. */
export type ProxySpinner = Ora | null;
/** Load-balancing strategy used by the proxy across accounts. */
export type ProxyStartStrategy = "round-robin" | "fill-first";
/** Alias for the model router's constructor configuration. */
export type ProxyModelRouterConfig = ProxyRoutingConfig;
/** Partial proxy config consumed by the start command. */
export type LoadedProxyConfig = {
routing?: Partial<ProxyModelRouterConfig> & {
strategy?: ProxyStartStrategy;
};
};
/**
* Handle for a NeuroLink runtime created by the proxy start command.
* The `neurolink` field is typed structurally (only the method used by the
* proxy layer is exposed) so types/proxy.ts does not depend on the full
* NeuroLink class.
*/
export type ProxyNeurolinkRuntime = {
neurolink: {
getToolRegistry(): MCPToolRegistry;
};
cleanupLogs: (daysToKeep?: number, maxFiles?: number) => void;
};
/** Hono app + readiness state created by the proxy start command. */
export type ProxyStartApp = {
app: Hono;
readiness: ProxyReadinessState;
};
/** Stats shape consumed by the proxy status printer. */
export type StatusStats = {
totalAttempts?: number;
totalRequests: number;
totalSuccess: number;
totalErrors: number;
totalRateLimits: number;
accounts?: {
label: string;
type: string;
attempts?: number;
requests?: number;
success?: number;
errors?: number;
rateLimits?: number;
cooling: boolean;
}[];
};
/** Sub-action of the `proxy telemetry` CLI command. */
export type ProxyTelemetryAction = "setup" | "start" | "stop" | "status" | "logs" | "import-dashboard";