import { type IncomingMessage, type Server, type ServerResponse } from "node:http"; import { type Config, type ResolvedTarget } from "./config.js"; import { MetadataLogger } from "./log.js"; import type { ResolvedAttempt } from "./resolved-attempt.js"; import { CredentialLru } from "./credential-select.js"; import { ToolUseValidator } from "./validator.js"; import { type Reshaper } from "./reshaper.js"; import { ModelCatalog } from "./catalog.js"; import { PingLoop } from "./ping/cadence.js"; import { type AccountingPricePort, type AccountingRecorder } from "./accounting.js"; import { type ModelCallRecorder } from "./accounting-state.js"; import type { AccountingReader, AccountingStore } from "./accounting-store.js"; import { DashboardAuthManager } from "./dashboard-auth.js"; import { createDashboardSnapshotReadPort } from "./dashboard-snapshot.js"; import { DashboardStaticHandler } from "./dashboard-static.js"; import type { AttributionPolicy } from "./dashboard-contract.js"; import { CircuitBreaker } from "./circuit-breaker.js"; import { type QuotaDemotionFn } from "./quota-demotion.js"; import { type LatencyDemotionFn } from "./latency-demotion.js"; import { type PacingFn } from "./pacing.js"; import { type HedgeDelayDecision } from "./hedge-trigger.js"; import { type HardCapVerdict } from "./hard-cap.js"; import { type ControlAuthorizationPort } from "./control-authorization.js"; import { StickySessionManager } from "./session-pin.js"; import { type CostClassFn, type ProbationFn } from "./candidate-runner.js"; import { type LaneExecutionBrokerPort } from "./lane-execution-broker.js"; export { baseLog, logSafePath } from "./request-log.js"; export { DEFAULT_MAX_BODY_BYTES } from "./stream-pipeline.js"; export { orderByUsability, classifyStatus, buildForwardHeaders, CredentialConfigError } from "./candidate-runner.js"; export declare const TOKENLESS_CONTROL_READ_PATHS: readonly ["/v1/models", "/models", "/offload", "/dispatch", "/telemetry"]; export interface ProxyDeps { reshaper?: Reshaper; catalog?: ModelCatalog; pingLoop?: PingLoop; breaker?: CircuitBreaker; modelCallRecorder?: ModelCallRecorder; accountingRecorder?: AccountingRecorder; accountingReader?: AccountingReader; accountingPricePortOverride?: AccountingPricePort | undefined; dashboardAssetRoot?: string; /** Version loaded by this proxy process; "unknown" when an embedder does not supply one. */ relayVersion?: string; /** Dashboard-only override; otherwise the dashboard uses relayVersion. */ dashboardRelayVersion?: string; dashboardAttributionPolicy?: AttributionPolicy; controlAuthorization?: ControlAuthorizationPort | null; /** * D1 daemon-owned lane execution broker. undefined installs the production configured broker; * null explicitly disables it for fail-closed embeds/tests. */ laneExecutionBroker?: LaneExecutionBrokerPort | null; /** * D2 validated config loader. Production injects the same source path + CLI overrides used at * startup. Absent/null keeps /reload fail-closed for programmatic embeds. */ reloadConfig?: (() => Config) | null; /** Best-effort post-commit warm/validation hook. It can never roll back an accepted config. */ onReloaded?: (cfg: Config) => void | Promise; /** Optional shutdown callback — called by POST /stop after responding 202. A bare programmatic proxy with no onStop answers 503. */ onStop?: () => void; } export declare function dashboardExpectedOriginForAuthority(hostname: string, port: number): string; export interface Handlers { validator: ToolUseValidator; logger: MetadataLogger; isDestructive: (name: string) => boolean; resolveReshaper: (attempt: ResolvedAttempt) => Reshaper | undefined; catalog: ModelCatalog; pingLoop?: PingLoop; breaker: CircuitBreaker; /** Package version loaded by this daemon process; absent only for an unversioned embed. */ relayVersion?: string; credentialLru: CredentialLru; modelCallRecorder?: ModelCallRecorder; accountingRecorder: AccountingRecorder; readonly accountingReader?: Pick; accountingPricePort: AccountingPricePort | undefined; dashboardAuth: DashboardAuthManager; dashboardStatic: DashboardStaticHandler; dashboardRead: ReturnType; stickySessions?: StickySessionManager; controlAuthorization?: ControlAuthorizationPort; laneExecutionBroker?: LaneExecutionBrokerPort; server: Server; quotaDemotion: QuotaDemotionFn; latencyDemotion: LatencyDemotionFn; probation: ProbationFn; pacing: PacingFn; hedgeDelay: (attempt: ResolvedAttempt, estimatedInputTokens: number) => HedgeDelayDecision | null; hedgeMaxInFlight: number; costClassOf: CostClassFn; /** See `CandidateRunnerHandlers.catalogStale` — wired to `ModelCatalog.noteProviderStale`. */ catalogStale: (attempt: ResolvedAttempt) => void; hardCap: (attempt: ResolvedAttempt, now: number) => HardCapVerdict | null; /** Optional shutdown callback — called by POST /stop after responding 202. */ onStop?: () => void; /** True the first time GET /telemetry observes the loaded config changed on disk, false on * every call after — so the daemon logs the fact exactly once (see config.ts `configStaleness`). */ claimConfigStalenessLogOnce: () => boolean; } /** * The context ceiling this relay may hold a deployment to, and WHICH rung stated it. * * Two rungs, most-authoritative first — the `contextWindowResolver` order, minus its snapshot rung: * * 1. `observed` — a `context-limit` fact recorded when THIS deployment stated its own maximum while * refusing an over-length request (`context-limits.ts`, deployment scope, 30-day TTL). It is * first-party evidence about the exact deployment, which a catalogue figure can contradict by * being generic or stale. * 2. `published` — the serving provider's own `contextLength` from the catalogue, read cache-only. * * Null when neither rung answers, and null must stay "no guardrail": the request goes upstream and * the backend returns its own authoritative error. ⚠ There is deliberately no invented third rung — * a 400 built from a number nobody stated is worse than a true upstream error. * * ⚠ The BASIS travels with the number because the refusal body names it. Reporting a learned * measurement as something the provider "publishes" is the one thing the provenance invariant * forbids, and the body said exactly that for every rung until 2026-09-01. */ export declare function contextCeilingFor(target: ResolvedTarget, catalog: Pick): { limit: number; basis: "observed" | "published"; } | null; export declare function createProxy(cfg: Config, deps?: ProxyDeps): Server;