@coool/pi-adaptive 1.0.0 → 1.0.1
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/README.md +98 -196
- package/dist/index.d.ts +2 -1
- package/dist/index.js +603 -343
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["isRecord","object","object","isRecord","parseVocab","parse","field","parse","object","isFiniteNumber","failureEvent","isRecord","isFiniteNumber","parseIdentifier","parseKey","failureEvent","parseKey","parse","object","field","field","payload","object","matrix.minimum","baseline.testedUpTo"],"sources":["../../core/src/routing/compatibility/types.ts","../../core/src/health/circuit-breaker/types.ts","../../core/src/health/resource-health/types.ts","../../core/src/health/resource-health/key.ts","../../core/src/routing/scheduler/types.ts","../../core/src/routing/work-unit/types.ts","../../core/src/routing/tier-policy/tier-list.ts","../../core/src/routing/tier-policy/types.ts","../../core/src/state/settings/parse.ts","../../core/src/execution/continuation/prompts.ts","../../core/src/execution/escalation/types.ts","../../core/src/log.ts","../src/settings.ts","../src/preferences.ts","../../core/src/state/receipts/bound.ts","../../core/src/routing/work-unit/interruption.ts","../../core/src/health/classifier/types.ts","../../core/src/state/receipts/parse.ts","../../core/src/state/receipts/store.ts","../src/receipts.ts","../../core/src/routing/compatibility/gate.ts","../../core/src/routing/scheduler/admit.ts","../src/router.ts","../../core/src/health/classifier/classify.ts","../../core/src/routing/scheduler/escalate.ts","../src/evidence.ts","../src/task.ts","../src/session.ts","../../core/src/flow/tiers.ts","../src/ui/notes.ts","../../core/src/health/circuit-breaker/breaker.ts","../../core/src/health/capacity/types.ts","../../core/src/health/capacity/merge.ts","../../core/src/health/resource-health/failure.ts","../../core/src/health/resource-health/transitions.ts","../../core/src/health/resource-health/registry.ts","../../core/src/state/health/parse.ts","../../core/src/state/health/store.ts","../src/health.ts","../../core/src/sensors/codex-capacity/types.ts","../../core/src/sensors/codex-capacity/parse.ts","../../core/src/sensors/codex-capacity/reading.ts","../../core/src/sensors/codex-capacity/sensor.ts","../../core/src/state/capacity/parse.ts","../src/capacity.ts","../src/host/dispatch-capacity.ts","../src/host/entries.ts","../../core/src/routing/scheduler/mode.ts","../../core/src/execution/parking/wake.ts","../src/parking.ts","../../../node_modules/@earendil-works/pi-ai/dist/utils/text.js","../../../node_modules/@earendil-works/pi-ai/dist/utils/estimate.js","../src/host/inventory.ts","../src/host/routing.ts","../src/host/tools.ts","../src/host/observe.ts","../src/host/parked-view.ts","../src/host/parking.ts","../../core/src/flow/waiting.ts","../src/health-actions.ts","../src/ui/copy.ts","../src/ui/doctor.ts","../src/capabilities.ts","../src/host/actions.ts","../../core/src/flow/status.ts","../../core/src/flow/menu.ts","../../core/src/flow/options.ts","../../core/src/flow/receipts.ts","../../core/src/flow/controller.ts","../src/host/commands.ts","../src/host/control.ts","../src/host/doctor.ts","../src/ui/proposal.ts","../../core/src/status.ts","../src/host/onboarding.ts","../src/host/status.ts","../src/host/view.ts","../src/host/adaptive.ts","../src/host/status-chip.ts","../src/host/extension.ts","../src/store.ts","../src/host/timer.ts","../pi-host-baseline.json","../pi-host-matrix.json","../src/index.ts"],"sourcesContent":["/**\n * Compatibility gate (ADP-017): filters candidates on context capacity,\n * tool use, modalities, and model/variant/provider availability BEFORE\n * health/preference ranking. Pure — adapters map OpenCode `Model.Info` /\n * `Provider.Info` into `CandidateModel`, this module never touches\n * `@opencode/plugin` types.\n *\n * Conservative rule: metadata the gate needs but cannot see is treated as\n * NOT satisfying the requirement (e.g. unknown `enabled`, unknown tool\n * support, unknown context limit). Only demand-side quantities that are\n * themselves unknown are skipped — there is nothing to check against.\n */\n\n/** What the executing work needs from a resource. All demand fields are optional. */\nexport interface Demand {\n /** The unit needs tool use. `undefined`/`false` imposes no tool requirement. */\n readonly tools?: boolean | undefined\n /** Input modalities the unit carries (e.g. `\"text\"`, `\"image\"`). */\n readonly input?: readonly string[] | undefined\n /** Output modalities the unit must produce. */\n readonly output?: readonly string[] | undefined\n /** Known or estimated context need in tokens; `undefined` skips the capacity check. */\n readonly contextTokens?: number | undefined\n}\n\n/** Adapter-normalized view of one candidate resource. */\nexport interface CandidateModel {\n readonly providerID: string\n readonly modelID: string\n readonly variant?: string | undefined\n /** Model is enabled in the host inventory. Unknown ⇒ conservative reject. */\n readonly enabled?: boolean | undefined\n /** Provider is available in the host inventory. Unknown ⇒ conservative reject. */\n readonly providerEnabled?: boolean | undefined\n /** The requested variant exists for this model. Unknown ⇒ conservative reject. */\n readonly variantAvailable?: boolean | undefined\n readonly capabilities?:\n | {\n readonly tools?: boolean | undefined\n readonly input?: readonly string[] | undefined\n readonly output?: readonly string[] | undefined\n }\n | undefined\n readonly limit?: { readonly context?: number | undefined } | undefined\n}\n\n/**\n * Why a candidate failed the gate, in the fixed order the checks run:\n * availability → tools → input modalities → output modalities → context.\n */\nexport const INCOMPATIBILITY_REASONS = [\n \"provider-unavailable\",\n \"model-unavailable\",\n \"variant-unavailable\",\n \"tool-use-unsupported\",\n \"input-modality-unsupported\",\n \"output-modality-unsupported\",\n \"context-capacity-insufficient\",\n \"context-capacity-unknown\",\n] as const satisfies readonly string[]\n\nexport type IncompatibilityReason = (typeof INCOMPATIBILITY_REASONS)[number]\n\nexport interface Verdict {\n readonly compatible: boolean\n readonly reasons: readonly IncompatibilityReason[]\n}\n","/**\n * Circuit breaker types (ADP-019).\n *\n * The breaker is the quarantine mechanism for transient infrastructure\n * failures (outage, overload, timeout): repeated failures open the resource\n * for a backoff window, after which exactly one probe request is admitted\n * (half-open state). Rate limiting and quota exhaustion are deliberately\n * exempt from breaker counting because they already have their own windowed\n * resource states; counting them here would double-punish a resource that is\n * already known to need a cooldown.\n */\nimport type { FailureCategory } from \"../classifier/types.js\"\n\nexport const BREAKER_STATES = [\"closed\", \"open\", \"half_open\"] as const satisfies readonly string[]\n\nexport type BreakerState = (typeof BREAKER_STATES)[number]\n\nexport interface BreakerConfig {\n /** Consecutive countable failures in the closed state that trip the breaker. */\n readonly failureThreshold: number\n /** Backoff for the first opening; doubles on each reopening, capped below. */\n readonly baseOpenMs: number\n /** Upper bound for the backoff window. */\n readonly maxBackoffMs: number\n /**\n * How long a half-open probe may stay unreported before assessment treats\n * it as lost. Generous by design: a probe episode is a real work unit and\n * may run for minutes; the deadline only exists so a probe whose terminal\n * event never arrives cannot wedge the resource in half_open forever.\n */\n readonly probeTimeoutMs: number\n}\n\nexport const DEFAULT_BREAKER_CONFIG: BreakerConfig = {\n failureThreshold: 5,\n baseOpenMs: 30_000,\n maxBackoffMs: 1_800_000,\n probeTimeoutMs: 600_000,\n}\n\nexport const BREAKER_EXEMPT_CATEGORIES: readonly FailureCategory[] = [\n \"rate_limited\",\n \"quota_exhausted\",\n \"user_cancelled\",\n]\n\n/**\n * Persistent breaker record for one resource. `openCount` drives the doubling\n * backoff and resets only when the breaker closes (a probe or an observed\n * success). Rate limiting, quota exhaustion and user cancellation are\n * deliberately exempt from breaker counting: the first two own their own\n * windowed resource states (counting them would double-punish a resource\n * already known to need a cooldown), and a user-interrupted probe says\n * nothing about resource health, so an interrupted probe re-arms the same\n * window rather than doubling it. `probeId` identifies the single admitted\n * probe while half-open so stale or forged probe reports can be rejected;\n * `probeAt` records when it was admitted so a probe whose outcome report is\n * lost can expire instead of wedging the resource half-open forever.\n */\nexport interface BreakerRecord {\n readonly state: BreakerState\n readonly failures: number\n readonly openCount: number\n readonly reopenAt?: number | undefined\n readonly probeId?: string | undefined\n readonly probeAt?: number | undefined\n}\n","/**\n * Resource health types (ADP-007, ADP-012, ADP-021).\n *\n * A resource is identified at the narrowest scope the evidence supports:\n * provider → account → model → variant. Health states are a closed set and\n * every transition between them is defined by the pure transition layer; the\n * registry never invents states. The circuit breaker (ADP-019) is an\n * orthogonal axis stored per resource record.\n */\nimport {\n DEFAULT_BREAKER_CONFIG,\n type BreakerConfig,\n type BreakerRecord,\n} from \"../circuit-breaker/types.js\"\nimport type { FailureCategory } from \"../classifier/types.js\"\n\nexport const RESOURCE_SCOPES = [\n \"provider\",\n \"account\",\n \"model\",\n \"variant\",\n] as const satisfies readonly string[]\n\nexport type ResourceScope = (typeof RESOURCE_SCOPES)[number]\n\n/**\n * Hierarchical resource identity. The scope is derived from the most specific\n * field present, so callers attribute evidence at exactly the level they can\n * prove (e.g. a provider-wide outage without a model id stays at provider\n * scope; a per-variant failure quarantines only that variant).\n */\nexport interface ResourceKey {\n readonly providerID: string\n readonly accountID?: string | undefined\n readonly modelID?: string | undefined\n readonly variantID?: string | undefined\n}\n\nexport const HEALTH_STATES = [\n \"healthy\",\n \"draining\",\n \"degraded\",\n \"rate_limited\",\n \"quota_exhausted\",\n \"unavailable\",\n] as const satisfies readonly string[]\n\nexport type HealthState = (typeof HEALTH_STATES)[number]\n\n/**\n * A time-bounded window during which the current state is known to hold\n * (e.g. until a Retry-After delay or a quota reset elapses). Absent when no\n * reset time is known — recovery then relies on probes, observed successes,\n * or explicit resets.\n */\nexport interface ResourceWindow {\n readonly kind: \"rate-limit\" | \"quota\"\n readonly until: number\n}\n\nexport interface ResourceRecord {\n readonly key: ResourceKey\n readonly health: HealthState\n readonly breaker: BreakerRecord\n readonly window?: ResourceWindow | undefined\n readonly updatedAt: number\n}\n\n/**\n * Health evidence events. `failure` carries an already-classified category\n * (from the error classifier, ADP-009) plus the classification's\n * definitiveness and parsed retry delay. `capacity` carries a CapacitySensor\n * reading (ADP-020) — `exhausted: false` is positive evidence of capacity.\n * `reset` is the manual Control-mode recovery op.\n */\nexport type HealthEvent =\n | {\n readonly kind: \"failure\"\n readonly key: ResourceKey\n readonly category: FailureCategory\n readonly definitive: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"success\"; readonly key: ResourceKey }\n | { readonly kind: \"drain\"; readonly key: ResourceKey }\n | {\n readonly kind: \"capacity\"\n readonly key: ResourceKey\n readonly exhausted: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"reset\"; readonly key: ResourceKey }\n\nexport interface ResourceHealthConfig {\n readonly breaker: BreakerConfig\n /** Window applied to rate-limited evidence that carries no Retry-After. */\n readonly defaultRateLimitWindowMs: number\n /**\n * Window applied to quota exhaustion that carries no reset delay. Without\n * one the state would be permanent (it is persisted and rehydrated), so an\n * unknown reset re-admits the resource after this window and lets fresh\n * evidence re-mark it (ADP-012).\n */\n readonly defaultQuotaWindowMs: number\n}\n\nexport const DEFAULT_HEALTH_CONFIG: ResourceHealthConfig = {\n breaker: DEFAULT_BREAKER_CONFIG,\n defaultRateLimitWindowMs: 30_000,\n defaultQuotaWindowMs: 15 * 60_000,\n}\n\n/** Injected monotonic clock, milliseconds. */\nexport type Clock = () => number\n\n/**\n * Why an assessment blocks new work. Ordered from hardest to softest fact:\n * hard resource states (unavailable, quota, rate limit) are direct evidence;\n * breaker reasons are inferred from failure counts; draining is a policy\n * request, not a health fact.\n */\nexport const BLOCKED_REASONS = [\n \"unavailable\",\n \"quota-exhausted\",\n \"rate-limited\",\n \"breaker-open\",\n \"probe-in-flight\",\n \"draining\",\n] as const satisfies readonly string[]\n\nexport type BlockedReason = (typeof BLOCKED_REASONS)[number]\n\n/** Opaque single-probe admission token; validated on report. */\nexport interface ProbeTicket {\n readonly id: string\n readonly key: ResourceKey\n}\n\nexport type ProbeOutcome =\n { readonly success: true } | { readonly success: false; readonly category: FailureCategory }\n\n/**\n * Result of assessing whether a resource may take new work right now. The\n * `blocked` variant reports the winning blocker's key (which may be a wider\n * scope than the assessed key) and, when known, when the block can lift.\n */\nexport type Assessment =\n | { readonly kind: \"available\" }\n | { readonly kind: \"probe\"; readonly ticket: ProbeTicket }\n | {\n readonly kind: \"blocked\"\n readonly reason: BlockedReason\n readonly key: ResourceKey\n readonly retryAtMs?: number\n }\n","/**\n * Resource key helpers: scope derivation and canonical identity.\n */\nimport type { ResourceKey, ResourceScope } from \"./types.js\"\n\n/** The scope a key is attributed at: the most specific present field. */\nexport function resourceScope(key: ResourceKey): ResourceScope {\n if (key.variantID !== undefined) {\n return \"variant\"\n }\n if (key.modelID !== undefined) {\n return \"model\"\n }\n if (key.accountID !== undefined) {\n return \"account\"\n }\n return \"provider\"\n}\n\n/** Canonical string identity for map keys and receipts. */\nexport function resourceKeyID(key: ResourceKey): string {\n return JSON.stringify([\n key.providerID,\n key.accountID ?? null,\n key.modelID ?? null,\n key.variantID ?? null,\n ])\n}\n\n/**\n * The chain of scopes implied by `key`, ordered widest → narrowest. Each level\n * keeps the narrower fields that are present, so a key without an account\n * (OpenCode model references carry only provider and model) still yields a\n * model-level entry. Health assessment walks this chain because a blocked\n * ancestor blocks every descendant (e.g. a provider-wide rate limit skips all\n * of its models). A variant field without a model field is degenerate and\n * contributes no level of its own.\n */\nexport function resourceChain(key: ResourceKey): ResourceKey[] {\n const chain: ResourceKey[] = [{ providerID: key.providerID }]\n if (key.accountID !== undefined) {\n chain.push({ providerID: key.providerID, accountID: key.accountID })\n }\n if (key.modelID !== undefined) {\n chain.push(\n key.accountID === undefined\n ? { providerID: key.providerID, modelID: key.modelID }\n : { providerID: key.providerID, accountID: key.accountID, modelID: key.modelID },\n )\n }\n if (key.modelID !== undefined && key.variantID !== undefined) {\n chain.push(\n key.accountID === undefined\n ? { providerID: key.providerID, modelID: key.modelID, variantID: key.variantID }\n : {\n providerID: key.providerID,\n accountID: key.accountID,\n modelID: key.modelID,\n variantID: key.variantID,\n },\n )\n }\n return chain\n}\n","/**\n * Scheduler types (ADP-013/015/016/022): the pure decision core's vocabulary.\n *\n * The core is a total function over its inputs — routing outcome, demand,\n * inventory, per-candidate health and capacity views — and never performs\n * effects. Effects (switching, receipts, parking) belong to the execution\n * layer. OBSERVE and CONTROL call the same core; mode handling is a pure\n * wrapper (`forMode`).\n */\nimport type { ModelRef } from \"../work-unit/types.js\"\nimport type { RoutingDecision, TierName } from \"../tier-policy/types.js\"\nimport type { CandidateModel, Demand } from \"../compatibility/types.js\"\nimport type { Assessment } from \"../../health/resource-health/types.js\"\nimport type { CapacitySignals } from \"../../health/capacity/types.js\"\nimport { INCOMPATIBILITY_REASONS } from \"../compatibility/types.js\"\nimport { BLOCKED_REASONS } from \"../../health/resource-health/types.js\"\nimport { resourceKeyID } from \"../../health/resource-health/key.js\"\n\n/** Operating modes (GOAL manual control). The plugin defaults to `observe`. */\nexport const OPERATING_MODES = [\"off\", \"observe\", \"active\"] as const satisfies readonly string[]\n\nexport type OperatingMode = (typeof OPERATING_MODES)[number]\n\n/** Why an `apply` decision chose its model (receipt provenance). */\nexport const APPLY_REASONS = [\n \"pin\",\n \"preferred\",\n \"fallback\",\n \"probe\",\n \"draining\",\n] as const satisfies readonly string[]\n\nexport type ApplyReason = (typeof APPLY_REASONS)[number]\n\n/**\n * Why the core did not apply anything.\n * - `routing-defer` — the tier ladder deferred; OpenCode's choice stands.\n * - `pin-unverifiable` — the pinned model is not in the host inventory, so\n * availability cannot be verified (inventory gate); deferring keeps the\n * user's own model choice, which for a pin is typically the pinned model.\n * - `pin-incompatible` — the pinned model cannot execute the work.\n * - `escalation-*` — escalation evidence was absent, the budget was spent,\n * the tier ladder is at its ceiling, or the next tier has no resources\n * (no cross-tier borrowing).\n * - `adaptive-off` — the plugin is off; only reachable through `forMode`.\n */\nexport const SCHEDULER_DEFER_REASONS = [\n \"routing-defer\",\n \"pin-unverifiable\",\n \"pin-incompatible\",\n \"escalation-not-justified\",\n \"escalation-budget-exhausted\",\n \"escalation-ceiling\",\n \"escalation-no-candidate\",\n \"adaptive-off\",\n] as const satisfies readonly string[]\n\nexport type SchedulerDeferReason = (typeof SCHEDULER_DEFER_REASONS)[number]\n\n/**\n * Why work parks instead of applying: the required tier has no usable\n * resource right now. Parking waits for recovery — it never borrows across\n * tiers (ADP-022).\n */\nexport const PARK_REASONS = [\n \"pin-blocked\",\n \"no-candidates\",\n \"no-compatible-resource\",\n \"all-blocked\",\n] as const satisfies readonly string[]\n\nexport type ParkReason = (typeof PARK_REASONS)[number]\n\n/** Why a tier candidate was not usable. Superset of gate and health reasons. */\nexport const SKIP_REASONS = [\n \"not-in-inventory\",\n \"capacity-exhausted\",\n ...INCOMPATIBILITY_REASONS,\n ...BLOCKED_REASONS,\n] as const satisfies readonly string[]\n\nexport type SkipReason = (typeof SKIP_REASONS)[number]\n\n/** A tier candidate that could not take the work, with the bounded reason. */\nexport interface SkippedCandidate {\n readonly ref: ModelRef\n readonly why: SkipReason\n}\n\n/** Bounded evidence attached to an `apply` decision. */\nexport interface ApplyEvidence {\n /** Candidates considered before the applied one, in order (bounded). */\n readonly skipped: readonly SkippedCandidate[]\n /** Breaker probe id when the applied unit is the half-open probe. */\n readonly probeId?: string | undefined\n}\n\nexport interface ApplyDecision {\n readonly kind: \"apply\"\n readonly model: ModelRef\n /** Required tier; `undefined` for pin routing (a pin is not a tier). */\n readonly tier?: TierName | undefined\n readonly reason: ApplyReason\n readonly evidence: ApplyEvidence\n}\n\nexport interface DeferDecision {\n readonly kind: \"defer\"\n readonly reason: SchedulerDeferReason\n readonly detail?: string | undefined\n}\n\nexport interface ParkDecision {\n readonly kind: \"park\"\n readonly reason: ParkReason\n readonly detail?: string | undefined\n}\n\n/** Structured capability evidence for escalation (ADP-015). Never prose mining. */\nexport const ESCALATION_EVIDENCE_KINDS = [\n \"agent-request\",\n \"reviewer-rejection\",\n \"verification-failure\",\n \"repeated-failure\",\n \"explicit-blocker\",\n] as const satisfies readonly string[]\n\nexport type EscalationEvidenceKind = (typeof ESCALATION_EVIDENCE_KINDS)[number]\n\nexport interface EscalationEvidence {\n readonly kind: EscalationEvidenceKind\n readonly detail?: string | undefined\n}\n\n// Persisted receipt vocabulary. The planner produces only \"tier\" today; the\n// historical \"variant\" step stays parseable so old receipts are not dropped.\nexport const ESCALATION_STEPS = [\"variant\", \"tier\"] as const satisfies readonly string[]\n\nexport type EscalationStep = (typeof ESCALATION_STEPS)[number]\n\n/** Finite per-unit escalation budget (ADP-015). `used >= max` ends escalation. */\nexport interface EscalationBudget {\n readonly used: number\n readonly max: number\n}\n\n/** Bound on evidence carried by an `escalate` decision (latest wins). */\nexport const MAX_ESCALATION_EVIDENCE = 4\n\nexport interface EscalationInput {\n readonly currentModel: ModelRef\n readonly currentTier: TierName\n /** Configured resources of the next tier, user order, already gated. */\n readonly nextTierResources: readonly ModelRef[]\n /** Non-empty structured evidence justifies escalation. */\n readonly evidence: readonly EscalationEvidence[]\n readonly budget: EscalationBudget\n}\n\nexport interface EscalateDecision {\n readonly kind: \"escalate\"\n readonly target: ModelRef\n readonly step: EscalationStep\n /** Tier of the escalated-to resource (the next tier). */\n readonly tier: TierName\n readonly evidence: readonly EscalationEvidence[]\n readonly budgetRemaining: number\n}\n\n/** OBSERVE mode's wrapper: the identical decision, recorded but not applied. */\nexport interface ObserveOnlyDecision {\n readonly kind: \"observe-only\"\n readonly would: Decision\n}\n\nexport type Decision =\n ApplyDecision | DeferDecision | ParkDecision | EscalateDecision | ObserveOnlyDecision\n\n/** What admission can return — escalation never originates from admission. */\nexport type AdmissionDecision = ApplyDecision | DeferDecision | ParkDecision\n\n/**\n * Everything admission looks at. `health` and `capacity` are keyed by\n * `schedulerHealthKey(ref)`; an absent health entry means \"no observed\n * failure\" (the registry's default), an absent capacity entry means \"no\n * estimate\" — unknown is never treated as exhausted.\n */\nexport interface SchedulerInput {\n readonly routing: RoutingDecision\n readonly demand: Demand\n /** Host inventory (adapter-normalized). Candidates absent here are unverifiable. */\n readonly inventory: readonly CandidateModel[]\n /** Configured resources of the required tier, in user order (ADP-005). */\n readonly tierCandidates: readonly ModelRef[]\n readonly health: Readonly<Record<string, Assessment>>\n readonly capacity: Readonly<Record<string, CapacitySignals>>\n}\n\n/** Bound on the `skipped` evidence list of an `apply` decision. */\nexport const MAX_EVIDENCE_SKIPPED = 8\n\n/** Canonical health/capacity map key for a candidate model reference. */\nexport function schedulerHealthKey(ref: ModelRef): string {\n return resourceKeyID(\n ref.variant === undefined\n ? { providerID: ref.providerID, modelID: ref.id }\n : { providerID: ref.providerID, modelID: ref.id, variantID: ref.variant },\n )\n}\n","/**\n * Work-unit model (ADP-001): one unit is exactly one OpenCode execution\n * episode — `session.execution.started` → `succeeded`/`failed`/`interrupted`.\n * Tool/step/text continuations never open, close, or split a unit (only the\n * execution events do); a subagent runs in its own session and therefore gets\n * its own units; a later continuation on the same session (e.g. a new /goal\n * round) is a new episode of that session.\n */\nimport type { InterruptReason } from \"./interruption.js\"\n\n/** OpenCode model reference (`Model.Ref`): provider, model, optional variant. */\nexport interface ModelRef {\n readonly providerID: string\n readonly id: string\n readonly variant?: string | undefined\n}\n\n/** Full-field equality; a variant change is a different reference. */\nexport function sameModelRef(a: ModelRef, b: ModelRef): boolean {\n return a.providerID === b.providerID && a.id === b.id && a.variant === b.variant\n}\n\n/**\n * How the model in effect became known. `selected-*` comes from the\n * `session.model.selected` event (which fires for both manual and\n * plugin-made switches — the tracker resolves which via pending own-switch\n * notes, see `WorkUnitTracker.noteOwnSwitch`); `request` comes from the\n * `context` hook and reports the model actually executing.\n */\nexport const MODEL_SOURCES = [\n \"selected-adaptive\",\n \"selected-external\",\n \"request\",\n] as const satisfies readonly string[]\n\nexport type ModelSource = (typeof MODEL_SOURCES)[number]\n\nexport interface ModelTransition {\n readonly at: number\n readonly model: ModelRef\n readonly source: ModelSource\n}\n\n/**\n * Minimal shape of the wire `Session.StructuredError` carried by\n * `session.execution.failed` (`response.body` is deliberately dropped here —\n * the adapter folds it into bounded `ErrorEvidence` for the classifier).\n */\nexport interface ExecutionError {\n readonly type: string\n readonly message: string\n readonly status?: number | undefined\n readonly retryAfterMs?: number | undefined\n}\n\n/**\n * The episode lifecycle. `kind` doubles as status: `\"active\"` while the\n * execution runs, then the terminal kind it closed with.\n */\ninterface UnitBase {\n /** Stable per-episode identifier: `${sessionID}#${episode}`. */\n readonly id: string\n readonly sessionID: string\n /** 1-based count of episodes started for this session (tracker lifetime). */\n readonly episode: number\n readonly startedAt: number\n /**\n * Model in effect for the unit: seeded from the last known selection when\n * the unit opens, then updated by transitions.\n */\n readonly model?: ModelRef | undefined\n readonly transitions: readonly ModelTransition[]\n}\n\nexport interface ActiveUnit extends UnitBase {\n readonly kind: \"active\"\n}\n\nexport interface SucceededUnit extends UnitBase {\n readonly kind: \"succeeded\"\n readonly closedAt: number\n}\n\nexport interface FailedUnit extends UnitBase {\n readonly kind: \"failed\"\n readonly closedAt: number\n readonly error: ExecutionError\n}\n\nexport interface InterruptedUnit extends UnitBase {\n readonly kind: \"interrupted\"\n readonly closedAt: number\n readonly reason: InterruptReason\n}\n\nexport type ClosedUnit = SucceededUnit | FailedUnit | InterruptedUnit\n\nexport type WorkUnit = ActiveUnit | ClosedUnit\n\n/**\n * Normalized episode events. The OpenCode adapter unwraps host event payloads\n * (`event.data.*`) and forwards them here; `model-request` is fed from the\n * `context` session hook.\n */\nexport type WorkUnitEvent =\n | { readonly kind: \"execution-started\"; readonly sessionID: string; readonly at: number }\n | { readonly kind: \"execution-succeeded\"; readonly sessionID: string; readonly at: number }\n | {\n readonly kind: \"execution-failed\"\n readonly sessionID: string\n readonly at: number\n readonly error: ExecutionError\n }\n | {\n readonly kind: \"execution-interrupted\"\n readonly sessionID: string\n readonly at: number\n readonly reason: InterruptReason\n }\n | {\n readonly kind: \"model-selected\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n | {\n readonly kind: \"model-request\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n\n/**\n * Why an event produced no state change. Only terminal events can be ignored\n * — they arrive without an active unit when the terminal was already handled\n * (duplicate delivery) or never preceded by `execution-started`.\n */\nexport const IGNORED_REASONS = [\"terminal-without-active-unit\"] as const satisfies readonly string[]\n\nexport type IgnoredReason = (typeof IGNORED_REASONS)[number]\n\n/** Result of an execution-started event: the tracker always opens (possibly superseding). */\nexport type OpenedResult = Extract<ApplyResult, { kind: \"opened\" }>\n\n/** Result of a selection event: the tracker always records model knowledge. */\nexport type SelectionResult = Extract<\n ApplyResult,\n { kind: \"model-noted\" } | { kind: \"model-tracked\" }\n>\n\nexport type ApplyResult =\n | {\n readonly kind: \"opened\"\n readonly unit: ActiveUnit\n readonly superseded?: ClosedUnit | undefined\n }\n | { readonly kind: \"closed\"; readonly unit: ClosedUnit }\n | {\n readonly kind: \"model-tracked\"\n readonly unit: ActiveUnit\n readonly transition: ModelTransition\n }\n /** Model knowledge recorded with no active unit; remembered for the next admission. */\n | { readonly kind: \"model-noted\"; readonly transition: ModelTransition }\n | { readonly kind: \"ignored\"; readonly reason: IgnoredReason }\n","/**\n * User-configured tier lists (ADP-005): each tier is an ordered list of\n * resources; list order is user policy and is never reordered by Adaptive.\n * Normalization only removes unusable entries and exact duplicates — it\n * never reorders and never merges look-alike names (ADP-006: similar model\n * names across providers are never equivalent unless the user configures\n * both, and full-reference equality below is deliberately provider-scoped).\n */\nimport { sameModelRef, type ModelRef } from \"../work-unit/types.js\"\n\nexport function normalizeTierList(resources: readonly ModelRef[]): ModelRef[] {\n const kept: ModelRef[] = []\n for (const resource of resources) {\n if (resource.providerID.length === 0 || resource.id.length === 0) {\n continue\n }\n if (kept.some((existing) => sameModelRef(existing, resource))) {\n continue\n }\n kept.push(resource)\n }\n return kept\n}\n","/**\n * Tier-policy types (ADP-002..006). Tier names are an ecosystem proposal —\n * OpenCode has no native capability-tier API — so every tier semantic lives\n * in this module and nowhere else.\n */\nimport type { ModelRef } from \"../work-unit/types.js\"\n\nexport const TIERS = [\"quick\", \"standard\", \"advanced\"] as const satisfies readonly string[]\n\nexport type TierName = (typeof TIERS)[number]\n\n/** Vocabulary guard without a cast: strict member equality. */\nexport function isTierName(tier: string): tier is TierName {\n return TIERS.some((name) => name === tier)\n}\n\n/**\n * Request kinds the OpenCode `context` hook exposes for the executing\n * request. Auxiliary kinds are trivial host-internal requests (title,\n * compaction, generate) that must not consume an unnecessarily expensive\n * tier — this is structured host evidence, not prompt keyword matching\n * (ADP-004).\n */\nexport const AUXILIARY_KINDS = [\n \"compaction\",\n \"title\",\n \"generate\",\n] as const satisfies readonly string[]\n\nexport type AuxiliaryKind = (typeof AUXILIARY_KINDS)[number]\n\nexport type RequestKind = \"primary\" | AuxiliaryKind\n\n/** Auxiliary requests route to `quick`. */\nexport const AUXILIARY_TIER: TierName = \"quick\"\n\n/** Unambiguous fallback tier (ADP-002). */\nexport const DEFAULT_TIER: TierName = \"standard\"\n\n/** How an explicit tier request reached the plugin (provenance for receipts). */\nexport const TIER_REQUEST_VIAS = [\n \"manual-command\",\n \"session-setting\",\n] as const satisfies readonly string[]\n\nexport type TierRequestVia = (typeof TIER_REQUEST_VIAS)[number]\n\nexport interface TierRequest {\n readonly tier: TierName\n readonly via: TierRequestVia\n}\n\n/**\n * Everything the ladder may look at, all optional except the configuration\n * view. Every signal is a structured field supplied by the adapter — never\n * text mined from a prompt.\n */\nexport interface RoutingInput {\n /** Explicit user/model pin (manual control); always wins (ADP-002). */\n readonly pin?: ModelRef | undefined\n /** Explicit tier request (manual command or session setting). */\n readonly tierRequest?: TierRequest | undefined\n /** OpenCode agent name of the executing request, when the host supplies one. */\n readonly agent?: string | undefined\n /** Request kind from the `context` hook, when known. */\n readonly requestKind?: RequestKind | undefined\n /** User-configured agent-name → tier mapping (role hints are user policy). */\n readonly agentTiers?: Readonly<Record<string, TierName>> | undefined\n /**\n * Tiers that currently have at least one configured resource (ADP-005).\n * A tier without resources can never be honored — Adaptive does not\n * invent resources and never borrows across tiers (GOAL tenet 4).\n */\n readonly configuredTiers: readonly TierName[]\n}\n\n/** Why the ladder produced a tier decision (receipt provenance). */\nexport const ROUTING_SOURCES = [\n \"pin\",\n \"tier-request\",\n \"agent-role\",\n \"auxiliary-request\",\n \"ambiguity\",\n \"default\",\n] as const satisfies readonly string[]\n\nexport type RoutingSource = (typeof ROUTING_SOURCES)[number]\n\nexport const DEFER_REASONS = [\"tier-not-configured\"] as const satisfies readonly string[]\n\nexport type DeferReason = (typeof DEFER_REASONS)[number]\n\n/**\n * Routing outcome (ADP-002/003):\n * - `pin` — route to the pinned resource.\n * - `tier` — route within the named tier.\n * - `defer` — Adaptive has no reason to override ordinary OpenCode behavior;\n * the unit keeps OpenCode's model choice. `tier` records which tier the\n * ladder resolved to before the configuration gate blocked it.\n */\nexport type RoutingDecision =\n | { readonly kind: \"pin\"; readonly model: ModelRef }\n | { readonly kind: \"tier\"; readonly tier: TierName; readonly source: RoutingSource }\n | { readonly kind: \"defer\"; readonly tier: TierName; readonly reason: DeferReason }\n\n/** True only for the trivial auxiliary request kinds. */\nexport function isAuxiliary(kind: RequestKind): boolean {\n return kind !== \"primary\"\n}\n\n/**\n * Escalation ladder order (GOAL capability escalation): `quick` → `standard`\n * → `advanced`. `advanced` is the last tier — there is no next.\n */\nexport function nextTier(tier: TierName): TierName | undefined {\n const index = TIERS.indexOf(tier)\n return TIERS[index + 1]\n}\n","/**\n * Bounded shape validation and migration-on-read (ADP-036). Every parser is\n * total: it accepts `unknown` and either returns a typed value or `undefined`\n * — the read path always falls back to a default rather than throwing, so a\n * corrupted record can never take the plugin (or the host) down (ADP-031).\n *\n * Plain objects are never indexed with untrusted strings beyond own-property\n * checks (`Object.hasOwn`) — prototype-chain keys like \"toString\" must not be\n * mistaken for data (project-wide audit rule).\n */\nimport { OPERATING_MODES } from \"../../routing/scheduler/types.js\"\nimport type { OperatingMode } from \"../../routing/scheduler/types.js\"\nimport { normalizeTierList } from \"../../routing/tier-policy/tier-list.js\"\nimport { TIERS } from \"../../routing/tier-policy/types.js\"\nimport type { TierName } from \"../../routing/tier-policy/types.js\"\nimport type { ModelRef } from \"../../routing/work-unit/types.js\"\nimport { MAX_AGENT_TIERS, MAX_TIER_RESOURCES, SETTINGS_VERSION } from \"./types.js\"\nimport type { SettingsV1 } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/** One field's patch-path parse outcome: a validated value or a field error. */\ntype FieldParse<T> = { ok: true; value: T } | { ok: false; error: string }\n\n/**\n * Quoted, bounded rendering of an untrusted patch value inside an error\n * message (errors travel to surfaces over RPC; JSON.stringify is only ever\n * called on strings here, so a cyclic object cannot make applyPatch throw).\n */\nfunction describePatchValue(value: unknown): string {\n if (typeof value === \"string\") {\n const quoted = JSON.stringify(value)\n return quoted.length > 64 ? `${quoted.slice(0, 64)}…` : quoted\n }\n if (value === null) return \"null\"\n if (typeof value === \"object\") return \"object\"\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value)\n return typeof value\n}\n\nexport function parseMode(raw: unknown): OperatingMode | undefined {\n if (typeof raw !== \"string\") return undefined\n return OPERATING_MODES.find((mode) => mode === raw)\n}\n\n/**\n * Legacy persisted value: v1 settings written before the `control → active`\n * rename store `mode: \"control\"`. Migration-on-read maps it; patches stay\n * strict (wire input must use the current vocabulary).\n */\nfunction parseLegacyMode(raw: unknown): OperatingMode | undefined {\n return raw === \"control\" ? \"active\" : parseMode(raw)\n}\n\nexport function parseTierLists(\n raw: unknown,\n): Readonly<Record<TierName, readonly ModelRef[]>> | undefined {\n if (!isRecord(raw)) return undefined\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n tiers[tier] = normalizeTierListValue(raw[tier])\n }\n return tiers\n}\n\n/** Shared per-tier normalization (drop invalid, dedupe, cap) for both paths. */\nfunction normalizeTierListValue(list: unknown): readonly ModelRef[] {\n return Array.isArray(list)\n ? normalizeTierList(\n list.map(parseModelRef).filter((ref): ref is ModelRef => ref !== undefined),\n ).slice(0, MAX_TIER_RESOURCES)\n : []\n}\n\nexport function parseModelRef(raw: unknown): ModelRef | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = raw[\"providerID\"]\n const id = raw[\"id\"]\n const variant = raw[\"variant\"]\n if (typeof providerID !== \"string\" || providerID === \"\") return undefined\n if (typeof id !== \"string\" || id === \"\") return undefined\n return {\n providerID,\n id,\n ...(typeof variant === \"string\" && variant !== \"\" ? { variant } : {}),\n }\n}\n\nexport function parsePin(raw: unknown): ModelRef | null | undefined {\n if (raw === null) return null\n return parseModelRef(raw)\n}\n\nexport function parseAgentTiers(raw: unknown): Readonly<Record<string, TierName>> | undefined {\n if (!isRecord(raw)) return undefined\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (agent === \"\") continue\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) continue\n entries.push([agent, parsed])\n if (entries.length === MAX_AGENT_TIERS) break\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return Object.fromEntries(entries)\n}\n\nfunction parseModelessTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\n/**\n * Patch-path tier-list validation. Unlike the read path (which fills missing\n * or unusable tiers with `[]`), a patch that names `tiers` REPLACES the whole\n * map — silently filling an omitted key with `[]` would wipe that tier's\n * configured resources, so every key must be present and array-typed. List\n * contents still go through the shared normalization (drop invalid, dedupe,\n * cap), which is repair of user-typed entries rather than data loss.\n */\nfunction parseTierListsPatch(\n raw: unknown,\n): FieldParse<Readonly<Record<TierName, readonly ModelRef[]>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid tiers\" }\n const missing = TIERS.filter((tier) => raw[tier] === undefined)\n if (missing.length > 0) {\n const named = missing.map((tier) => JSON.stringify(tier)).join(\", \")\n return { ok: false, error: `invalid tiers: missing ${named}` }\n }\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n const list = raw[tier]\n if (!Array.isArray(list)) {\n return { ok: false, error: `invalid tiers: ${JSON.stringify(tier)} must be an array` }\n }\n tiers[tier] = normalizeTierListValue(list)\n }\n return { ok: true, value: tiers }\n}\n\n/**\n * Patch-path agent-tier validation. Unlike the read path (which drops invalid\n * entries as migration-on-read repair), a patch REPLACES the whole map —\n * silently dropping entries would let a single typo wipe the persisted hints,\n * so any invalid entry (and an over-cap patch) is rejected with an error that\n * names the offending field and value.\n */\nfunction parseAgentTiersPatch(raw: unknown): FieldParse<Readonly<Record<string, TierName>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid agentTiers\" }\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (entries.length === MAX_AGENT_TIERS) {\n return {\n ok: false,\n error: `invalid agentTiers: more than ${String(MAX_AGENT_TIERS)} entries`,\n }\n }\n if (agent === \"\") return { ok: false, error: \"invalid agentTiers: empty agent name\" }\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) {\n return {\n ok: false,\n error: `invalid agentTiers entry ${describePatchValue(agent)}: ${describePatchValue(tier)}`,\n }\n }\n entries.push([agent, parsed])\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return { ok: true, value: Object.fromEntries(entries) }\n}\n\n/** Settings with nothing configured: OBSERVE, empty tiers, no pin (ADP-029/032). */\nexport function defaultSettings(): SettingsV1 {\n return {\n version: SETTINGS_VERSION,\n mode: \"observe\",\n tiers: { quick: [], standard: [], advanced: [] },\n pin: null,\n agentTiers: {},\n inviteDismissed: false,\n }\n}\n\n/**\n * Migration-on-read. `undefined`/absent record → defaults (first install);\n * versionless (v0 draft) and v1 records are validated field-wise with\n * defaults for unusable fields; a record written by a NEWER version is\n * returned as defaults rather than guessed at (and is only re-persisted once\n * the user changes something, which stamps the current version).\n */\nexport function migrateSettings(raw: unknown): SettingsV1 {\n if (!isRecord(raw)) return defaultSettings()\n const version = raw[\"version\"]\n if (version !== SETTINGS_VERSION && version !== 0 && version !== undefined) {\n return defaultSettings()\n }\n return fieldsFrom(raw)\n}\n\nfunction fieldsFrom(raw: Record<string, unknown>): SettingsV1 {\n const mode = parseLegacyMode(raw[\"mode\"]) ?? \"observe\"\n const tiers = parseTierLists(raw[\"tiers\"]) ?? defaultSettings().tiers\n const pin = parsePin(raw[\"pin\"]) ?? null\n const agentTiers = parseAgentTiers(raw[\"agentTiers\"]) ?? {}\n const inviteDismissed = raw[\"inviteDismissed\"] === true\n return { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed }\n}\n\n/**\n * Validate a patch against current settings. The patch is WIRE input (unknown\n * by contract — surfaces send untrusted JSON over RPC; the SettingsPatch type\n * documents the expected shape, the field parsers enforce it). Invalid fields\n * collect error strings (at most one per field, five fields); a valid patch\n * produces a NEW settings object (inputs are never mutated).\n */\nexport function applyPatch(\n current: SettingsV1,\n patch: unknown,\n): { ok: true; settings: SettingsV1 } | { ok: false; errors: string[] } {\n if (!isRecord(patch)) return { ok: false, errors: [\"invalid patch\"] }\n const request = patch as {\n mode?: unknown\n tiers?: unknown\n pin?: unknown\n agentTiers?: unknown\n inviteDismissed?: unknown\n }\n const errors: string[] = []\n let mode = current.mode\n let tiers = current.tiers\n let pin = current.pin\n let agentTiers = current.agentTiers\n let inviteDismissed = current.inviteDismissed\n\n if (request.mode !== undefined) {\n const parsed = parseMode(request.mode)\n if (parsed === undefined) errors.push(\"invalid mode\")\n else mode = parsed\n }\n if (request.tiers !== undefined) {\n const parsed = parseTierListsPatch(request.tiers)\n if (parsed.ok) tiers = parsed.value\n else errors.push(parsed.error)\n }\n // `pin === null` is a meaningful clear and must not read as absence.\n if (request.pin !== undefined) {\n const parsed = parsePin(request.pin)\n if (parsed === undefined) errors.push(\"invalid pin\")\n else pin = parsed\n }\n if (request.agentTiers !== undefined) {\n const parsed = parseAgentTiersPatch(request.agentTiers)\n if (parsed.ok) agentTiers = parsed.value\n else errors.push(parsed.error)\n }\n if (request.inviteDismissed !== undefined) {\n if (typeof request.inviteDismissed !== \"boolean\") errors.push(\"invalid inviteDismissed\")\n else inviteDismissed = request.inviteDismissed\n }\n\n if (errors.length > 0) return { ok: false, errors }\n return {\n ok: true,\n settings: { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed },\n }\n}\n","/**\n * Continuation prompt for owned recovery and parked-work resume (ADP-023).\n * Continues from session state; never replays the original instruction once\n * tool side effects may exist. The executor sends exactly this prompt — the\n * never-replay invariant is structural, not a caller responsibility.\n */\nexport const CONTINUATION_PROMPT =\n \"Continue the interrupted work from the current session state. Do not repeat completed work; resume from what the session already produced.\"\n","/**\n * The Adaptive-owned escalation request surface (T-18, ADP-015..017). The\n * schema requires a reason and evidence — it is deliberately the smallest\n * typed mechanism for an agent to request stronger capability, and it is not\n * a planning or task-management API. The request is recorded against the\n * current work unit and applies at the next safe boundary within the finite\n * per-unit budget; a completing unit discards it (routing re-runs fresh).\n */\nimport type { FailureCategory } from \"../../health/classifier/types.js\"\n\n/** The tool name as registered with the host. */\nexport const ESCALATION_TOOL_NAME = \"adaptive_escalate\"\n\n/** Each field is bounded — the request never carries unbounded prose. */\nexport const MAX_ESCALATION_FIELD_LENGTH = 256\n\nexport interface EscalationRequest {\n readonly reason: string\n readonly evidence: string\n}\n\n/**\n * Truncates to `max` UTF-16 code units without splitting a surrogate pair:\n * a trailing high surrogate whose low half was cut is dropped, so the\n * persisted evidence never carries a lone surrogate.\n */\nexport function truncateBounded(text: string, max: number): string {\n if (text.length <= max) return text\n const cut = text.slice(0, max)\n const last = cut.charCodeAt(cut.length - 1)\n return last >= 0xd800 && last <= 0xdbff ? cut.slice(0, -1) : cut\n}\n\n/**\n * Total parser for the tool input (the host forwards model-produced JSON, so\n * the runtime shape is untrusted even though the standard schema describes\n * it). Both fields are required, non-empty, and bounded.\n */\nexport function parseEscalationRequest(input: unknown): EscalationRequest | undefined {\n if (typeof input !== \"object\" || input === null) return undefined\n const record = input as Record<string, unknown>\n const reason = record[\"reason\"]\n const evidence = record[\"evidence\"]\n if (typeof reason !== \"string\" || reason.length === 0) return undefined\n if (typeof evidence !== \"string\" || evidence.length === 0) return undefined\n return {\n reason: truncateBounded(reason, MAX_ESCALATION_FIELD_LENGTH),\n evidence: truncateBounded(evidence, MAX_ESCALATION_FIELD_LENGTH),\n }\n}\n\n/** One-line summary recorded as escalation evidence (bounded). */\nexport function escalationDetail(request: EscalationRequest): string {\n return truncateBounded(`${request.reason}: ${request.evidence}`, MAX_ESCALATION_FIELD_LENGTH)\n}\n\n/**\n * Failure categories that count as structured capability evidence (ADP-015).\n * The remaining evidence kinds (agent request, reviewer rejection) have no\n * structured host source and are never inferred from free text.\n */\nexport const CAPABILITY_FAILURE_CATEGORIES: readonly FailureCategory[] = [\n \"context_overflow\",\n \"content_policy\",\n]\n\n/** Finite per-task escalation budget (ADP-017). */\nexport const MAX_ESCALATIONS_PER_TASK = 2\n","/**\n * Fail-open logging (ADP-031). The supervisor never throws from its public\n * entry points; unexpected failures are logged with a bounded scope line and\n * swallowed. Logging is the degradation path, not a channel for secrets —\n * only the error's string form, bounded, is emitted.\n */\n\n/** Bound for the logged error text (bounded diagnostics, ADP-030 spirit). */\nexport const LOG_ERROR_LENGTH = 200\n\n/** Log one swallowed internal failure under the plugin's namespace. */\nexport function logFailOpen(scope: string, error: unknown): void {\n const detail = String(error).slice(0, LOG_ERROR_LENGTH)\n console.error(`[coool.adaptive] ${scope}: ${detail}`)\n}\n","import { defaultSettings, migrateSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport {\n MAX_AGENT_TIERS,\n MAX_TIER_RESOURCES,\n type SettingsV1,\n type PatchResult,\n} from \"@coool/adaptive-core/state/settings/types\"\nimport { isTierName, TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport function object(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction invalid(field: string): never {\n throw new Error(`Adaptive settings: invalid ${field}`)\n}\n\nfunction reference(value: unknown, field: string): void {\n if (\n !object(value) ||\n Object.keys(value).some((key) => ![\"providerID\", \"id\", \"variant\"].includes(key))\n )\n invalid(field)\n for (const key of [\"providerID\", \"id\"]) {\n const id = value[key]\n if (typeof id !== \"string\" || id.trim() === \"\" || id.length > 128) invalid(field)\n }\n const variant = value[\"variant\"]\n if (\n variant !== undefined &&\n (typeof variant !== \"string\" || variant.trim() === \"\" || variant.length > 128)\n )\n invalid(field)\n}\n\n/** Validate before using core's forgiving migration/normalization on durable data. */\nfunction validate(raw: Record<string, unknown>, reading: boolean): void {\n if (\n Object.keys(raw).some(\n (key) => ![\"version\", \"mode\", \"tiers\", \"pin\", \"agentTiers\", \"inviteDismissed\"].includes(key),\n )\n )\n invalid(\"field\")\n const version = raw[\"version\"]\n if (version !== undefined && version !== 1 && !(reading && version === 0)) invalid(\"version\")\n const mode = raw[\"mode\"]\n if (\n mode !== undefined &&\n !(typeof mode === \"string\" && [\"off\", \"observe\", \"active\"].includes(mode)) &&\n !(reading && mode === \"control\")\n )\n invalid(\"mode\")\n if (raw[\"pin\"] !== undefined && raw[\"pin\"] !== null) reference(raw[\"pin\"], \"pin\")\n if (raw[\"inviteDismissed\"] !== undefined && typeof raw[\"inviteDismissed\"] !== \"boolean\")\n invalid(\"inviteDismissed\")\n const tiers = raw[\"tiers\"]\n if (tiers !== undefined) {\n if (!object(tiers) || Object.keys(tiers).some((key) => !isTierName(key))) invalid(\"tiers\")\n for (const tier of TIERS) {\n const list: unknown = tiers[tier]\n if (!Array.isArray(list) || list.length > MAX_TIER_RESOURCES) invalid(`tiers.${tier}`)\n const seen = new Set<string>()\n for (const entry of list) {\n reference(entry, `tiers.${tier}`)\n const key = JSON.stringify(entry, [\"providerID\", \"id\", \"variant\"])\n if (seen.has(key)) invalid(`tiers.${tier}`)\n seen.add(key)\n }\n }\n }\n const agents = raw[\"agentTiers\"]\n if (agents !== undefined) {\n if (!object(agents) || Object.keys(agents).length > MAX_AGENT_TIERS) invalid(\"agentTiers\")\n for (const [agent, tier] of Object.entries(agents))\n if (agent.trim() === \"\" || typeof tier !== \"string\" || !isTierName(tier))\n invalid(\"agentTiers\")\n }\n}\n\nexport function parseSettings(raw: unknown): SettingsV1 {\n if (raw === undefined) return defaultSettings()\n if (!object(raw)) invalid(\"record\")\n validate(raw, true)\n return migrateSettings(raw)\n}\n\nexport async function readSettings(file: Pick<JsonFile, \"read\">): Promise<SettingsV1> {\n return parseSettings(await file.read())\n}\n\nexport function updateSettings(file: JsonFile, patch: unknown): Promise<PatchResult> {\n return file.update<PatchResult>((raw) => {\n const current = parseSettings(raw)\n try {\n if (!object(patch)) invalid(\"patch\")\n validate(patch, false)\n } catch (error) {\n return {\n next: undefined,\n result: { ok: false, errors: [String(error).replace(\"Error: Adaptive settings: \", \"\")] },\n }\n }\n const settings = migrateSettings({ ...current, ...patch, version: 1 })\n return { next: settings, result: { ok: true, settings } }\n })\n}\n","import type { JsonFile } from \"./store.js\"\nimport { object } from \"./settings.js\"\n\nexport const NOTE_VERBOSITIES = [\"quiet\", \"changes\", \"all\"] as const\nexport type NoteVerbosity = (typeof NOTE_VERBOSITIES)[number]\nexport interface PiPreferences {\n readonly version: 1\n readonly verbosity: NoteVerbosity\n readonly escalateFromPinned: boolean\n}\n\nfunction fields(raw: unknown): Partial<PiPreferences> {\n if (!object(raw)) throw new Error(\"Adaptive preferences: expected an object\")\n if (Object.keys(raw).some((key) => ![\"version\", \"verbosity\", \"escalateFromPinned\"].includes(key)))\n throw new Error(\"Adaptive preferences: unknown field\")\n if (raw[\"version\"] !== undefined && raw[\"version\"] !== 1)\n throw new Error(\"Adaptive preferences.version: expected 1\")\n const verbosity = NOTE_VERBOSITIES.find((value) => value === raw[\"verbosity\"])\n if (raw[\"verbosity\"] !== undefined && verbosity === undefined)\n throw new Error(\"Adaptive preferences.verbosity: expected quiet, changes, or all\")\n const escalate = raw[\"escalateFromPinned\"]\n if (escalate !== undefined && typeof escalate !== \"boolean\")\n throw new Error(\"Adaptive preferences.escalateFromPinned: expected a boolean\")\n return {\n ...(verbosity === undefined ? {} : { verbosity }),\n ...(typeof escalate === \"boolean\" ? { escalateFromPinned: escalate } : {}),\n }\n}\n\nexport function parsePreferences(raw: unknown): PiPreferences {\n return {\n version: 1,\n verbosity: \"changes\",\n escalateFromPinned: false,\n ...(raw === undefined ? {} : fields(raw)),\n }\n}\n\nexport async function readPreferences(file: Pick<JsonFile, \"read\">): Promise<PiPreferences> {\n return parsePreferences(await file.read())\n}\n\nexport function updatePreferences(file: JsonFile, patch: unknown): Promise<PiPreferences> {\n return file.update((raw) => {\n const next = { ...parsePreferences(raw), ...fields(patch) }\n return { next, result: next }\n })\n}\n","/**\n * Bounding for receipts (ADP-030). Receipts are built from typed scheduler\n * decisions, but every string they can carry is truncated to\n * `MAX_RECEIPT_TEXT` before persisting — including identifiers. Boundedness\n * is what makes the no-secrets invariant checkable: no field accepts\n * unbounded text, so nothing unbounded can be persisted.\n */\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n ObserveOnlyDecision,\n ParkDecision,\n} from \"../../routing/scheduler/types.js\"\nimport type { ModelRef } from \"../../routing/work-unit/types.js\"\nimport { MAX_RECEIPT_TEXT } from \"./types.js\"\n\nexport function boundText(raw: string): string {\n return raw.length > MAX_RECEIPT_TEXT ? raw.slice(0, MAX_RECEIPT_TEXT) : raw\n}\n\nfunction boundRef(ref: ModelRef): ModelRef {\n return {\n providerID: boundText(ref.providerID),\n id: boundText(ref.id),\n ...(ref.variant !== undefined ? { variant: boundText(ref.variant) } : {}),\n }\n}\n\nfunction boundApply(decision: ApplyDecision): ApplyDecision {\n return {\n kind: \"apply\",\n model: boundRef(decision.model),\n ...(decision.tier !== undefined ? { tier: decision.tier } : {}),\n reason: decision.reason,\n evidence: {\n skipped: decision.evidence.skipped.map((skip) => ({\n ref: boundRef(skip.ref),\n why: skip.why,\n })),\n ...(decision.evidence.probeId !== undefined\n ? { probeId: boundText(decision.evidence.probeId) }\n : {}),\n },\n }\n}\n\nfunction boundDefer(decision: DeferDecision): DeferDecision {\n return {\n kind: \"defer\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundPark(decision: ParkDecision): ParkDecision {\n return {\n kind: \"park\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundEscalate(decision: EscalateDecision): EscalateDecision {\n return {\n kind: \"escalate\",\n target: boundRef(decision.target),\n step: decision.step,\n tier: decision.tier,\n evidence: decision.evidence.map((item) => ({\n kind: item.kind,\n ...(item.detail !== undefined ? { detail: boundText(item.detail) } : {}),\n })),\n budgetRemaining: decision.budgetRemaining,\n }\n}\n\nfunction boundObserveOnly(decision: ObserveOnlyDecision, depth: number): ObserveOnlyDecision {\n return { kind: \"observe-only\", would: boundDecision(decision.would, depth + 1) }\n}\n\n/**\n * Structural copy of a decision with every string bounded. `depth` guards\n * the `observe-only` recursion (max one nesting level is ever produced).\n */\nexport function boundDecision(decision: Decision, depth = 0): Decision {\n switch (decision.kind) {\n case \"apply\":\n return boundApply(decision)\n case \"defer\":\n return boundDefer(decision)\n case \"park\":\n return boundPark(decision)\n case \"escalate\":\n return boundEscalate(decision)\n case \"observe-only\":\n return depth < 2 ? boundObserveOnly(decision, depth) : decision\n }\n}\n","/**\n * Why an OpenCode execution was interrupted. Values mirror the verified\n * `session.execution.interrupted` event payload (`reason`), which OpenCode\n * guarantees to be one of these four.\n */\nexport const INTERRUPT_REASONS = [\n \"user\",\n \"shutdown\",\n \"superseded\",\n \"inactivity\",\n] as const satisfies readonly string[]\n\nexport type InterruptReason = (typeof INTERRUPT_REASONS)[number]\n","/**\n * Failure classification types (ADP-008, ADP-009).\n *\n * The classifier consumes a layered evidence record assembled by the OpenCode\n * adapter. Evidence layers exist so classification can honor the ADP-008\n * precedence chain: structured metadata beats HTTP status beats standard\n * headers beats documented provider-specific metadata beats bounded text.\n */\nimport type { InterruptReason } from \"../../routing/work-unit/interruption.js\"\n\nexport const FAILURE_CATEGORIES = [\n \"rate_limited\",\n \"quota_exhausted\",\n \"outage\",\n \"overload\",\n \"timeout\",\n \"auth_failure\",\n \"invalid_model\",\n \"context_overflow\",\n \"content_policy\",\n \"user_cancelled\",\n \"unknown\",\n] as const satisfies readonly string[]\n\nexport type FailureCategory = (typeof FAILURE_CATEGORIES)[number]\n\n/**\n * Where the winning classification came from. Exposed so receipts can show\n * why a decision was made and so tests can pin the precedence chain.\n */\nexport const EVIDENCE_LAYERS = [\n \"interruption\",\n \"structured\",\n \"status\",\n \"headers\",\n \"provider-metadata\",\n \"textual\",\n \"none\",\n] as const satisfies readonly string[]\n\nexport type EvidenceLayer = (typeof EVIDENCE_LAYERS)[number]\n\n/**\n * Structured OpenCode evidence (`Session.StructuredError`): a server-assigned\n * error tag plus, when the provider sent it, a retry delay OpenCode already\n * parsed from `Retry-After`. `type` is a free-form string on the wire, so the\n * classifier only interprets types from the documented @opencode/protocol\n * vocabulary and falls through to lower layers for anything unmapped instead\n * of guessing.\n */\nexport interface StructuredSignal {\n readonly type: string\n readonly retryAfterMs?: number | undefined\n}\n\n/**\n * Documented provider-specific metadata, already normalized by our own\n * adapters (e.g. the Codex capacity sensor validates `x-codex-*` headers\n * before producing these). The classifier never reads raw provider headers\n * itself.\n */\nexport interface ProviderMetadata {\n readonly quotaExhausted?: boolean | undefined\n readonly overloaded?: boolean | undefined\n}\n\n/**\n * Layered failure evidence. `status` is the merged HTTP status (the adapter\n * prefers the wire status seen by `http.response` over any status echoed in\n * structured metadata). `text` is the bounded concatenation of error message\n * and response body, bounded again defensively inside the classifier.\n */\nexport interface ErrorEvidence {\n readonly interrupted?: InterruptReason | undefined\n readonly structured?: StructuredSignal | undefined\n readonly status?: number | undefined\n readonly headers?: Readonly<Record<string, string>> | undefined\n readonly providerMetadata?: ProviderMetadata | undefined\n readonly text?: string | undefined\n}\n\n/** Advisory retry semantics; the retry policy (T-12) makes final decisions. */\nexport interface RetryAdvice {\n readonly retryable: boolean\n readonly retryAfterMs?: number\n}\n\nexport interface FailureClassification {\n readonly category: FailureCategory\n readonly layer: EvidenceLayer\n /** Explicit shared subscription/balance evidence; absent means keep the model scope. */\n readonly quotaScope?: \"provider\"\n /**\n * True when the evidence conclusively identifies the failure. Textual\n * classifications are always non-definitive; scheduling treats\n * non-definitive evidence more conservatively (ADP-012).\n */\n readonly definitive: boolean\n readonly retry: RetryAdvice\n /** Horizontal recovery (switch resource within the tier) is allowed. */\n readonly failoverEligible: boolean\n}\n","/**\n * Read-side parsing for persisted receipts. Every parser is total: it accepts\n * `unknown` and returns typed records, dropping anything invalid — a\n * corrupted receipts file can never take the plugin down (ADP-031). Reason\n * vocabularies are membership-checked (the write path is typed); free-text\n * fields are re-bounded. An older plugin reading newer receipts may drop\n * unknown-vocabulary entries — receipts are bounded diagnostics, eviction is\n * expected behavior, and the payload version guards the schema itself.\n */\nimport {\n APPLY_REASONS,\n ESCALATION_EVIDENCE_KINDS,\n ESCALATION_STEPS,\n PARK_REASONS,\n SKIP_REASONS,\n SCHEDULER_DEFER_REASONS,\n} from \"../../routing/scheduler/types.js\"\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n EscalationEvidence,\n ObserveOnlyDecision,\n ParkDecision,\n SkippedCandidate,\n} from \"../../routing/scheduler/types.js\"\nimport { TIERS } from \"../../routing/tier-policy/types.js\"\nimport type { TierName } from \"../../routing/tier-policy/types.js\"\nimport { INTERRUPT_REASONS } from \"../../routing/work-unit/interruption.js\"\nimport { FAILURE_CATEGORIES } from \"../../health/classifier/types.js\"\nimport { parseModelRef } from \"../settings/parse.js\"\nimport { MAX_RECEIPTS, MAX_RECEIPT_TEXT, RECEIPTS_VERSION } from \"./types.js\"\nimport type { Receipt, ReceiptOutcome } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction boundString(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined\n return raw.length > MAX_RECEIPT_TEXT ? raw.slice(0, MAX_RECEIPT_TEXT) : raw\n}\n\nfunction isFiniteNonNegative(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\nfunction parseTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\nfunction parseOptionalBounded(raw: unknown): string | undefined {\n const value = boundString(raw)\n return value === \"\" ? undefined : value\n}\n\n/** Free-text detail keeps empty strings (round-trips through the store). */\nfunction parseDetailBounded(raw: unknown): string | undefined {\n return boundString(raw) ?? undefined\n}\n\nfunction parseApplyEvidence(raw: unknown): ApplyDecision[\"evidence\"] | undefined {\n if (!isRecord(raw)) return undefined\n const skippedRaw = raw[\"skipped\"]\n if (!Array.isArray(skippedRaw)) return undefined\n const skipped: SkippedCandidate[] = []\n for (const entry of skippedRaw.slice(0, 8)) {\n if (!isRecord(entry)) continue\n const ref = parseModelRef(entry[\"ref\"])\n const why = parseVocab(entry[\"why\"], SKIP_REASONS)\n if (ref === undefined || why === undefined) continue\n skipped.push({ ref, why })\n }\n const probeId = parseDetailBounded(raw[\"probeId\"])\n return { skipped, ...(probeId !== undefined ? { probeId } : {}) }\n}\n\nfunction parseApply(raw: Record<string, unknown>): ApplyDecision | undefined {\n const model = parseModelRef(raw[\"model\"])\n const reason = parseVocab(raw[\"reason\"], APPLY_REASONS)\n const evidence = parseApplyEvidence(raw[\"evidence\"])\n if (model === undefined || reason === undefined || evidence === undefined) {\n return undefined\n }\n const tier = parseTier(raw[\"tier\"])\n return {\n kind: \"apply\",\n model,\n ...(tier !== undefined ? { tier } : {}),\n reason,\n evidence,\n }\n}\n\nfunction parseDefer(raw: Record<string, unknown>): DeferDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], SCHEDULER_DEFER_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"defer\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parsePark(raw: Record<string, unknown>): ParkDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], PARK_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"park\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parseEscalate(raw: Record<string, unknown>): EscalateDecision | undefined {\n const target = parseModelRef(raw[\"target\"])\n const step = parseVocab(raw[\"step\"], ESCALATION_STEPS)\n const tier = parseTier(raw[\"tier\"])\n const budgetRemainingRaw = raw[\"budgetRemaining\"]\n if (\n target === undefined ||\n step === undefined ||\n tier === undefined ||\n !isFiniteNonNegative(budgetRemainingRaw)\n ) {\n return undefined\n }\n const evidenceRaw = raw[\"evidence\"]\n if (!Array.isArray(evidenceRaw)) return undefined\n const evidence: EscalationEvidence[] = []\n for (const entry of evidenceRaw.slice(0, 4)) {\n if (!isRecord(entry)) continue\n const kind = parseVocab(entry[\"kind\"], ESCALATION_EVIDENCE_KINDS)\n if (kind === undefined) continue\n const detail = parseDetailBounded(entry[\"detail\"])\n evidence.push({ kind, ...(detail !== undefined ? { detail } : {}) })\n }\n return {\n kind: \"escalate\",\n target,\n step,\n tier,\n evidence,\n budgetRemaining: budgetRemainingRaw,\n }\n}\n\n/** Max `observe-only` nesting accepted on read (the scheduler produces ≤ 1). */\nconst MAX_PARSE_DEPTH = 2\n\nfunction parseObserveOnly(\n raw: Record<string, unknown>,\n depth: number,\n): ObserveOnlyDecision | undefined {\n if (depth >= MAX_PARSE_DEPTH) return undefined\n const would = parseDecision(raw[\"would\"], depth + 1)\n return would === undefined ? undefined : { kind: \"observe-only\", would }\n}\n\nfunction parseDecision(raw: unknown, depth = 0): Decision | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"kind\"]) {\n case \"apply\":\n return parseApply(raw)\n case \"defer\":\n return parseDefer(raw)\n case \"park\":\n return parsePark(raw)\n case \"escalate\":\n return parseEscalate(raw)\n case \"observe-only\":\n return parseObserveOnly(raw, depth)\n default:\n return undefined\n }\n}\n\nfunction parseOutcome(raw: unknown): ReceiptOutcome | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"status\"]) {\n case \"succeeded\":\n return { status: \"succeeded\" }\n case \"failed\": {\n const category = parseVocab(raw[\"category\"], FAILURE_CATEGORIES)\n return category === undefined ? undefined : { status: \"failed\", category }\n }\n case \"interrupted\": {\n const reason = parseVocab(raw[\"reason\"], INTERRUPT_REASONS)\n return reason === undefined ? undefined : { status: \"interrupted\", reason }\n }\n default:\n return undefined\n }\n}\n\nfunction parseReceipt(raw: unknown): Receipt | undefined {\n if (!isRecord(raw)) return undefined\n const id = raw[\"id\"]\n const at = raw[\"at\"]\n const sessionID = parseOptionalBounded(raw[\"sessionID\"])\n const decision = parseDecision(raw[\"decision\"])\n if (\n !(isFiniteNonNegative(id) && Number.isInteger(id) && isFiniteNonNegative(at)) ||\n sessionID === undefined ||\n decision === undefined\n ) {\n return undefined\n }\n const unitID = parseOptionalBounded(raw[\"unitID\"])\n const tier = parseTier(raw[\"tier\"])\n // A present-but-invalid outcome invalidates the whole record: stripping\n // just the outcome would break first-outcome-wins across a restart (the\n // receipt would accept a later, different outcome as its first).\n let outcome: ReceiptOutcome | undefined\n if (raw[\"outcome\"] !== undefined) {\n outcome = parseOutcome(raw[\"outcome\"])\n if (outcome === undefined) return undefined\n }\n return {\n id,\n at,\n sessionID,\n ...(unitID !== undefined ? { unitID } : {}),\n ...(tier !== undefined ? { tier } : {}),\n decision,\n ...(outcome !== undefined ? { outcome } : {}),\n }\n}\n\n/**\n * Parse a persisted receipts payload. Accepts the versioned shape and a\n * versionless draft array; anything else yields no receipts.\n */\nexport function parseReceiptsPayload(raw: unknown): Receipt[] {\n let list: unknown\n if (isRecord(raw)) {\n const version = raw[\"version\"]\n if (version !== RECEIPTS_VERSION && version !== undefined) return []\n list = raw[\"receipts\"]\n } else if (Array.isArray(raw)) {\n list = raw\n }\n if (!Array.isArray(list)) return []\n const parsed = list\n .map(parseReceipt)\n .filter((receipt): receipt is Receipt => receipt !== undefined)\n return parsed.length > MAX_RECEIPTS ? parsed.slice(-MAX_RECEIPTS) : parsed\n}\n","/**\n * Bounded receipt store (ADP-030). Receipts live in a ring capped at\n * `MAX_RECEIPTS` (newest kept, oldest evicted) and persist through the\n * storage seam on every mutation. Ids are monotonic across restarts (they\n * continue from the persisted maximum) so a receipt can always be told apart\n * from its neighbors. Write failures propagate to the caller — the wiring\n * layer's fail-open wrapper decides how to degrade (ADP-031) — and the\n * in-memory ring is only advanced after a successful write, so memory and\n * disk never diverge.\n */\nimport { boundDecision, boundText } from \"./bound.js\"\nimport { parseReceiptsPayload } from \"./parse.js\"\nimport { MAX_RECEIPTS, RECEIPTS_VERSION } from \"./types.js\"\nimport type {\n Receipt,\n ReceiptInput,\n ReceiptOutcome,\n ReceiptsPayload,\n ReceiptsStorage,\n} from \"./types.js\"\n\nexport interface ReceiptRef {\n readonly sessionID: string\n /** When given, only receipts of that unit are updated; otherwise only receipts without a unit. */\n readonly unitID?: string | undefined\n}\n\nexport class ReceiptStore {\n #receipts: Receipt[] = []\n #counter = 0\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: ReceiptsStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#receipts = []\n return\n }\n const parsed = parseReceiptsPayload(raw)\n this.#receipts = parsed\n this.#counter = parsed.reduce((max, receipt) => Math.max(max, receipt.id), 0)\n }\n\n /** All retained receipts, oldest → newest. */\n snapshot(): readonly Receipt[] {\n return this.#receipts\n }\n\n record(input: ReceiptInput): Promise<Receipt> {\n return this.#serialize(() => this.#record(input))\n }\n\n async #record(input: ReceiptInput): Promise<Receipt> {\n // A receipt with no session can never be attributed to anything, and the\n // read path drops empty identifiers — persisting one would make it vanish\n // across a restart. Throw instead; the wiring layer fail-open-catches.\n if (input.sessionID.trim() === \"\") {\n throw new Error(\"invalid receipt: sessionID must be a non-empty string\")\n }\n const id = this.#counter + 1\n const receipt: Receipt = {\n id,\n at: input.at,\n // Identifiers are bounded with the same bound the read path applies, so\n // what is persisted is exactly what comes back (types.ts invariant).\n sessionID: boundText(input.sessionID),\n ...(input.unitID !== undefined ? { unitID: boundText(input.unitID) } : {}),\n ...(input.tier !== undefined ? { tier: input.tier } : {}),\n decision: boundDecision(input.decision),\n }\n const next =\n this.#receipts.length >= MAX_RECEIPTS\n ? [...this.#receipts.slice(1 - MAX_RECEIPTS), receipt]\n : [...this.#receipts, receipt]\n // Persist BEFORE committing memory: a write failure must leave memory and\n // disk consistent (the caller decides how to fail open).\n await this.#persist(next)\n this.#receipts = next\n this.#counter = id\n return receipt\n }\n\n /**\n * Attach a unit outcome to matching receipts that do not have one yet\n * (first outcome wins). Returns how many receipts were updated; zero\n * updates do not touch storage.\n */\n attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n return this.#serialize(() => this.#attachOutcome(ref, outcome))\n }\n\n async #attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n let updated = 0\n const next = this.#receipts.map((receipt) => {\n if (receipt.outcome !== undefined) return receipt\n if (receipt.sessionID !== ref.sessionID) return receipt\n const matches =\n ref.unitID !== undefined ? receipt.unitID === ref.unitID : receipt.unitID === undefined\n if (!matches) return receipt\n updated++\n return { ...receipt, outcome }\n })\n if (updated === 0) return 0\n await this.#persist(next)\n this.#receipts = next\n return updated\n }\n\n /**\n * Stamps the unit that just opened onto the session's pending unit-less\n * admission receipts (recorded in the awaited prompt hook, before the unit\n * existed). After adoption the receipt carries the unitID, so outcomes\n * attach to it like any unit-scoped receipt.\n *\n * One opened unit adopts ONE admission — the newest pending receipt. With\n * several pending receipts (a prompt admitted but superseded before its\n * unit ever opened), stamping all of them would attach this unit's outcome\n * to foreign admission decisions; the older receipts stay pending instead.\n */\n adoptUnit(sessionID: string, unitID: string): Promise<number> {\n return this.#serialize(() => this.#adoptUnit(sessionID, unitID))\n }\n\n async #adoptUnit(sessionID: string, unitID: string): Promise<number> {\n let target: number | undefined\n this.#receipts.forEach((receipt, index) => {\n if (receipt.unitID !== undefined || receipt.outcome !== undefined) return\n if (receipt.sessionID !== sessionID) return\n target = index\n })\n if (target === undefined) return 0\n const at = target\n const next = this.#receipts.map((receipt, index) =>\n index === at ? { ...receipt, unitID } : receipt,\n )\n await this.#persist(next)\n this.#receipts = next\n return 1\n }\n\n // Include reads in the chain so a reload cannot overwrite a newer commit.\n // A failed write rejects its caller without blocking subsequent operations.\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n\n /** Writes the given next state; the caller commits memory only on success. */\n async #persist(receipts: readonly Receipt[]): Promise<void> {\n const payload: ReceiptsPayload = {\n version: RECEIPTS_VERSION,\n receipts,\n }\n await this.storage.write(payload)\n }\n}\n","// covers: [\"ADP-030\", \"ADP-051\", \"ADP-059\"]\nimport { isDeepStrictEqual } from \"node:util\"\nimport { ReceiptStore, type ReceiptRef } from \"@coool/adaptive-core/state/receipts/store\"\nimport { parseReceiptsPayload } from \"@coool/adaptive-core/state/receipts/parse\"\nimport type {\n Receipt,\n ReceiptInput,\n ReceiptOutcome,\n} from \"@coool/adaptive-core/state/receipts/types\"\nimport type { JsonTransactionFile } from \"./store.js\"\n\nfunction parse(raw: unknown): readonly Receipt[] {\n if (raw === undefined) return []\n const receipts = parseReceiptsPayload(raw)\n if (!isDeepStrictEqual(raw, { version: 1, receipts }))\n throw new Error(\"Adaptive receipts: invalid receipts.json payload\")\n return receipts\n}\n\nasync function transaction<R>(\n file: JsonTransactionFile,\n change: (store: ReceiptStore) => Promise<R>,\n): Promise<R> {\n return file.transaction(async (current) => {\n const receipts = parse(current)\n let next: unknown\n const store = new ReceiptStore({\n read: () => Promise.resolve({ version: 1, receipts }),\n write: (payload) => {\n next = payload\n return Promise.resolve()\n },\n })\n await store.load()\n return { result: await change(store), next }\n })\n}\n\nexport function recordReceipt(file: JsonTransactionFile, input: ReceiptInput): Promise<Receipt> {\n return transaction(file, (store) => store.record(input))\n}\n\nexport function attachReceiptOutcome(\n file: JsonTransactionFile,\n ref: ReceiptRef,\n outcome: ReceiptOutcome,\n): Promise<number> {\n return transaction(file, (store) => store.attachOutcome(ref, outcome))\n}\n\n/** Shared flow expects newest first; the durable ring remains oldest first. */\nexport async function readReceipts(file: Pick<JsonTransactionFile, \"read\">): Promise<Receipt[]> {\n return [...parse(await file.read())].reverse()\n}\n","import type { CandidateModel, Demand, IncompatibilityReason, Verdict } from \"./types.js\"\n\n/** A finite, non-negative token count is assessable; anything else is unknown demand. */\nfunction assessableTokens(value: number | undefined): value is number {\n return value !== undefined && Number.isFinite(value) && value >= 0\n}\n\nfunction supportsModalities(\n supported: readonly string[] | undefined,\n demanded: readonly string[],\n): boolean {\n if (supported === undefined) {\n return false\n }\n return demanded.every((modality) => supported.includes(modality))\n}\n\n/**\n * Run every check and accumulate reasons in fixed order. A candidate is\n * compatible only when no reason applies; unknown candidate metadata never\n * satisfies a stated requirement.\n */\nexport function checkCompatibility(candidate: CandidateModel, demand: Demand): Verdict {\n const reasons: IncompatibilityReason[] = []\n\n if (candidate.providerEnabled !== true) {\n reasons.push(\"provider-unavailable\")\n }\n if (candidate.enabled !== true) {\n reasons.push(\"model-unavailable\")\n }\n if (candidate.variant !== undefined && candidate.variantAvailable !== true) {\n reasons.push(\"variant-unavailable\")\n }\n\n if (demand.tools === true && candidate.capabilities?.tools !== true) {\n reasons.push(\"tool-use-unsupported\")\n }\n if (\n demand.input !== undefined &&\n demand.input.length > 0 &&\n !supportsModalities(candidate.capabilities?.input, demand.input)\n ) {\n reasons.push(\"input-modality-unsupported\")\n }\n if (\n demand.output !== undefined &&\n demand.output.length > 0 &&\n !supportsModalities(candidate.capabilities?.output, demand.output)\n ) {\n reasons.push(\"output-modality-unsupported\")\n }\n\n if (assessableTokens(demand.contextTokens)) {\n const contextLimit = candidate.limit?.context\n if (!assessableTokens(contextLimit)) {\n reasons.push(\"context-capacity-unknown\")\n } else if (contextLimit < demand.contextTokens) {\n reasons.push(\"context-capacity-insufficient\")\n }\n }\n\n return { compatible: reasons.length === 0, reasons }\n}\n","/**\n * Admission routing (ADP-013/016/022): pick the model for a fresh work unit,\n * or decide to defer (OpenCode's choice stands) or park (wait for recovery).\n *\n * Selection, after the compatibility gate (ADP-017) filters candidates: the\n * first candidate in user order that is ready or due for its half-open probe\n * wins; draining only when none is. Rationale: a due probe at a preferred\n * position is how that resource returns (ADP-018/019) — passing it over for a\n * later ready sibling would keep it out forever; a draining resource is being\n * retired, so depending on it is the last resort. Breaker single-flight is\n * enforced by the resource-health registry, not here.\n */\nimport { checkCompatibility } from \"../compatibility/gate.js\"\nimport type { CandidateModel } from \"../compatibility/types.js\"\nimport type { RoutingDecision, TierName } from \"../tier-policy/types.js\"\nimport { sameModelRef, type ModelRef } from \"../work-unit/types.js\"\nimport type { Assessment } from \"../../health/resource-health/types.js\"\nimport type { CapacitySignals } from \"../../health/capacity/types.js\"\nimport type {\n AdmissionDecision,\n ApplyDecision,\n ApplyReason,\n SchedulerInput,\n SkippedCandidate,\n SkipReason,\n} from \"./types.js\"\nimport { MAX_EVIDENCE_SKIPPED, schedulerHealthKey } from \"./types.js\"\n\n/** The health/capacity view of one candidate, resolved to an admission bucket. */\ntype Bucket =\n | { readonly kind: \"ready\" }\n | { readonly kind: \"probe\"; readonly probeId: string }\n | { readonly kind: \"draining\" }\n | { readonly kind: \"skip\"; readonly why: SkipReason }\n\nfunction refOfCandidate(candidate: CandidateModel): ModelRef {\n return {\n providerID: candidate.providerID,\n id: candidate.modelID,\n variant: candidate.variant,\n }\n}\n\nfunction lookup(inventory: readonly CandidateModel[], ref: ModelRef): CandidateModel | undefined {\n return inventory.find((candidate) => sameModelRef(refOfCandidate(candidate), ref))\n}\n\nfunction classify(\n assessment: Assessment | undefined,\n signals: CapacitySignals | undefined,\n): Bucket {\n if (signals?.exhausted === true) {\n return { kind: \"skip\", why: \"capacity-exhausted\" }\n }\n if (assessment === undefined) {\n return signals?.draining === true ? { kind: \"draining\" } : { kind: \"ready\" }\n }\n if (assessment.kind === \"probe\") {\n return { kind: \"probe\", probeId: assessment.ticket.id }\n }\n if (assessment.kind === \"available\") {\n return signals?.draining === true ? { kind: \"draining\" } : { kind: \"ready\" }\n }\n return assessment.reason === \"draining\"\n ? { kind: \"draining\" }\n : { kind: \"skip\", why: assessment.reason }\n}\n\nfunction apply(\n model: ModelRef,\n tier: TierName | undefined,\n reason: ApplyReason,\n skipped: readonly SkippedCandidate[],\n probeId: string | undefined,\n): ApplyDecision {\n return {\n kind: \"apply\",\n model,\n ...(tier === undefined ? {} : { tier }),\n reason,\n evidence: {\n skipped: skipped.slice(0, MAX_EVIDENCE_SKIPPED),\n ...(probeId === undefined ? {} : { probeId }),\n },\n }\n}\n\nfunction admitPin(input: SchedulerInput, pin: ModelRef): AdmissionDecision {\n const entry = lookup(input.inventory, pin)\n if (entry === undefined) {\n return { kind: \"defer\", reason: \"pin-unverifiable\" }\n }\n const verdict = checkCompatibility(entry, input.demand)\n if (!verdict.compatible) {\n return { kind: \"defer\", reason: \"pin-incompatible\", detail: verdict.reasons.join(\",\") }\n }\n const key = schedulerHealthKey(pin)\n const bucket = classify(input.health[key], input.capacity[key])\n if (bucket.kind === \"skip\") {\n return { kind: \"park\", reason: \"pin-blocked\", detail: bucket.why }\n }\n // Manual intent wins (GOAL): a pinned model is applied even while draining;\n // a probe admission is recorded for observability but never overrides intent.\n return apply(pin, undefined, \"pin\", [], bucket.kind === \"probe\" ? bucket.probeId : undefined)\n}\n\nfunction admitTier(input: SchedulerInput, tier: TierName): AdmissionDecision {\n if (input.tierCandidates.length === 0) {\n // The tier was reported configured but has an empty list — a configuration\n // discrepancy; park rather than invent resources (ADP-005).\n return { kind: \"park\", reason: \"no-candidates\" }\n }\n // Candidates passed over before the winner (or all of them, when none won).\n const seen: { ref: ModelRef; bucket: Extract<Bucket, { kind: \"draining\" | \"skip\" }> }[] = []\n let gateSkipped = 0\n const skipWhys: string[] = []\n let chosen: { ref: ModelRef; bucket: Extract<Bucket, { kind: \"ready\" | \"probe\" }> } | undefined\n for (const ref of input.tierCandidates) {\n const entry = lookup(input.inventory, ref)\n if (entry === undefined) {\n seen.push({ ref, bucket: { kind: \"skip\", why: \"not-in-inventory\" } })\n skipWhys.push(\"not-in-inventory\")\n gateSkipped += 1\n continue\n }\n const verdict = checkCompatibility(entry, input.demand)\n if (!verdict.compatible) {\n // The gate reports incompatible only when at least one reason exists; the\n // non-null assertion is the only way to express that invariant locally.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const why = verdict.reasons[0]!\n seen.push({ ref, bucket: { kind: \"skip\", why } })\n skipWhys.push(why)\n gateSkipped += 1\n continue\n }\n const key = schedulerHealthKey(ref)\n const bucket = classify(input.health[key], input.capacity[key])\n if (bucket.kind === \"ready\" || bucket.kind === \"probe\") {\n // The first ready or probe candidate wins; later candidates are\n // irrelevant, so the scan stops and the evidence stays an honest prefix\n // of the user order.\n chosen = { ref, bucket }\n break\n }\n seen.push({ ref, bucket })\n if (bucket.kind === \"skip\") {\n skipWhys.push(bucket.why)\n }\n }\n const first = input.tierCandidates[0]\n const evidenceBefore = (until: number): SkippedCandidate[] =>\n seen.slice(0, until).map((e): SkippedCandidate => ({\n ref: e.ref,\n why: e.bucket.kind === \"skip\" ? e.bucket.why : \"draining\",\n }))\n if (chosen?.bucket.kind === \"probe\") {\n return apply(chosen.ref, tier, \"probe\", evidenceBefore(seen.length), chosen.bucket.probeId)\n }\n if (chosen !== undefined) {\n return apply(\n chosen.ref,\n tier,\n first !== undefined && sameModelRef(chosen.ref, first) ? \"preferred\" : \"fallback\",\n evidenceBefore(seen.length),\n undefined,\n )\n }\n const drainIndex = seen.findIndex((e) => e.bucket.kind === \"draining\")\n const drainEntry = drainIndex >= 0 ? seen[drainIndex] : undefined\n if (drainEntry !== undefined) {\n return apply(drainEntry.ref, tier, \"draining\", evidenceBefore(drainIndex), undefined)\n }\n const summary = skipWhys.slice(0, 3).join(\",\")\n return {\n kind: \"park\",\n reason: gateSkipped === skipWhys.length ? \"no-compatible-resource\" : \"all-blocked\",\n detail: summary,\n }\n}\n\n/**\n * Decide the model for a fresh work unit. Total and deterministic: the same\n * input always yields the same decision, and the function has no effects.\n */\nexport function admit(input: SchedulerInput): AdmissionDecision {\n const routing: RoutingDecision = input.routing\n if (routing.kind === \"defer\") {\n return { kind: \"defer\", reason: \"routing-defer\", detail: routing.reason }\n }\n if (routing.kind === \"pin\") {\n return admitPin(input, routing.model)\n }\n return admitTier(input, routing.tier)\n}\n","// covers: [\"ADP-002\", \"ADP-005\", \"ADP-009\", \"ADP-013\", \"ADP-017\", \"ADP-022\", \"ADP-057\"]\nimport { admit } from \"@coool/adaptive-core/routing/scheduler/admit\"\nimport type {\n SchedulerInput,\n AdmissionDecision,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\n\nexport const VIRTUAL_IDS = [\"auto\", \"quick\", \"standard\", \"advanced\"] as const\nexport type VirtualID = (typeof VIRTUAL_IDS)[number]\n\nexport interface RouteInput {\n readonly tier: TierName\n /** In-unit request: keep the previous physical model when there is one. */\n readonly sticky: boolean\n readonly settings: SettingsV1\n readonly previous: ModelRef | undefined\n readonly inventory: SchedulerInput[\"inventory\"]\n readonly demand: SchedulerInput[\"demand\"]\n readonly health: SchedulerInput[\"health\"]\n readonly capacity: SchedulerInput[\"capacity\"]\n /** Models this unit already failed over from (same-tier recovery). */\n readonly exclude: readonly ModelRef[]\n}\n\n/** The models a non-sticky admission may dispatch, before exclusions. */\nexport function admissionCandidates(settings: SettingsV1, tier: TierName): readonly ModelRef[] {\n return settings.pin === null ? settings.tiers[tier] : [settings.pin]\n}\n\nfunction excluded(exclude: readonly ModelRef[], ref: ModelRef): boolean {\n return exclude.some((tried) => tried.providerID === ref.providerID && tried.id === ref.id)\n}\n\n/**\n * Admit within the tier, never across it. Recovery first avoids the models\n * this unit already failed on; when nothing else in the tier can take the\n * work, the failed model stays eligible so Pi's own backoff retry proceeds\n * unless health blocks it. A user pin always wins and is never excluded.\n */\nexport function routeAdmission(input: RouteInput): AdmissionDecision {\n // Ordinary tool continuations must never be repriced or re-tiered mid-unit.\n const pin = input.sticky ? input.previous : input.settings.pin\n const decide = (exclude: readonly ModelRef[]) =>\n admit({\n routing:\n pin === undefined || pin === null\n ? { kind: \"tier\", tier: input.tier, source: \"default\" }\n : { kind: \"pin\", model: pin },\n inventory: input.inventory,\n demand: input.demand,\n tierCandidates: input.settings.tiers[input.tier].filter((ref) => !excluded(exclude, ref)),\n health: input.health,\n capacity: input.capacity,\n })\n const decision = decide(input.exclude)\n return decision.kind === \"apply\" || input.exclude.length === 0 ? decision : decide([])\n}\n","import type { ErrorEvidence, FailureCategory, FailureClassification, RetryAdvice } from \"./types.js\"\n\n/**\n * Text fed to the textual last-resort layer is truncated to this bound before\n * matching, so adversarial or enormous error bodies cannot dominate\n * classification cost or smuggle patterns in late bytes (ADP-008).\n */\nconst TEXT_BOUND = 512\n\n// These messages describe the subscription's shared allowance or balance,\n// unlike a generic quota error or a named model-family limit (ADP-007).\nconst SHARED_QUOTA_PATTERN =\n /\\byou['’]ve hit your (?:session|usage|weekly) limit(?=\\s*(?:$|[·.,;(:]|resets?\\b))|\\b(?:out of credits|insufficient credits|credit balance)\\b/i\n\n// A 429 whose message says the quota itself is spent (\"You exceeded your\n// current quota, please check your plan and billing details\") is quota\n// exhaustion: a burst-sized window would re-admit it every half minute. The\n// status stays the definitive evidence; text only picks the window. Messages\n// that also speak of rate limits keep the short window — Gemini words its\n// per-minute 429s as \"exceeded your current quota\" and links its rate-limit\n// docs.\nconst RATE_LIMIT_TEXT = /rate[ _-]?limit|per min/i\n\n/**\n * Retry/failover policy per category (ADP-010, ADP-011).\n *\n * - Infrastructure failures (rate limiting, quota, outage, overload, timeout)\n * are failover-eligible: horizontal recovery within the tier is exactly\n * their remedy.\n * - Permanent configuration failures (auth, invalid model, content policy)\n * and context overflow never retry and never failover: retrying the same\n * request cannot help and switching resources would reproduce the failure.\n * - User cancellation is final: no retry, no failover (ADP-010).\n * - Unknown failures defer to OpenCode's native handling.\n */\nconst CATEGORY_POLICY: Readonly<\n Record<FailureCategory, { retryable: boolean; failoverEligible: boolean }>\n> = {\n rate_limited: { retryable: true, failoverEligible: true },\n quota_exhausted: { retryable: false, failoverEligible: true },\n outage: { retryable: true, failoverEligible: true },\n overload: { retryable: true, failoverEligible: true },\n timeout: { retryable: true, failoverEligible: true },\n auth_failure: { retryable: false, failoverEligible: false },\n invalid_model: { retryable: false, failoverEligible: false },\n context_overflow: { retryable: false, failoverEligible: false },\n content_policy: { retryable: false, failoverEligible: false },\n user_cancelled: { retryable: false, failoverEligible: false },\n unknown: { retryable: false, failoverEligible: false },\n}\n\n/**\n * Error tags from the documented @opencode/protocol vocabulary that map\n * directly to a failure category. Tags absent here (`ProviderRequestError`,\n * `UnknownError`, anything unrecognized) are structured but not\n * category-specific: they never guess, and classification falls through to\n * the refining layers.\n */\nconst STRUCTURED_TYPES = new Map<string, FailureCategory>([\n [\"UnauthorizedError\", \"auth_failure\"],\n [\"ForbiddenError\", \"auth_failure\"],\n [\"ModelNotFoundError\", \"invalid_model\"],\n [\"UnsupportedModelError\", \"invalid_model\"],\n [\"ServiceUnavailableError\", \"outage\"],\n])\n\n/**\n * Bounded textual patterns, last resort only (ADP-008). Ordered most\n * specific first; the first match wins. These encode provider error-message\n * conventions documented by the research phase, not a general-purpose\n * keyword classifier.\n */\nconst TEXTUAL_PATTERNS: readonly {\n readonly category: FailureCategory\n readonly pattern: RegExp\n}[] = [\n {\n category: \"context_overflow\",\n pattern:\n /context (length|window)|maximum context|input length exceeds|prompt is too long|too many (input )?tokens|exceeds the maximum/i,\n },\n {\n // Subscription limits (\"You've hit your session/usage limit\") are quota\n // exhaustion with a provider-side reset window; the reset time in the\n // text is not parsed (the classifier has no clock) — the health layer's\n // default quota window bounds the quarantine instead.\n // Sibling fallback plugins' issue trackers document the real-world\n // phrasings that missed curated whitelists (oh-my-openagent #2393/#5815,\n // lichter's 429 lesson): snake-cased limits, \"usage exceeded\" without\n // \"limit\", credit exhaustion without \"balance\". Qualifiers stay required\n // so \"token limit reached\" (context overflow) never matches quota.\n category: \"quota_exhausted\",\n pattern:\n /\\bquota\\b|credit balance|(?:session|usage|free usage|message|plan|monthly|weekly|daily)[ _-]?limit|usage exceeded|out of credits|insufficient credits/i,\n },\n { category: \"rate_limited\", pattern: /rate ?limit/i },\n { category: \"timeout\", pattern: /\\btimeout\\b|timed? ?out|deadline exceeded|etimedout/i },\n {\n category: \"auth_failure\",\n pattern:\n /unauthorized|invalid (api|access) key|api key (expired|invalid)|authentication|permission denied/i,\n },\n {\n category: \"invalid_model\",\n pattern: /model.{0,30}(does not exist|not found)|invalid model|unknown model|no such model/i,\n },\n {\n // OpenAI-compatible finish reasons arrive snake-cased (\"Provider\n // finish_reason: content_filter\" in pi-ai).\n category: \"content_policy\",\n pattern:\n /content[ _](management[ _])?(policy|filter)|safety system|violates?.{0,32}policy|flagged as/i,\n },\n { category: \"overload\", pattern: /overloaded|over capacity|high demand/i },\n { category: \"user_cancelled\", pattern: /cancel+(l)?ed|aborted by (the )?user|user abort/i },\n]\n\nfunction isHttpStatus(status: number | undefined): status is number {\n return typeof status === \"number\" && Number.isInteger(status) && status >= 100 && status <= 599\n}\n\n/**\n * Upper bound on a provider-claimed retry delay. `Retry-After` and structured\n * retry metadata are untrusted provider data: a hostile or misconfigured\n * value (\"999999999\" seconds) must not convert one response into a\n * near-permanent resource blacklist. The host's own retry scheduling waits\n * out the raw header verbatim — this bound only concerns the health window\n * the supervisor derives from the classification (ADP-011 boundedness).\n */\nconst MAX_RETRY_AFTER_MS = 24 * 60 * 60 * 1000\n\nfunction boundedRetryAfterMs(retryAfterMs: number | undefined): number | undefined {\n if (retryAfterMs === undefined) {\n return undefined\n }\n return Math.min(retryAfterMs, MAX_RETRY_AFTER_MS)\n}\n\nfunction isNonNegativeInteger(value: number | undefined): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 0\n}\n\nfunction lowercasedHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n): ReadonlyMap<string, string> {\n const lowered = new Map<string, string>()\n if (headers === undefined) {\n return lowered\n }\n for (const [name, value] of Object.entries(headers)) {\n lowered.set(name.toLowerCase(), value)\n }\n return lowered\n}\n\n/**\n * Parses a `Retry-After` header into milliseconds. Only the integer-seconds\n * form is accepted: the HTTP-date form requires a clock, which the classifier\n * deliberately does not have (reset-time handling belongs to the capacity\n * boundary, T-05/T-15).\n */\nfunction retryAfterHeaderMs(headers: ReadonlyMap<string, string>): number | undefined {\n const raw = headers.get(\"retry-after\")\n if (raw === undefined || !/^\\d+$/.test(raw)) {\n return undefined\n }\n return Number(raw) * 1000\n}\n\n/**\n * Standard rate-limit headers (case-insensitive `x-ratelimit-remaining*`).\n * All-zero remaining capacity indicates a fixed-window quota exhaustion\n * rather than a short burst limit.\n */\nfunction fixedWindowExhausted(headers: ReadonlyMap<string, string>): boolean {\n let sawRemaining = false\n for (const [name, value] of headers) {\n if (name.startsWith(\"x-ratelimit-remaining\")) {\n sawRemaining = true\n if (value !== \"0\") {\n return false\n }\n }\n }\n return sawRemaining\n}\n\nfunction retryAdvice(category: FailureCategory, retryAfterMs: number | undefined): RetryAdvice {\n const policy = CATEGORY_POLICY[category]\n const bounded = boundedRetryAfterMs(retryAfterMs)\n if (bounded === undefined) {\n return { retryable: policy.retryable }\n }\n return { retryable: policy.retryable, retryAfterMs: bounded }\n}\n\nfunction classification(\n category: FailureCategory,\n layer: FailureClassification[\"layer\"],\n definitive: boolean,\n retryAfterMs: number | undefined,\n quotaScope?: \"provider\",\n): FailureClassification {\n const policy = CATEGORY_POLICY[category]\n return {\n category,\n layer,\n definitive,\n retry: retryAdvice(category, retryAfterMs),\n failoverEligible: policy.failoverEligible,\n ...(quotaScope !== undefined ? { quotaScope } : {}),\n }\n}\n\n/**\n * Classifies an HTTP status. 429 consults the standard rate-limit headers in\n * the same step: status plus documented standard headers are one HTTP\n * semantics layer, and the quota refinement is more specific evidence than a\n * bare 429, so it cannot weaken the ADP-008 precedence.\n */\nfunction classifyStatus(\n status: number,\n headers: ReadonlyMap<string, string>,\n): FailureCategory | undefined {\n if (status === 429) {\n return fixedWindowExhausted(headers) ? \"quota_exhausted\" : \"rate_limited\"\n }\n if (status === 401 || status === 403) {\n return \"auth_failure\"\n }\n if (status === 402) {\n return \"quota_exhausted\"\n }\n if (status === 408) {\n return \"timeout\"\n }\n if (status === 413) {\n return \"context_overflow\"\n }\n if (status === 502 || status === 503 || status === 504) {\n return \"outage\"\n }\n return undefined\n}\n\nfunction classifyText(text: string): FailureCategory | undefined {\n const bounded = text.length > TEXT_BOUND ? text.slice(0, TEXT_BOUND) : text\n for (const { category, pattern } of TEXTUAL_PATTERNS) {\n if (pattern.test(bounded)) {\n return category\n }\n }\n return undefined\n}\n\n/**\n * Total classification of layered failure evidence. Never throws and always\n * returns a category: any evidence shape outside the documented vocabularies\n * classifies as `unknown` via the `none` layer, deferring to OpenCode's\n * native failure handling (ADP-009, ADP-012).\n */\nexport function classifyFailure(evidence: ErrorEvidence): FailureClassification {\n // Layer 0: interruption evidence. Interruptions are host decisions, not\n // provider failures; a user cancellation is final (ADP-010).\n if (evidence.interrupted === \"user\") {\n return classification(\"user_cancelled\", \"interruption\", true, undefined)\n }\n if (evidence.interrupted !== undefined) {\n return classification(\"unknown\", \"interruption\", true, undefined)\n }\n\n // Layer 1: structured OpenCode metadata.\n const structured = evidence.structured\n const structuredRetryAfterMs = isNonNegativeInteger(structured?.retryAfterMs)\n ? structured.retryAfterMs\n : undefined\n if (structured !== undefined) {\n const mapped = STRUCTURED_TYPES.get(structured.type)\n if (mapped !== undefined) {\n return classification(mapped, \"structured\", true, structuredRetryAfterMs)\n }\n // Unmapped tag: fall through so HTTP semantics can refine the category.\n }\n\n // Layer 2: HTTP status (+ standard headers for the 429 refinement).\n const headers = lowercasedHeaders(evidence.headers)\n if (isHttpStatus(evidence.status)) {\n const category = classifyStatus(evidence.status, headers)\n if (category !== undefined) {\n const retryAfterMs = structuredRetryAfterMs ?? retryAfterHeaderMs(headers)\n // Payment Required is the account's balance, not one model's limit:\n // every model behind the provider ID (a gateway such as OpenRouter or\n // Ofox) bills the same account, so a sibling model cannot help.\n if (evidence.status === 402) {\n return classification(category, \"status\", true, retryAfterMs, \"provider\")\n }\n if (category === \"rate_limited\" && evidence.text !== undefined) {\n const bounded = evidence.text.slice(0, TEXT_BOUND)\n if (classifyText(bounded) === \"quota_exhausted\" && !RATE_LIMIT_TEXT.test(bounded)) {\n const quotaScope = SHARED_QUOTA_PATTERN.test(bounded) ? \"provider\" : undefined\n return classification(\"quota_exhausted\", \"status\", true, retryAfterMs, quotaScope)\n }\n }\n return classification(category, \"status\", true, retryAfterMs)\n }\n }\n\n // Layer 3: standard headers alone (Retry-After without a decisive status).\n const headerRetryAfterMs = retryAfterHeaderMs(headers)\n if (headerRetryAfterMs !== undefined) {\n return classification(\"rate_limited\", \"headers\", false, headerRetryAfterMs)\n }\n\n // Layer 4: documented provider-specific metadata, normalized by our own\n // adapters after validation (T-15).\n if (evidence.providerMetadata?.quotaExhausted === true) {\n return classification(\"quota_exhausted\", \"provider-metadata\", true, undefined)\n }\n if (evidence.providerMetadata?.overloaded === true) {\n return classification(\"overload\", \"provider-metadata\", true, structuredRetryAfterMs)\n }\n\n // Layer 5: bounded textual classification, always non-definitive.\n const text = evidence.text\n if (text !== undefined) {\n const category = classifyText(text)\n if (category !== undefined) {\n const quotaScope =\n category === \"quota_exhausted\" && SHARED_QUOTA_PATTERN.test(text.slice(0, TEXT_BOUND))\n ? \"provider\"\n : undefined\n return classification(category, \"textual\", false, structuredRetryAfterMs, quotaScope)\n }\n }\n\n return classification(\"unknown\", \"none\", false, undefined)\n}\n","/**\n * Capability escalation planner (ADP-015).\n *\n * Escalation is justified only by non-empty structured evidence, follows the\n * ladder next tier, and is bounded by the caller's finite budget. The\n * same-model stronger-variant rung is not implemented: it would need an\n * ordered variant ladder the host does not expose, and strength is never\n * guessed from variant names. Every output moves strictly up the ladder or\n * refuses. Termination rests on the budget, which the caller must carry\n * across every unit of one task (each escalation continues on a new unit).\n */\nimport { nextTier } from \"../tier-policy/types.js\"\nimport type { ModelRef } from \"../work-unit/types.js\"\nimport type { DeferDecision, EscalateDecision, EscalationInput } from \"./types.js\"\nimport { MAX_ESCALATION_EVIDENCE } from \"./types.js\"\n\nfunction escalate(\n input: EscalationInput,\n target: ModelRef,\n step: EscalateDecision[\"step\"],\n tier: EscalateDecision[\"tier\"],\n): EscalateDecision {\n return {\n kind: \"escalate\",\n target,\n step,\n tier,\n evidence: input.evidence.slice(-MAX_ESCALATION_EVIDENCE),\n budgetRemaining: input.budget.max - input.budget.used - 1,\n }\n}\n\n/**\n * Plan the next escalation step, or defer with the reason escalation cannot\n * proceed. Total and deterministic.\n */\nexport function planEscalation(input: EscalationInput): EscalateDecision | DeferDecision {\n if (input.evidence.length === 0) {\n return { kind: \"defer\", reason: \"escalation-not-justified\" }\n }\n if (input.budget.max <= 0 || input.budget.used >= input.budget.max) {\n return { kind: \"defer\", reason: \"escalation-budget-exhausted\" }\n }\n const next = nextTier(input.currentTier)\n if (next === undefined) {\n return { kind: \"defer\", reason: \"escalation-ceiling\" }\n }\n const target = input.nextTierResources[0]\n if (target === undefined) {\n return { kind: \"defer\", reason: \"escalation-no-candidate\" }\n }\n return escalate(input, target, \"tier\", next)\n}\n","// covers: [\"ADP-008\", \"ADP-065\"]\n/**\n * Failure evidence from a Pi assistant message. Pi reports provider failures\n * only as free-text `errorMessage`; there is no structured status field. The\n * pi-ai adapters do place the HTTP status deterministically at the start of\n * that text — SDK errors read \"429 You exceeded…\" or \"503 status code (no\n * body)\", and pi-ai's `formatProviderError` writes \"429: <body>\" or\n * \"<Provider> API error (429): …\" — so the status is recovered from those\n * prefixes only. A status mentioned later in a body is not trusted, and\n * everything else stays textual, non-definitive evidence (ADP-008).\n */\nimport type { ErrorEvidence } from \"@coool/adaptive-core/health/classifier/types\"\n\n/** The structural subset of Pi's `AssistantMessage` this module reads. */\nexport interface FailedMessage {\n readonly stopReason: string\n readonly errorMessage?: string | undefined\n}\n\nconst STATUS_PREFIXES: readonly RegExp[] = [\n /^(\\d{3})(?=[\\s:]|$)/,\n /^[\\w .-]+ API error \\((\\d{3})\\):/,\n]\n\n// pi-ai's Bedrock adapter replaces the SDK exception name with a fixed\n// human-readable prefix and drops the status. AWS documents these exceptions\n// as HTTP 429 and 503; without this, \"Throttling error: Too many tokens…\"\n// would read as context overflow.\nconst BEDROCK_STATUS: readonly (readonly [string, number])[] = [\n [\"Throttling error: \", 429],\n [\"Service unavailable: \", 503],\n]\n\nfunction statusOf(text: string): number | undefined {\n for (const pattern of STATUS_PREFIXES) {\n const digits = pattern.exec(text)?.[1]\n if (digits !== undefined) {\n return Number(digits)\n }\n }\n return BEDROCK_STATUS.find(([prefix]) => text.startsWith(prefix))?.[1]\n}\n\nexport function failureEvidence(message: FailedMessage): ErrorEvidence {\n // Pi marks a user abort (Esc, or the abort signal during retry backoff) as\n // its own stop reason; it is never a provider failure (ADP-010).\n if (message.stopReason === \"aborted\") {\n return { interrupted: \"user\" }\n }\n const text = message.errorMessage?.trim() ?? \"\"\n if (text === \"\") {\n return {}\n }\n const status = statusOf(text)\n return status === undefined ? { text } : { status, text }\n}\n","// covers: [\"ADP-009\", \"ADP-013\", \"ADP-015\", \"ADP-016\", \"ADP-017\", \"ADP-055\", \"ADP-061\"]\n/**\n * Branch-aware task state for the Pi virtual models. Everything is derived\n * from the session branch Pi hands us — router state, tool results, and the\n * hidden continuation message — so forking or rewinding a session also\n * rewinds tier requests and escalation budgets. Pure: no Pi imports.\n */\nimport { classifyFailure } from \"@coool/adaptive-core/health/classifier/classify\"\nimport type { FailureClassification } from \"@coool/adaptive-core/health/classifier/types\"\nimport {\n CAPABILITY_FAILURE_CATEGORIES,\n escalationDetail,\n MAX_ESCALATIONS_PER_TASK,\n parseEscalationRequest,\n} from \"@coool/adaptive-core/execution/escalation/index\"\nimport { planEscalation } from \"@coool/adaptive-core/routing/scheduler/escalate\"\nimport type { EscalationEvidence } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { isTierName, nextTier } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { failureEvidence, type FailedMessage } from \"./evidence.js\"\nimport type { VirtualID } from \"./router.js\"\n\nexport const TIER_TOOL = \"adaptive_tier\"\nexport const CONTINUATION_TYPE = \"adaptive.continuation\"\n// Pi's own custom entry for router state (`VIRTUAL_MODEL_STATE_ENTRY`); the\n// constant is not exported from the package root.\nconst ROUTER_STATE_ENTRY = \"pi.virtual-model-state\"\n/** Infra restarts after a run ended on a provider failure, per task (ADP-061). */\nexport const MAX_RESTARTS_PER_TASK = 2\n\n/** The structural subset of Pi's `SessionEntry` this module reads. */\nexport interface BranchEntry {\n readonly type: string\n readonly customType?: string\n readonly data?: unknown\n readonly details?: unknown\n readonly message?: BranchMessage\n}\n\ninterface BranchMessage {\n readonly role: string\n readonly toolName?: string\n readonly details?: unknown\n readonly provider?: string\n readonly model?: string\n readonly stopReason?: string\n readonly errorMessage?: string\n}\n\n/** Router state stored by Pi on the branch for one virtual model. */\nexport interface TaskState {\n readonly version: 1\n readonly task: string\n readonly unit: string\n readonly tier: TierName\n readonly escalations: number\n readonly restarts: number\n readonly hops?: number\n /** Failed wake deliveries of this task (the give-up budget, ADP-024). */\n readonly wakes?: number\n /** Token of the park this task was resumed from, when it was. */\n readonly wakeToken?: string\n /** Models this unit failed over from; new admissions in the unit avoid them. */\n readonly tried: readonly ModelRef[]\n /** Token of the last owned continuation already turned into a unit. */\n readonly consumed?: string\n}\n\n/** Details of the hidden continuation message that continues a task. */\nexport interface Recovery {\n readonly task: string\n readonly token: string\n readonly tier: TierName\n readonly escalations: number\n readonly restarts: number\n readonly wakes?: number\n /** Set when this continuation resumes parked work (its park's token). */\n readonly wakeToken?: string\n /** Models the new unit starts out avoiding (the one that just failed). */\n readonly tried: readonly ModelRef[]\n}\n\nexport interface RoutePlan {\n readonly tier: TierName\n /** Keep the previous physical model (in-unit continuation or retry). */\n readonly sticky: boolean\n /** Models a non-sticky admission avoids while the tier has alternatives. */\n readonly exclude: readonly ModelRef[]\n readonly state: TaskState | undefined\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\nfunction text(value: unknown, key: string, label: string): string {\n const found = field(value, key)\n if (typeof found !== \"string\" || found.length === 0)\n throw new Error(`${label}: ${key} must be a non-empty string`)\n return found\n}\n\nfunction tier(value: unknown, label: string): TierName {\n const found = field(value, \"tier\")\n if (typeof found !== \"string\" || !isTierName(found))\n throw new Error(`${label}: tier must be quick, standard, or advanced`)\n return found\n}\n\nfunction count(value: unknown, key: string, label: string): number {\n const found = field(value, key)\n if (typeof found !== \"number\" || !Number.isSafeInteger(found) || found < 0)\n throw new Error(`${label}: ${key} must be a non-negative integer`)\n return found\n}\n\nfunction parkingCounts(\n value: unknown,\n label: string,\n): { readonly wakes?: number; readonly hops?: number; readonly wakeToken?: string } {\n const token = field(value, \"wakeToken\")\n if (token !== undefined && (typeof token !== \"string\" || token.length === 0))\n throw new Error(`${label}: wakeToken must be a non-empty string`)\n return {\n ...(field(value, \"wakes\") === undefined ? {} : { wakes: count(value, \"wakes\", label) }),\n ...(field(value, \"hops\") === undefined ? {} : { hops: count(value, \"hops\", label) }),\n ...(token === undefined ? {} : { wakeToken: token }),\n }\n}\n\nfunction refs(value: unknown, label: string): ModelRef[] {\n const found = field(value, \"tried\")\n if (!Array.isArray(found)) throw new Error(`${label}: tried must be an array`)\n return found.map((entry: unknown, index) => ({\n providerID: text(entry, \"providerID\", `${label}: tried[${String(index)}]`),\n id: text(entry, \"id\", `${label}: tried[${String(index)}]`),\n }))\n}\n\nfunction sameRef(left: ModelRef, right: ModelRef): boolean {\n return left.providerID === right.providerID && left.id === right.id\n}\n\n/** Total parser for persisted router state; `undefined` means none yet. */\nexport function parseTaskState(value: unknown): TaskState | undefined {\n if (value === undefined) return undefined\n const label = \"Adaptive task state\"\n if (field(value, \"version\") !== 1) throw new Error(`${label}: version must be 1`)\n const consumed = field(value, \"consumed\")\n if (consumed !== undefined && (typeof consumed !== \"string\" || consumed.length === 0))\n throw new Error(`${label}: consumed must be a non-empty string`)\n return {\n version: 1,\n task: text(value, \"task\", label),\n unit: text(value, \"unit\", label),\n tier: tier(value, label),\n escalations: count(value, \"escalations\", label),\n restarts: count(value, \"restarts\", label),\n ...parkingCounts(value, label),\n tried: refs(value, label),\n ...(consumed === undefined ? {} : { consumed }),\n }\n}\n\nfunction parseRecovery(value: unknown): Recovery {\n const label = \"Adaptive continuation\"\n return {\n task: text(value, \"task\", label),\n token: text(value, \"token\", label),\n tier: tier(value, label),\n escalations: count(value, \"escalations\", label),\n restarts: count(value, \"restarts\", label),\n ...parkingCounts(value, label),\n tried: refs(value, label),\n }\n}\n\n/** Latest router state Pi stored on this branch for `adaptive/<id>`. */\nexport function branchState(branch: readonly BranchEntry[], id: VirtualID): TaskState | undefined {\n const entry = branch.findLast(\n (candidate) =>\n candidate.type === \"custom\" &&\n candidate.customType === ROUTER_STATE_ENTRY &&\n field(candidate.data, \"provider\") === \"adaptive\" &&\n field(candidate.data, \"modelId\") === id,\n )\n return parseTaskState(field(entry?.data, \"state\"))\n}\n\nfunction toolResults(branch: readonly BranchEntry[], name: string): unknown[] {\n return branch.flatMap((entry) =>\n entry.message?.role === \"toolResult\" && entry.message.toolName === name\n ? [entry.message.details]\n : [],\n )\n}\n\n/** The latest recorded `adaptive_tier` request (sticky for the session branch). */\nexport function tierRequest(branch: readonly BranchEntry[]): TierName | undefined {\n const recorded = toolResults(branch, TIER_TOOL)\n .map((details) => field(details, \"tier\"))\n .findLast((value) => typeof value === \"string\" && isTierName(value))\n return typeof recorded === \"string\" && isTierName(recorded) ? recorded : undefined\n}\n\nfunction isUnitStart(entry: BranchEntry): boolean {\n return (\n entry.message?.role === \"user\" ||\n (entry.type === \"custom_message\" && entry.customType === CONTINUATION_TYPE)\n )\n}\n\n/** Entries of the current unit: everything after the latest unit start. */\nfunction currentUnit(branch: readonly BranchEntry[]): readonly BranchEntry[] {\n return branch.slice(branch.findLastIndex(isUnitStart) + 1)\n}\n\n/**\n * The owned continuation that the next `continuation` route must turn into a\n * new unit. Only our hidden message, as the latest conversation entry, for\n * the branch's current task and not yet consumed — any other extension's\n * message or a user prompt in between invalidates it.\n */\nexport function pendingRecovery(\n branch: readonly BranchEntry[],\n state: TaskState | undefined,\n): Recovery | undefined {\n const latest = branch.findLast(\n (entry) => entry.type === \"message\" || entry.type === \"custom_message\",\n )\n if (\n state === undefined ||\n latest?.type !== \"custom_message\" ||\n latest.customType !== CONTINUATION_TYPE\n )\n return undefined\n const recovery = parseRecovery(latest.details)\n return recovery.task === state.task && recovery.token !== state.consumed ? recovery : undefined\n}\n\n/** The request Pi is retrying: what failed and on which physical model. */\nexport interface FailedRequest {\n readonly model: ModelRef\n readonly message: FailedMessage\n}\n\nexport interface PlanRouteInput {\n readonly id: VirtualID\n readonly reason: \"user\" | \"continuation\" | \"retry\" | \"direct\"\n readonly state: TaskState | undefined\n readonly branch: readonly BranchEntry[]\n /** ADP-055: sticky session-tier requests rank under a user pin, above the default. */\n readonly requestedTier?: TierName | null | undefined\n readonly failed?: FailedRequest | undefined\n readonly newId: () => string\n}\n\nexport function startTask(tier: TierName, newId: () => string): TaskState {\n return { version: 1, task: newId(), unit: newId(), tier, escalations: 0, restarts: 0, tried: [] }\n}\n\n/** Infra failures that another resource of the same tier may absorb. */\nexport function infraFailure(message: FailedMessage): FailureClassification | undefined {\n const classification = classifyFailure(failureEvidence(message))\n return classification.failoverEligible ? classification : undefined\n}\n\n/**\n * Which tier admits this request and how the task state moves. A user prompt\n * starts a new task (escalations and restarts never carry over); an owned\n * continuation starts a new unit of the same task; a native retry after an\n * infra failure re-admits within the tier, avoiding the models that failed\n * (ADP-009/013 — never a capability escalation); everything else stays\n * in-unit on the previous model.\n */\nexport function planRoute(input: PlanRouteInput): RoutePlan {\n const selected: TierName = input.id === \"auto\" ? \"standard\" : input.id\n const { state } = input\n if (input.reason === \"direct\")\n return { tier: \"quick\", sticky: false, exclude: [], state: input.state }\n if (input.reason === \"user\") {\n const base =\n input.id === \"auto\"\n ? (input.requestedTier ?? tierRequest(input.branch) ?? selected)\n : selected\n return {\n tier: base,\n sticky: false,\n exclude: [],\n state: startTask(base, input.newId),\n }\n }\n if (input.reason === \"retry\" && state !== undefined && input.failed !== undefined) {\n const failed = input.failed\n if (infraFailure(failed.message) !== undefined) {\n const tried = state.tried.some((ref) => sameRef(ref, failed.model))\n ? state.tried\n : [...state.tried, failed.model]\n return {\n tier: state.tier,\n sticky: false,\n exclude: tried,\n state: { ...state, tried, hops: (state.hops ?? 0) + 1 },\n }\n }\n }\n const recovery =\n input.reason === \"continuation\" ? pendingRecovery(input.branch, state) : undefined\n if (recovery === undefined)\n return { tier: state?.tier ?? selected, sticky: true, exclude: [], state }\n return {\n tier: recovery.tier,\n sticky: false,\n exclude: recovery.tried,\n state: {\n version: 1,\n task: recovery.task,\n unit: input.newId(),\n tier: recovery.tier,\n escalations: recovery.escalations,\n restarts: recovery.restarts,\n ...(recovery.wakes === undefined ? {} : { wakes: recovery.wakes }),\n ...(recovery.wakeToken === undefined ? {} : { wakeToken: recovery.wakeToken }),\n tried: recovery.tried,\n consumed: recovery.token,\n },\n }\n}\n\n/** Escalation requests recorded by `adaptive_escalate` during the current unit. */\nexport function unitEvidence(branch: readonly BranchEntry[], tool: string): EscalationEvidence[] {\n return toolResults(currentUnit(branch), tool).flatMap((details) => {\n const request = parseEscalationRequest(details)\n return request === undefined\n ? []\n : [{ kind: \"agent-request\", detail: escalationDetail(request) }]\n })\n}\n\nexport interface AfterRunInput {\n readonly id: VirtualID\n readonly escalateFromPinned: boolean\n /** The host resolves virtual selection and branch overrides before settling. */\n readonly settings: SettingsV1\n readonly branch: readonly BranchEntry[]\n /** Physical models Pi can dispatch right now. */\n readonly available: readonly ModelRef[]\n readonly tool: string\n readonly newId: () => string\n}\n\ninterface FailedRun {\n readonly state: TaskState\n readonly model: ModelRef\n readonly classification: FailureClassification\n}\n\n/**\n * The failure the settled run ended on, for an unpinned task in active mode.\n * Without a user pin the routing is Adaptive's; with one it never recovers on\n * the user's behalf.\n */\nfunction failedRun(input: AfterRunInput): FailedRun | undefined {\n if (input.settings.mode !== \"active\" || input.settings.pin !== null) return undefined\n const state = branchState(input.branch, input.id)\n const last = currentUnit(input.branch).findLast((entry) => entry.message?.role === \"assistant\")\n const message = last?.message\n // A run Adaptive's own route ended (Pi records it under the virtual model)\n // carries no provider evidence to recover from.\n if (state === undefined || message?.stopReason !== \"error\" || message.provider === \"adaptive\")\n return undefined\n return {\n state,\n model: { providerID: message.provider ?? \"\", id: message.model ?? \"\" },\n classification: classifyFailure(\n failureEvidence({ stopReason: message.stopReason, errorMessage: message.errorMessage }),\n ),\n }\n}\n\n/**\n * Decide, after a run settles, whether the task continues one tier up\n * (ADP-015..017). Pinned tiers require explicit user opt-in. Only a capability-class\n * failure of the run's last request, only to a configured, dispatchable\n * next-tier model, within the per-task budget. A successful run never\n * escalates, whatever the agent requested.\n */\nexport function escalationAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = input.id === \"auto\" || input.escalateFromPinned ? failedRun(input) : undefined\n if (run === undefined || !CAPABILITY_FAILURE_CATEGORIES.includes(run.classification.category))\n return undefined\n const { state } = run\n const next = nextTier(state.tier)\n const plan = planEscalation({\n currentModel: run.model,\n currentTier: state.tier,\n nextTierResources: (next === undefined ? [] : input.settings.tiers[next]).filter((ref) =>\n input.available.some((model) => sameRef(model, ref)),\n ),\n evidence: [\n ...unitEvidence(input.branch, input.tool),\n { kind: \"repeated-failure\", detail: run.classification.category },\n ],\n budget: { used: state.escalations, max: MAX_ESCALATIONS_PER_TASK },\n })\n if (plan.kind !== \"escalate\") return undefined\n return {\n task: state.task,\n token: input.newId(),\n tier: plan.tier,\n escalations: state.escalations + 1,\n restarts: state.restarts,\n ...(state.wakes === undefined ? {} : { wakes: state.wakes }),\n ...(state.wakeToken === undefined ? {} : { wakeToken: state.wakeToken }),\n tried: [],\n }\n}\n\n/**\n * Decide, after a run settles on an infra failure Pi did not (or could no\n * longer) retry — quota and billing errors are never retried natively —\n * whether the task continues on another model of the SAME tier (ADP-061).\n * Bounded per task; the failed model is avoided while the tier has another.\n */\nexport function restartAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = failedRun(input)\n if (!run?.classification.failoverEligible) return undefined\n const { state } = run\n if (state.restarts >= MAX_RESTARTS_PER_TASK) return undefined\n return {\n task: state.task,\n token: input.newId(),\n tier: state.tier,\n escalations: state.escalations,\n restarts: state.restarts + 1,\n ...(state.wakes === undefined ? {} : { wakes: state.wakes }),\n ...(state.wakeToken === undefined ? {} : { wakeToken: state.wakeToken }),\n // A failure without provider metadata names no model to avoid; an empty\n // reference would make the continuation unparseable.\n tried: [run.model].filter((ref) => ref.providerID !== \"\" && ref.id !== \"\"),\n }\n}\n\n/**\n * A spent immediate-restart budget may still wait for an actual tier reset.\n * A task that was resumed from a park (wakeToken) and failed again has\n * consumed one wake of the give-up budget; a task that never woke has not.\n */\nexport function parkingAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = failedRun(input)\n if (!run?.classification.failoverEligible || run.state.restarts < MAX_RESTARTS_PER_TASK)\n return undefined\n const { wakes, wakeToken } = run.state\n return {\n task: run.state.task,\n token: input.newId(),\n tier: run.state.tier,\n escalations: run.state.escalations,\n restarts: run.state.restarts,\n wakes: (wakes ?? 0) + (wakeToken === undefined ? 0 : 1),\n ...(wakeToken === undefined ? {} : { wakeToken }),\n tried: [],\n }\n}\n\n/**\n * The task whose wake lineage a successful settle concludes. A provider success\n * is the only outcome that closes a park: the record it parked stands for work\n * that just finished, and keeping it would promise work that no longer exists.\n * A failed settle never serves — the recovery chain owns the lineage then.\n */\nexport function servedTask(input: AfterRunInput): string | undefined {\n const last = currentUnit(input.branch).findLast((entry) => entry.message?.role === \"assistant\")\n if (last?.message?.stopReason !== \"stop\") return undefined\n return branchState(input.branch, input.id)?.task\n}\n","import type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { isTierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { object } from \"./settings.js\"\nimport { VIRTUAL_IDS } from \"./router.js\"\nimport { TIER_TOOL, type BranchEntry } from \"./task.js\"\n\nexport const SESSION_ENTRY = \"adaptive.session\"\nexport interface SessionPatch {\n readonly version: 1\n readonly mode?: OperatingMode | null\n readonly tier?: TierName | null\n}\n\nfunction parse(raw: unknown): SessionPatch {\n if (!object(raw) || raw[\"version\"] !== 1) throw new Error(\"Adaptive session.version: expected 1\")\n const mode = raw[\"mode\"]\n const tier = raw[\"tier\"]\n if (\n mode !== undefined &&\n mode !== null &&\n mode !== \"off\" &&\n mode !== \"observe\" &&\n mode !== \"active\"\n )\n throw new Error(\"Adaptive session.mode: expected off, observe, active, or null\")\n if (tier !== undefined && tier !== null && (typeof tier !== \"string\" || !isTierName(tier)))\n throw new Error(\"Adaptive session.tier: expected quick, standard, advanced, or null\")\n return {\n version: 1,\n ...(mode === undefined ? {} : { mode }),\n ...(tier === undefined ? {} : { tier }),\n }\n}\n\nexport function sessionModeOverride(branch: readonly BranchEntry[]): OperatingMode | null {\n let mode: OperatingMode | null = null\n for (const entry of branch) {\n if (entry.type !== \"custom\" || entry.customType !== SESSION_ENTRY) continue\n const patch = parse(entry.data)\n if (patch.mode !== undefined) mode = patch.mode\n }\n return mode\n}\n\n/** A physical selection is always manual, even if the global mode says active. */\nexport function effectiveMode(\n model: { readonly provider: string; readonly id: string } | undefined,\n global: OperatingMode,\n branch: readonly BranchEntry[],\n): OperatingMode {\n if (model?.provider === \"adaptive\" && VIRTUAL_IDS.some((id) => id === model.id)) return \"active\"\n const override = sessionModeOverride(branch)\n return (override ?? global) === \"off\" ? \"off\" : \"observe\"\n}\n\n/** User dialogs and tool declarations share one chronological, branch-aware request. */\nexport function requestedTier(branch: readonly BranchEntry[]): TierName | null {\n let tier: TierName | null = null\n for (const entry of branch) {\n if (entry.type === \"custom\" && entry.customType === SESSION_ENTRY) {\n const patch = parse(entry.data)\n if (patch.tier !== undefined) tier = patch.tier\n }\n if (entry.message?.role === \"toolResult\" && entry.message.toolName === TIER_TOOL) {\n const details = entry.message.details\n if (object(details)) {\n const next = details[\"tier\"]\n if (next === null || (typeof next === \"string\" && isTierName(next))) tier = next\n }\n }\n }\n return tier\n}\n","/**\n * Tier-editor view models (ADP-033): resource labels with clear health tags,\n * model search over the host's available models, variant picking, and pure\n * reorder/remove helpers. All functions are total and deterministic.\n */\nimport type { ModelRef } from \"../routing/work-unit/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../status.js\"\nimport type { SettingsV1 } from \"../state/settings/index.js\"\nimport type { SelectOption } from \"./options.js\"\n\n/** `provider/model` with an `@variant` suffix when pinned to one. */\nexport function resourceLabel(ref: ModelRef): string {\n const base = `${ref.providerID}/${ref.id}`\n return ref.variant === undefined ? base : `${base}@${ref.variant}`\n}\n\n/**\n * Unavailable-resource display: empty string when healthy, otherwise a\n * bracketed, comma-separated tag list (health, breaker, window).\n */\nexport function healthTag(status: TierResourceStatus | undefined): string {\n if (status === undefined) return \"\"\n const parts: string[] = []\n if (status.health !== \"healthy\") parts.push(status.health)\n if (status.breaker === \"open\") parts.push(\"breaker-open\")\n else if (status.breaker === \"half_open\") parts.push(\"half-open\")\n if (status.windowed) parts.push(\"windowed\")\n return parts.length === 0 ? \"\" : ` [${parts.join(\", \")}]`\n}\n\nexport type TierEditorChoice = { kind: \"add\" } | { kind: \"resource\"; index: number; ref: ModelRef }\nexport function tierEditorOptions(\n settings: SettingsV1,\n tier: TierName,\n status: StatusSnapshot | undefined,\n modelSearchPlaceholder: string,\n): SelectOption<TierEditorChoice>[] {\n const options: SelectOption<TierEditorChoice>[] = [\n { title: \"Add model…\", value: { kind: \"add\" }, description: modelSearchPlaceholder },\n ]\n const tierStatus = status?.tiers[tier]\n settings.tiers[tier].forEach((ref, index) => {\n options.push({\n title: `${resourceLabel(ref)}${healthTag(tierStatus?.[index])}`,\n value: { kind: \"resource\", index, ref },\n description: \"Move or remove\",\n })\n })\n // No \"Back\" row: Escape steps back out of the dialog (undefined pick →\n // the editor loop re-shows the tier list).\n return options\n}\n\nexport function tierMenuOptions(status: StatusSnapshot): SelectOption<TierName>[] {\n return TIERS.map((tier) => {\n const resources = status.tiers[tier]\n // The lists are short: showing them inline answers \"what is configured\n // where\" without opening the editor.\n const description =\n resources.length === 0\n ? \"(empty — add models to enable routing)\"\n : resources.map((entry) => resourceLabel(entry.ref)).join(\" · \")\n return { title: `${tier} (${String(resources.length)})`, value: tier, description }\n })\n}\n\n/** Structural summary of one real OpenCode model (built by the entry). */\nexport interface ModelSummary {\n readonly providerID: string\n readonly modelID: string\n readonly name: string\n readonly variants: readonly string[]\n}\n\nexport function modelPickerOptions(models: readonly ModelSummary[]): SelectOption<ModelSummary>[] {\n return models.map((info) => ({\n title: `${info.providerID}/${info.modelID}`,\n description: info.name,\n value: info,\n }))\n}\n\nexport interface VariantChoice {\n variant: string | undefined\n}\n\nexport function variantOptions(variants: readonly string[]): SelectOption<VariantChoice>[] {\n const options: SelectOption<VariantChoice>[] = [\n { title: \"(model default)\", value: { variant: undefined } },\n ]\n for (const variant of variants) {\n options.push({ title: `@${variant}`, value: { variant } })\n }\n return options\n}\n\n/** Move the resource at `index` to the front (make it primary); out-of-bounds is a no-op. */\nexport function moveResourceToTop(resources: readonly ModelRef[], index: number): ModelRef[] {\n return [...resources.filter((_, i) => i === index), ...resources.filter((_, i) => i !== index)]\n}\n\n/** Swap the resource at `index` with its `delta` neighbour; bounds are no-ops. */\nexport function moveResource(\n resources: readonly ModelRef[],\n index: number,\n delta: -1 | 1,\n): ModelRef[] {\n const next = [...resources]\n const target = index + delta\n const item = next[index]\n const other = next[target]\n if (item === undefined || other === undefined) return next\n next[index] = other\n next[target] = item\n return next\n}\n\n/** Drop the resource at `index`; out-of-bounds keeps the list unchanged. */\nexport function removeResource(resources: readonly ModelRef[], index: number): ModelRef[] {\n return resources.filter((_, i) => i !== index)\n}\n","// covers: [\"ADP-057\", \"ADP-058\"]\nimport { sameModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport type { Decision, ParkReason } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { NoteVerbosity } from \"../preferences.js\"\n\nexport interface AdaptiveNote {\n readonly version: 1\n readonly text: string\n readonly receiptID?: number\n}\n\nfunction base(decision: Decision): Decision {\n return decision.kind === \"observe-only\" ? base(decision.would) : decision\n}\n\nexport function shouldWriteNote(\n verbosity: NoteVerbosity,\n decision: Decision,\n previous: Decision | undefined,\n): boolean {\n if (verbosity === \"quiet\") return false\n if (verbosity === \"all\" || previous === undefined) return true\n const current = base(decision)\n const last = base(previous)\n return (\n current.kind !== \"apply\" ||\n last.kind !== \"apply\" ||\n current.reason === \"fallback\" ||\n current.reason === \"probe\" ||\n decision.kind !== previous.kind ||\n !sameModelRef(current.model, last.model)\n )\n}\n\nconst PARKED: Record<ParkReason, string> = {\n \"all-blocked\": \"all models unavailable\",\n \"no-candidates\": \"no models configured\",\n \"no-compatible-resource\": \"no compatible model\",\n \"pin-blocked\": \"pinned model unavailable\",\n}\nconst APPLIED: Partial<Record<Extract<Decision, { kind: \"apply\" }>[\"reason\"], string>> = {\n fallback: \" · fallback\",\n probe: \" · testing recovery\",\n}\n\n/** Written when the user leaves an Adaptive model: routing stops until they come back. */\nexport function pausedNote(model: { readonly provider: string; readonly id: string }): string {\n return `Paused · you picked ${model.provider}/${model.id}`\n}\n\nexport function decisionNote(decision: Decision, tier: TierName, retry = false): string {\n switch (decision.kind) {\n case \"observe-only\":\n return `Observing · would ${decisionNote(decision.would, tier, retry)}`\n case \"apply\":\n return `${tier} → ${resourceLabel(decision.model)}${retry ? \" · retry\" : (APPLIED[decision.reason] ?? \"\")}`\n case \"park\":\n return `${tier} waiting · ${PARKED[decision.reason]}`\n case \"defer\":\n return `Not routing · ${decision.reason.replaceAll(\"-\", \" \")} · /adaptive why`\n case \"escalate\":\n return `Escalated to ${decision.tier} for this task → ${resourceLabel(decision.target)}`\n }\n}\n","/**\n * Pure circuit breaker state machine (ADP-019).\n *\n * All functions are total, synchronous, and clock-free: `now` is always an\n * injected parameter. The single-probe guarantee comes from the admission\n * protocol: `admitProbe` synchronously transitions an open (and due) breaker\n * to half-open, so the second concurrent caller observes `half_open` and is\n * blocked — there is never an await between the state check and the\n * transition. Callers must persist the returned record immediately.\n */\nimport type { FailureCategory } from \"../classifier/types.js\"\nimport { BREAKER_EXEMPT_CATEGORIES, type BreakerConfig, type BreakerRecord } from \"./types.js\"\n\nexport function initialBreaker(): BreakerRecord {\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\n/**\n * Backoff window for the `openCount`-th opening: doubling, capped at\n * `maxBackoffMs` so a persistently failing resource never waits longer than\n * the configured ceiling.\n */\nfunction backoffMs(openCount: number, config: BreakerConfig): number {\n return Math.min(config.baseOpenMs * 2 ** (openCount - 1), config.maxBackoffMs)\n}\n\nfunction openBreaker(\n record: BreakerRecord,\n openCount: number,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n return {\n state: \"open\",\n failures: record.failures,\n openCount,\n reopenAt: now + backoffMs(openCount, config),\n }\n}\n\nexport interface BreakerFailureResult {\n readonly record: BreakerRecord\n /** True exactly when this failure tripped the breaker from closed to open. */\n readonly opened: boolean\n}\n\n/**\n * Records a countable failure. Callers route only infrastructure failures\n * here (the resource-health transitions layer sends outage, overload, and\n * timeout); the breaker additionally exempts rate limiting and quota\n * exhaustion, which own their windowed resource states. Failures observed\n * while the breaker is not closed cannot happen through the admission\n * protocol (non-probe callers are blocked) and are ignored defensively.\n */\nexport function recordBreakerFailure(\n record: BreakerRecord,\n category: FailureCategory,\n now: number,\n config: BreakerConfig,\n): BreakerFailureResult {\n if (BREAKER_EXEMPT_CATEGORIES.includes(category) || record.state !== \"closed\") {\n return { record, opened: false }\n }\n const failures = record.failures + 1\n if (failures < config.failureThreshold) {\n return { record: { ...record, failures }, opened: false }\n }\n return {\n record: openBreaker({ ...record, failures }, record.openCount + 1, now, config),\n opened: true,\n }\n}\n\n/**\n * Observed success closes the breaker and resets the failure/backoff state.\n * Evidence beats inference: a success is proof the resource works, from any\n * prior breaker state.\n */\nexport function recordBreakerSuccess(): BreakerRecord {\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\nexport type ProbeAdmission =\n | { kind: \"closed\"; record: BreakerRecord }\n | { kind: \"waiting\"; record: BreakerRecord; retryAtMs: number }\n | { kind: \"in-flight\"; record: BreakerRecord }\n | { kind: \"admitted\"; record: BreakerRecord }\n\n/**\n * Attempts to admit the single half-open probe. Callers must persist the\n * returned record synchronously; the returned record carries no probeId — the\n * registry stamps its own ticket id on the persisted copy.\n */\n/**\n * Non-mutating wait computation for an open breaker, admission view: the\n * remaining backoff in ms, or `undefined` when the window has elapsed (or the\n * record is not open). Used to decide whether a probe may be admitted.\n */\nexport function breakerWait(record: BreakerRecord, now: number): number | undefined {\n if (record.state !== \"open\") return undefined\n const reopenAt = record.reopenAt\n if (reopenAt !== undefined && now < reopenAt) return reopenAt - now\n return undefined\n}\n\n/**\n * Non-mutating block computation for an open breaker, observer view: an open\n * breaker blocks regardless of elapsed backoff — recovery counts only once a\n * probe proved it — so an elapsed (or, unreachable through the state machine,\n * missing) stamp simply means zero remaining wait.\n */\nexport function breakerBlockWait(record: BreakerRecord, now: number): number | undefined {\n if (record.state !== \"open\") return undefined\n return Math.max(0, (record.reopenAt ?? 0) - now)\n}\n\nexport function admitProbe(record: BreakerRecord, now: number): ProbeAdmission {\n if (record.state === \"closed\") {\n return { kind: \"closed\", record }\n }\n if (record.state === \"half_open\") {\n return { kind: \"in-flight\", record }\n }\n const wait = breakerWait(record, now)\n if (wait !== undefined) {\n return { kind: \"waiting\", record, retryAtMs: wait }\n }\n return {\n kind: \"admitted\",\n record: { state: \"half_open\", failures: record.failures, openCount: record.openCount },\n }\n}\n\n/** Closes the breaker when a probe report confirms recovery. */\nexport function recordProbeSuccess(record: BreakerRecord): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\n/**\n * Expires a probe whose episode never reported an outcome. A lost probe is\n * no health evidence: the breaker re-arms the SAME backoff window (no\n * doubling) so a fresh probe can be admitted after it. Evaluated lazily by\n * the registry's assessment sweep — there are no timers.\n */\nexport function expireProbe(\n record: BreakerRecord,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n if (\n record.state !== \"half_open\" ||\n record.probeAt === undefined ||\n now - record.probeAt < config.probeTimeoutMs\n ) {\n return record\n }\n return openBreaker(record, record.openCount, now, config)\n}\n\n/**\n * Returns an admitted probe that was never dispatched (the admission picked\n * another resource, only observed, or failed to switch). No request ran, so\n * this is no evidence at all: the breaker goes back to open with the window\n * it was admitted under — still due — instead of restarting the backoff,\n * which would push a passed-over resource back on every admission.\n */\nexport function releaseProbe(record: BreakerRecord): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n return {\n state: \"open\",\n failures: record.failures,\n openCount: record.openCount,\n ...(record.probeAt !== undefined ? { reopenAt: record.probeAt } : {}),\n }\n}\n\n/**\n * Records a failed probe. A non-exempt failure reopens the breaker with a\n * doubled backoff. An exempt failure (the probe was rate limited or quota\n * blocked) re-arms the same backoff window without escalation: the resource\n * was rejected for demand reasons, not degraded health, so doubling would\n * overstate the failure.\n */\nexport function recordProbeFailure(\n record: BreakerRecord,\n category: FailureCategory,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n if (BREAKER_EXEMPT_CATEGORIES.includes(category)) {\n return openBreaker(record, record.openCount, now, config)\n }\n return openBreaker(record, record.openCount + 1, now, config)\n}\n","/**\n * Capacity sensor boundary (ADP-020).\n *\n * Capacity is observed, never inferred: a sensor reports what its telemetry\n * actually shows (used/remaining ratios, retry-after, reset time) and grades\n * its own confidence. A `null` reading or assessment means \"no trustworthy\n * estimate\" — callers must treat that as unknown, never as healthy. Provider\n * specific sensing (passive Codex headers, optional quota endpoints) lives in\n * adapters; this module owns the boundary type, the deterministic merge of\n * concurrent readings for one resource, and the derivation of the\n * draining/exhausted signals consumed by the health layer (ADP-021).\n */\nimport type { ResourceKey } from \"../resource-health/types.js\"\n\nexport const CONFIDENCE_LEVELS = [\"low\", \"medium\", \"high\"] as const satisfies readonly string[]\n\n/** How much a sensor trusts its own numbers. `high` is required for draining. */\nexport type Confidence = (typeof CONFIDENCE_LEVELS)[number]\n\n/**\n * One observation of a resource's capacity. Ratios are fractions in [0, 1].\n * A reading may carry any subset of the measured fields (e.g. a header that\n * only reports a Retry-After); a reading with none of them carries no\n * information and is discarded. `observedAt` is when the underlying telemetry\n * was seen, not when the sensor was asked.\n */\nexport interface CapacityReading {\n readonly usedRatio?: number | undefined\n readonly remainingRatio?: number | undefined\n readonly retryAfterMs?: number | undefined\n /** Epoch milliseconds at which capacity is expected to reset. */\n readonly resetAt?: number | undefined\n readonly confidence: Confidence\n readonly observedAt: number\n /** Bounded, secret-free label of the data source (e.g. a header name). */\n readonly evidence?: string | undefined\n}\n\n/** A source of capacity observations for exactly one resource. */\nexport interface CapacitySensor {\n readonly id: string\n readonly resource: ResourceKey\n /**\n * Returns the latest reading, or `null` when the sensor has no trustworthy\n * estimate. Expected \"no data\" must be returned as `null`, never thrown;\n * the registry still guards against throws (fail-open: a failing sensor is\n * no estimate, not an error).\n */\n read(): Promise<CapacityReading | null>\n}\n\nexport interface CapacityConfig {\n /** Readings older than this are treated as absent (no estimate). */\n readonly maxAgeMs: number\n /**\n * Near-exhaustion bound at or below which high-confidence evidence marks\n * the resource `draining` (ADP-021). A fixed product constant, deliberately\n * not user-configurable — no threshold sliders.\n */\n readonly drainingRemainingThreshold: number\n}\n\nexport const DEFAULT_CAPACITY_CONFIG: CapacityConfig = {\n maxAgeMs: 60_000,\n drainingRemainingThreshold: 0.1,\n}\n\n/** Drain/exhaust derivation for a merged reading. */\nexport interface CapacitySignals {\n readonly exhausted: boolean\n readonly draining: boolean\n}\n\n/**\n * Scheduler-facing view for one resource. `none` is the explicit \"no\n * estimate\" answer — unknown capacity, not zero capacity.\n */\nexport type CapacityAssessment =\n | { readonly kind: \"none\" }\n | {\n readonly kind: \"estimate\"\n readonly reading: CapacityReading\n readonly signals: CapacitySignals\n }\n","/**\n * Deterministic capacity merge semantics (ADP-020).\n *\n * Several sensors may observe the same resource (e.g. passive headers and an\n * optional quota endpoint). The merge picks one coherent story instead of\n * synthesizing chimera numbers: readings are prioritized by confidence, then\n * by conservativeness (lower remaining ratio first), then by input order, and\n * each measured field is taken from the first reading in priority order that\n * supplies it. Trust is reduced, never amplified:\n *\n * - the merged confidence is the LOWEST confidence among all surviving fresh\n * readings, because any concurrent contradictory observation unsettles the\n * whole picture (a sensor that merely corroborates still shares its doubt);\n * - `observedAt` is the oldest surviving observation, so the merged reading\n * ages honestly;\n * - `evidence` follows the base (highest-priority) reading, which owns the\n * merged story.\n *\n * Exact bounds are facts, not estimates: `remainingRatio === 0` or\n * `usedRatio === 1` signals exhaustion at any confidence, while the softer\n * `draining` signal requires `high` confidence (ADP-021). Anything that is\n * not a well-formed measurement is rejected — untrusted data becomes \"no\n * estimate\", never a guess.\n */\nimport type { HealthEvent, ResourceKey } from \"../resource-health/types.js\"\nimport {\n CONFIDENCE_LEVELS,\n type CapacityConfig,\n type CapacityReading,\n type CapacitySignals,\n DEFAULT_CAPACITY_CONFIG,\n type Confidence,\n} from \"./types.js\"\n\n/** Evidence labels are bounded so unbounded header text cannot be persisted. */\nexport const MAX_EVIDENCE_LENGTH = 128\n\nexport function confidenceRank(confidence: Confidence): number {\n return CONFIDENCE_LEVELS.indexOf(confidence)\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value)\n}\n\nfunction isValidRatio(value: unknown): value is number {\n return isFiniteNumber(value) && value >= 0 && value <= 1\n}\n\n/**\n * Re-validates a reading field by field. A reading with an invalid ratio is\n * rejected entirely (its numbers cannot be partially trusted); invalid\n * `retryAfterMs`/`resetAt` values only drop their own field. A reading with\n * no measured field left is discarded as pure noise.\n */\nexport function normalizeReading(reading: unknown): CapacityReading | null {\n if (typeof reading !== \"object\" || reading === null) {\n return null\n }\n const candidate = reading as CapacityReading\n if (!CONFIDENCE_LEVELS.includes(candidate.confidence)) {\n return null\n }\n if (!isFiniteNumber(candidate.observedAt) || candidate.observedAt < 0) {\n return null\n }\n if (\n (candidate.usedRatio !== undefined && !isValidRatio(candidate.usedRatio)) ||\n (candidate.remainingRatio !== undefined && !isValidRatio(candidate.remainingRatio))\n ) {\n return null\n }\n const retryAfterMs =\n candidate.retryAfterMs !== undefined &&\n isFiniteNumber(candidate.retryAfterMs) &&\n Number.isInteger(candidate.retryAfterMs) &&\n candidate.retryAfterMs >= 0\n ? candidate.retryAfterMs\n : undefined\n const resetAt =\n isFiniteNumber(candidate.resetAt) && candidate.resetAt >= 0 ? candidate.resetAt : undefined\n const evidence =\n typeof candidate.evidence === \"string\"\n ? candidate.evidence.slice(0, MAX_EVIDENCE_LENGTH)\n : undefined\n if (\n candidate.usedRatio === undefined &&\n candidate.remainingRatio === undefined &&\n retryAfterMs === undefined &&\n resetAt === undefined\n ) {\n return null\n }\n return {\n ...(candidate.usedRatio !== undefined ? { usedRatio: candidate.usedRatio } : {}),\n ...(candidate.remainingRatio !== undefined ? { remainingRatio: candidate.remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence: candidate.confidence,\n observedAt: candidate.observedAt,\n ...(evidence !== undefined ? { evidence } : {}),\n }\n}\n\nfunction isFresh(reading: CapacityReading, now: number, config: CapacityConfig): boolean {\n return now - reading.observedAt <= config.maxAgeMs\n}\n\n/**\n * Strict priority between two readings: higher confidence wins; on equal\n * confidence the more conservative remaining ratio wins (a missing remaining\n * ratio cannot prove scarcity, so it counts as the least conservative value).\n * Equal readings keep their relative order.\n */\nfunction strictlyHigherPriority(candidate: CapacityReading, incumbent: CapacityReading): boolean {\n const byConfidence = confidenceRank(candidate.confidence) - confidenceRank(incumbent.confidence)\n if (byConfidence !== 0) {\n return byConfidence > 0\n }\n const candidateRemaining = candidate.remainingRatio ?? 1\n const incumbentRemaining = incumbent.remainingRatio ?? 1\n return candidateRemaining < incumbentRemaining\n}\n\n/**\n * Merges concurrent readings for one resource. Returns `null` when nothing\n * survives normalization and the freshness window — an explicit \"no estimate\".\n *\n * Selection runs over the input order with a strict priority comparator, so\n * ties keep the earliest reading and both comparator outcomes stay reachable.\n */\nexport function mergeReadings(\n readings: readonly CapacityReading[],\n now: number,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacityReading | null {\n const survivors = readings\n .map(normalizeReading)\n .filter((reading): reading is CapacityReading => reading !== null)\n .filter((reading) => isFresh(reading, now, config))\n if (survivors.length === 0) {\n return null\n }\n const base = survivors.reduce((best, reading) =>\n strictlyHigherPriority(reading, best) ? reading : best,\n )\n const bestField = <T>(pick: (reading: CapacityReading) => T | undefined): T | undefined => {\n let best: CapacityReading | undefined\n let bestValue: T | undefined\n for (const reading of survivors) {\n const value = pick(reading)\n if (value === undefined) {\n continue\n }\n if (best === undefined || strictlyHigherPriority(reading, best)) {\n best = reading\n bestValue = value\n }\n }\n return bestValue\n }\n const usedRatio = bestField((reading) => reading.usedRatio)\n const remainingRatio = bestField((reading) => reading.remainingRatio)\n const retryAfterMs = bestField((reading) => reading.retryAfterMs)\n const resetAt = bestField((reading) => reading.resetAt)\n const confidence = survivors.reduce<Confidence>(\n (lowest, reading) =>\n confidenceRank(reading.confidence) < confidenceRank(lowest) ? reading.confidence : lowest,\n base.confidence,\n )\n const observedAt = Math.min(...survivors.map((reading) => reading.observedAt))\n return {\n ...(usedRatio !== undefined ? { usedRatio } : {}),\n ...(remainingRatio !== undefined ? { remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n ...(base.evidence !== undefined ? { evidence: base.evidence } : {}),\n }\n}\n\n/**\n * Drain/exhaust derivation. Exhaustion is signaled by exact bounds at any\n * confidence (a header stating zero remaining is a fact, not a guess);\n * draining additionally requires `high` confidence because it withdraws new\n * work before hard evidence exists (ADP-021).\n */\nexport function capacitySignals(\n reading: CapacityReading,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacitySignals {\n const exhausted = reading.remainingRatio === 0 || reading.usedRatio === 1\n const draining =\n !exhausted &&\n reading.confidence === \"high\" &&\n ((reading.remainingRatio !== undefined &&\n reading.remainingRatio <= config.drainingRemainingThreshold) ||\n (reading.usedRatio !== undefined &&\n reading.usedRatio >= 1 - config.drainingRemainingThreshold))\n return { exhausted, draining }\n}\n\n/**\n * Pure bridge to the health layer: converts a merged reading into the\n * capacity event consumed by resource-health transitions (ADP-021). The\n * scheduler wiring decides when to observe it; this function only shapes it.\n */\nexport function capacityHealthEvent(key: ResourceKey, reading: CapacityReading): HealthEvent {\n return {\n kind: \"capacity\",\n key,\n exhausted: capacitySignals(reading).exhausted,\n ...(reading.retryAfterMs !== undefined ? { retryAfterMs: reading.retryAfterMs } : {}),\n }\n}\n","/**\n * Maps a classified failure onto the resource scope it actually blocks.\n */\nimport type { FailureClassification } from \"../classifier/types.js\"\nimport type { HealthEvent, ResourceKey } from \"./types.js\"\n\n/** Quota survives variantless host resolution; only shared-limit evidence blocks siblings. */\nexport function failureKey(key: ResourceKey, classification: FailureClassification): ResourceKey {\n if (classification.quotaScope === \"provider\") {\n // Host model refs expose the configured provider, not a credential/account id.\n return { providerID: key.providerID }\n }\n if (classification.category === \"quota_exhausted\" && key.variantID !== undefined) {\n return { providerID: key.providerID, modelID: key.modelID }\n }\n return key\n}\n\n/** Health failure event from a classification (bounded structured evidence). */\nexport function failureEvent(key: ResourceKey, classification: FailureClassification): HealthEvent {\n return {\n kind: \"failure\",\n key: failureKey(key, classification),\n category: classification.category,\n definitive: classification.definitive,\n ...(classification.retry.retryAfterMs !== undefined\n ? { retryAfterMs: classification.retry.retryAfterMs }\n : {}),\n }\n}\n","/**\n * Pure resource health transitions (ADP-007, ADP-012, ADP-019, ADP-021).\n *\n * `applyHealthEvent` is the single authority for how evidence changes a\n * resource record: total, synchronous, and clock-free (`now` is injected).\n *\n * Policy notes:\n * - Rate limiting and quota exhaustion set their own windowed states, always\n * bounded (a default window when the evidence names no reset);\n * a windowed state is never downgraded by weaker evidence (a 429 while\n * quota-exhausted does not erase the quota signal).\n * - Outage, overload, and timeout count toward the circuit breaker and mark\n * the resource degraded. They never hard-quarantine on their own: a single\n * definitive outage signal can be a blip, so the breaker owns transient\n * failure quarantine with backoff windows and probe recovery.\n * - Definitive configuration failures (auth, invalid model) hard-quarantine\n * the resource: the evidence proves the resource cannot work. Non-definitive\n * evidence of the same categories (the textual last resort, ADP-008) is\n * transient and breaker-owned instead — one fuzzy substring in an error\n * body must never permanently blacklist a resource with no recovery path\n * (ADP-012).\n * - The `definitive` flag otherwise guides scheduling deference, not health:\n * both definitive and non-definitive infra failures leave the resource\n * degraded.\n * - Ambiguous or request-level failures (context overflow, content policy,\n * user cancellation, unknown) never change health: they say nothing about\n * the resource.\n * - Draining is a policy request (ADP-021), not degraded health: it applies\n * on top of healthy/degraded and never masks a harder state.\n */\nimport {\n recordBreakerFailure,\n recordBreakerSuccess,\n initialBreaker,\n} from \"../circuit-breaker/breaker.js\"\nimport type { BreakerRecord } from \"../circuit-breaker/types.js\"\nimport { resourceScope } from \"./key.js\"\nimport type { HealthEvent, ResourceHealthConfig, ResourceKey, ResourceRecord } from \"./types.js\"\n\nexport function initialRecord(key: ResourceKey, now: number): ResourceRecord {\n return { key, health: \"healthy\", breaker: initialBreaker(), updatedAt: now }\n}\n\n/**\n * Elapses time-bounded windows: once a window's `until` passes, the windowed\n * state (rate limited, quota exhausted) lifts back to healthy. Records\n * without a window, or with one still in the future, pass through unchanged.\n */\nexport function sweepRecord(record: ResourceRecord, now: number): ResourceRecord {\n const window = record.window\n if (window === undefined || now < window.until) {\n return record\n }\n return { key: record.key, health: \"healthy\", breaker: record.breaker, updatedAt: now }\n}\n\nfunction touched(record: ResourceRecord, now: number): ResourceRecord {\n return { ...record, updatedAt: now }\n}\n\n/**\n * Defensive re-validation of a parsed retry delay: the classifier already\n * rejects malformed values, but the health layer never trusts a negative or\n * fractional delay to compute a window.\n */\nfunction validRetryAfterMs(value: number | undefined): number | undefined {\n return value !== undefined && Number.isInteger(value) && value >= 0 ? value : undefined\n}\n\nfunction quotaExhausted(\n record: ResourceRecord,\n retryAfterMs: number | undefined,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n const until = now + (validRetryAfterMs(retryAfterMs) ?? config.defaultQuotaWindowMs)\n return { ...record, health: \"quota_exhausted\", window: { kind: \"quota\", until }, updatedAt: now }\n}\n\nfunction failureEvent(\n record: ResourceRecord,\n event: Extract<HealthEvent, { kind: \"failure\" }>,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n switch (event.category) {\n case \"rate_limited\": {\n if (record.health === \"quota_exhausted\" || record.health === \"unavailable\") {\n return touched(record, now)\n }\n const retryAfterMs = validRetryAfterMs(event.retryAfterMs)\n const until = now + (retryAfterMs ?? config.defaultRateLimitWindowMs)\n return {\n ...record,\n health: \"rate_limited\",\n window: { kind: \"rate-limit\", until },\n updatedAt: now,\n }\n }\n case \"quota_exhausted\": {\n if (record.health === \"unavailable\") {\n return touched(record, now)\n }\n return quotaExhausted(record, event.retryAfterMs, now, config)\n }\n case \"outage\":\n case \"overload\":\n case \"timeout\": {\n const breaker = recordBreakerFailure(record.breaker, event.category, now, config.breaker)\n const health =\n record.health === \"healthy\" || record.health === \"draining\" ? \"degraded\" : record.health\n return { ...record, health, breaker: breaker.record, updatedAt: now }\n }\n case \"auth_failure\":\n case \"invalid_model\": {\n // An invalid model says nothing about the provider or account; only\n // model-scoped and variant-scoped keys may be quarantined by it.\n if (event.category === \"invalid_model\") {\n const scope = resourceScope(record.key)\n if (scope !== \"model\" && scope !== \"variant\") {\n return touched(record, now)\n }\n }\n if (!event.definitive) {\n // Non-definitive evidence (bounded-textual last resort) is not proof\n // the resource cannot work: quarantine through the breaker's bounded\n // failure counting instead of a windowless, unrecoverable state.\n const breaker = recordBreakerFailure(record.breaker, event.category, now, config.breaker)\n const health =\n record.health === \"healthy\" || record.health === \"draining\" ? \"degraded\" : record.health\n return { ...record, health, breaker: breaker.record, updatedAt: now }\n }\n return { ...record, health: \"unavailable\", updatedAt: now }\n }\n default:\n // context_overflow, content_policy, user_cancelled, unknown:\n // request-level evidence, not resource health.\n return touched(record, now)\n }\n}\n\nexport function applyHealthEvent(\n record: ResourceRecord,\n event: HealthEvent,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n switch (event.kind) {\n case \"failure\":\n return failureEvent(record, event, now, config)\n case \"success\": {\n const breaker: BreakerRecord = recordBreakerSuccess()\n const health =\n record.health === \"draining\" || record.health === \"quota_exhausted\"\n ? record.health\n : \"healthy\"\n return {\n ...record,\n health,\n breaker,\n window: health === record.health ? record.window : undefined,\n updatedAt: now,\n }\n }\n case \"drain\": {\n const health =\n record.health === \"healthy\" || record.health === \"degraded\" ? \"draining\" : record.health\n return { ...record, health, updatedAt: now }\n }\n case \"capacity\": {\n if (event.exhausted) {\n if (record.health === \"unavailable\") {\n return touched(record, now)\n }\n return quotaExhausted(record, event.retryAfterMs, now, config)\n }\n const health = record.health === \"quota_exhausted\" ? \"healthy\" : record.health\n return {\n ...record,\n health,\n window: health === record.health ? record.window : undefined,\n updatedAt: now,\n }\n }\n case \"reset\":\n return { key: record.key, health: \"healthy\", breaker: initialBreaker(), updatedAt: now }\n }\n}\n","/**\n * Resource health registry (ADP-007, ADP-019, ADP-021).\n *\n * Stateful façade over the pure transition layer: one record per resource\n * key, an injected clock, and assessment that composes the record's chain of\n * ancestor scopes. Time only advances through the injected clock — there are\n * no timers; windows and breaker backoffs are evaluated (swept) lazily on\n * every observation, assessment, and snapshot.\n *\n * The single-probe guarantee (ADP-019) lives here: `assess` synchronously\n * flips a due open breaker to half-open and issues the probe ticket, so\n * concurrent assessors can never observe two admissions.\n */\nimport {\n admitProbe,\n breakerBlockWait,\n expireProbe,\n recordProbeFailure,\n recordProbeSuccess,\n releaseProbe,\n} from \"../circuit-breaker/breaker.js\"\nimport { resourceChain, resourceKeyID } from \"./key.js\"\nimport { applyHealthEvent, initialRecord, sweepRecord } from \"./transitions.js\"\nimport {\n DEFAULT_HEALTH_CONFIG,\n type Assessment,\n type Clock,\n type HealthEvent,\n type ProbeOutcome,\n type ProbeTicket,\n type ResourceHealthConfig,\n type ResourceKey,\n type ResourceRecord,\n} from \"./types.js\"\n\n/**\n * Severity of the three hard resource states. Used only to choose which\n * blocker a report names when several scopes in a chain are blocked at once;\n * every candidate still blocks regardless of which wins the report.\n */\nconst HARD_BLOCK_SEVERITY = {\n unavailable: 3,\n \"quota-exhausted\": 2,\n \"rate-limited\": 1,\n} as const\n\ntype HardBlockReason = keyof typeof HARD_BLOCK_SEVERITY\n\ninterface HardBlock {\n readonly reason: HardBlockReason\n readonly key: ResourceKey\n readonly retryAtMs: number | undefined\n readonly severity: number\n}\n\nfunction blocked(\n reason: HardBlockReason,\n key: ResourceKey,\n retryAtMs: number | undefined,\n): Assessment\nfunction blocked(reason: \"breaker-open\", key: ResourceKey, retryAtMs: number): Assessment\nfunction blocked(\n reason: \"probe-in-flight\" | \"draining\",\n key: ResourceKey,\n retryAtMs: undefined,\n): Assessment\nfunction blocked(\n reason: HardBlockReason | \"breaker-open\" | \"probe-in-flight\" | \"draining\",\n key: ResourceKey,\n retryAtMs: number | undefined,\n): Assessment {\n if (retryAtMs === undefined) {\n return { kind: \"blocked\", reason, key }\n }\n return { kind: \"blocked\", reason, key, retryAtMs }\n}\n\nfunction hardBlocker(record: ResourceRecord, now: number): HardBlock | undefined {\n const retryAtMs = record.window === undefined ? undefined : record.window.until - now\n switch (record.health) {\n case \"unavailable\":\n return {\n reason: \"unavailable\",\n key: record.key,\n retryAtMs: undefined,\n severity: HARD_BLOCK_SEVERITY.unavailable,\n }\n case \"quota_exhausted\":\n return {\n reason: \"quota-exhausted\",\n key: record.key,\n retryAtMs,\n severity: HARD_BLOCK_SEVERITY[\"quota-exhausted\"],\n }\n case \"rate_limited\":\n return {\n reason: \"rate-limited\",\n key: record.key,\n retryAtMs,\n severity: HARD_BLOCK_SEVERITY[\"rate-limited\"],\n }\n default:\n return undefined\n }\n}\n\n/** Most severe hard block across a chain; narrowest scope wins ties. */\nfunction hardest(\n records: readonly (ResourceRecord | undefined)[],\n now: number,\n): HardBlock | undefined {\n let hard: HardBlock | undefined\n for (const record of records) {\n if (record === undefined) {\n continue\n }\n const candidate = hardBlocker(record, now)\n if (candidate === undefined) {\n continue\n }\n if (hard === undefined || candidate.severity >= hard.severity) {\n hard = candidate\n }\n }\n return hard\n}\n\nexport class ResourceHealthRegistry {\n readonly #records = new Map<string, ResourceRecord>()\n readonly #clock: Clock\n readonly #config: ResourceHealthConfig\n readonly #newProbeId: () => string\n\n /**\n * `newProbeId` must be unique across every instance that shares records\n * (see `restore`); a per-instance counter suffices for a single owner.\n */\n constructor(\n clock: Clock,\n config: ResourceHealthConfig = DEFAULT_HEALTH_CONFIG,\n newProbeId?: () => string,\n ) {\n this.#clock = clock\n this.#config = config\n let counter = 0\n this.#newProbeId =\n newProbeId ??\n (() => {\n counter += 1\n return String(counter)\n })\n }\n\n /**\n * Replaces the registry's view with records another live instance shares\n * (one process per host session, all reading one locked file). Unlike\n * `hydrate`, an in-flight probe is kept: its owner is alive and will report\n * the outcome, and a lost owner is still bounded by the probe timeout.\n */\n restore(records: readonly ResourceRecord[]): void {\n const now = this.#clock()\n this.#records.clear()\n for (const record of records) {\n this.#records.set(resourceKeyID(record.key), sweepRecord(record, now))\n }\n }\n\n /**\n * Seeds the registry from persisted records (restart / cross-instance\n * reload). Records are swept against the current clock and inserted\n * without persisting — hydration must not write back what it just read.\n * A hydrated half_open record cannot keep its probe (the ticket lived in\n * the previous instance's memory), so it re-opens due immediately — its\n * backoff window had already elapsed when it went half-open, and the next\n * assessment admits exactly one probe as usual.\n */\n hydrate(records: readonly ResourceRecord[]): void {\n const now = this.#clock()\n for (const record of records) {\n const swept = sweepRecord(record, now)\n const breaker =\n swept.breaker.state === \"half_open\"\n ? {\n state: \"open\" as const,\n failures: swept.breaker.failures,\n openCount: swept.breaker.openCount,\n reopenAt: now,\n }\n : swept.breaker\n this.#records.set(resourceKeyID(swept.key), { ...swept, breaker, updatedAt: now })\n }\n }\n\n observe(event: HealthEvent): ResourceRecord {\n const now = this.#clock()\n const id = resourceKeyID(event.key)\n const existing = this.#records.get(id)\n const swept =\n existing === undefined ? initialRecord(event.key, now) : sweepRecord(existing, now)\n const updated = applyHealthEvent(swept, event, now, this.#config)\n this.#records.set(id, updated)\n return updated\n }\n\n #sweptRecord(key: ResourceKey, now: number): ResourceRecord | undefined {\n const id = resourceKeyID(key)\n const record = this.#records.get(id)\n if (record === undefined) {\n return undefined\n }\n const swept = sweepRecord(record, now)\n if (swept !== record) {\n this.#records.set(id, swept)\n }\n return swept\n }\n\n /**\n * Assesses whether the resource may take new work right now, composing the\n * full ancestor chain. Precedence: the most severe hard resource state\n * wins (narrowest scope on ties), then the breaker scan (widest scope\n * first — a due wide breaker is probed before a narrow one), then draining,\n * then available.\n */\n assess(key: ResourceKey): Assessment {\n const now = this.#clock()\n const records = resourceChain(key).map((chainKey) => this.#sweptRecord(chainKey, now))\n\n const hard = hardest(records, now)\n if (hard !== undefined) {\n return blocked(hard.reason, hard.key, hard.retryAtMs)\n }\n\n for (const record of records) {\n if (record === undefined) {\n continue\n }\n // A probe whose outcome report never arrived must not wedge the\n // resource in half_open: expire it (same backoff window, no doubling)\n // before attempting admission.\n const expired = expireProbe(record.breaker, now, this.#config.breaker)\n const current =\n expired === record.breaker ? record : { ...record, breaker: expired, updatedAt: now }\n if (current !== record) {\n this.#records.set(resourceKeyID(record.key), current)\n }\n const admission = admitProbe(current.breaker, now)\n if (admission.kind === \"closed\") {\n continue\n }\n if (admission.kind === \"waiting\") {\n return blocked(\"breaker-open\", record.key, admission.retryAtMs)\n }\n if (admission.kind === \"in-flight\") {\n return blocked(\"probe-in-flight\", record.key, undefined)\n }\n const probeId = this.#newProbeId()\n this.#records.set(resourceKeyID(record.key), {\n ...record,\n breaker: { ...admission.record, probeId, probeAt: now },\n updatedAt: now,\n })\n return { kind: \"probe\", ticket: { id: probeId, key: record.key } }\n }\n\n // Draining is the softest blocker; report the narrowest draining scope.\n let draining: ResourceRecord | undefined\n for (const record of records) {\n if (record?.health === \"draining\") {\n draining = record\n }\n }\n if (draining !== undefined) {\n return blocked(\"draining\", draining.key, undefined)\n }\n\n return { kind: \"available\" }\n }\n\n /**\n * Non-mutating assessment for decisions that must not admit a probe\n * (escalation-target gating): identical hard-state and draining walk, but\n * an open or half-open breaker blocks without being flipped or ticketed.\n */\n evaluate(key: ResourceKey): Assessment {\n const now = this.#clock()\n const records = resourceChain(key).map((chainKey) => this.#sweptRecord(chainKey, now))\n const hard = hardest(records, now)\n if (hard !== undefined) {\n return blocked(hard.reason, hard.key, hard.retryAtMs)\n }\n for (const record of records) {\n if (record === undefined) continue\n // Observer view (non-mutating): an open breaker blocks even when its\n // backoff elapsed — assess is what flips it to half_open and issues\n // the probe ticket.\n const wait = breakerBlockWait(record.breaker, now)\n if (wait !== undefined) {\n return blocked(\"breaker-open\", record.key, wait)\n }\n if (record.breaker.state === \"half_open\") {\n return blocked(\"probe-in-flight\", record.key, undefined)\n }\n }\n let draining: ResourceRecord | undefined\n for (const record of records) {\n if (record?.health === \"draining\") {\n draining = record\n }\n }\n if (draining !== undefined) {\n return blocked(\"draining\", draining.key, undefined)\n }\n return { kind: \"available\" }\n }\n\n /**\n * Reports the outcome of an admitted probe. Only the ticket issued for the\n * current half-open record is honored; stale tickets (probe already\n * resolved, record reset, or unknown key) are rejected.\n */\n reportProbe(ticket: ProbeTicket, outcome: ProbeOutcome): boolean {\n const now = this.#clock()\n const id = resourceKeyID(ticket.key)\n const record = this.#records.get(id)\n if (record === undefined) {\n return false\n }\n const breaker = record.breaker\n if (breaker.state !== \"half_open\" || breaker.probeId !== ticket.id) {\n return false\n }\n const next = outcome.success\n ? recordProbeSuccess(breaker)\n : recordProbeFailure(breaker, outcome.category, now, this.#config.breaker)\n this.#records.set(id, { ...record, breaker: next, updatedAt: now })\n return true\n }\n\n /**\n * Returns an admitted-but-never-dispatched probe ticket: the breaker\n * reopens still due, so the next admission can issue a fresh probe. Same\n * stale-ticket rule as `reportProbe`.\n */\n releaseProbe(ticket: ProbeTicket): boolean {\n const id = resourceKeyID(ticket.key)\n const record = this.#records.get(id)\n if (record?.breaker.state !== \"half_open\" || record.breaker.probeId !== ticket.id) {\n return false\n }\n this.#records.set(id, {\n ...record,\n breaker: releaseProbe(record.breaker),\n updatedAt: this.#clock(),\n })\n return true\n }\n\n /** Current (swept) record for one key, if the registry tracks it. */\n recordFor(key: ResourceKey): ResourceRecord | undefined {\n return this.#sweptRecord(key, this.#clock())\n }\n\n /** All tracked records, swept against the clock. */\n snapshot(): ResourceRecord[] {\n const now = this.#clock()\n return [...this.#records.values()].map((record) => sweepRecord(record, now))\n }\n}\n","/**\n * Read-side parsing for persisted health records. Every parser is total: it\n * accepts `unknown` and returns typed records, dropping anything invalid — a\n * corrupted health file can never take the plugin down (ADP-031). State and\n * breaker vocabularies are membership-checked; timestamps must be finite\n * numbers. An older plugin reading newer records may drop unknown-vocabulary\n * entries — health records are bounded mirrors of an in-memory registry, and\n * the payload version guards the schema itself.\n */\nimport { BREAKER_STATES } from \"../../health/circuit-breaker/types.js\"\nimport type { BreakerRecord } from \"../../health/circuit-breaker/types.js\"\nimport { HEALTH_STATES } from \"../../health/resource-health/types.js\"\nimport type {\n ResourceKey,\n ResourceRecord,\n ResourceWindow,\n} from \"../../health/resource-health/types.js\"\nimport { HEALTH_VERSION } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\nfunction isNonNegativeInt(raw: unknown): raw is number {\n return isFiniteNumber(raw) && Number.isInteger(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\n/**\n * A non-empty bounded identifier string (provider/model/variant/account ids).\n * Over-long values are rejected, not truncated: the writer stores keys as-is,\n * so a truncated key would name a different resource.\n */\nfunction parseIdentifier(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || raw === \"\" || raw.length > 128) return undefined\n return raw\n}\n\nfunction parseKey(raw: unknown): ResourceKey | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = parseIdentifier(raw[\"providerID\"])\n if (providerID === undefined) return undefined\n const accountID = parseIdentifier(raw[\"accountID\"])\n const modelID = parseIdentifier(raw[\"modelID\"])\n const variantID = parseIdentifier(raw[\"variantID\"])\n // A present-but-unusable scope field would silently widen the key.\n if (raw[\"accountID\"] !== undefined && accountID === undefined) return undefined\n if (raw[\"modelID\"] !== undefined && modelID === undefined) return undefined\n if (raw[\"variantID\"] !== undefined && variantID === undefined) return undefined\n // Scope fields must form a valid prefix: a variant without a model, or a\n // model without its variant's provider context, is not a real resource.\n if (variantID !== undefined && modelID === undefined) return undefined\n return {\n providerID,\n ...(accountID !== undefined ? { accountID } : {}),\n ...(modelID !== undefined ? { modelID } : {}),\n ...(variantID !== undefined ? { variantID } : {}),\n }\n}\n\nfunction parseBreaker(raw: unknown): BreakerRecord | undefined {\n if (!isRecord(raw)) return undefined\n const state = parseVocab(raw[\"state\"], BREAKER_STATES)\n const failures = raw[\"failures\"]\n const openCount = raw[\"openCount\"]\n if (state === undefined) return undefined\n if (!(isNonNegativeInt(failures) && isNonNegativeInt(openCount))) return undefined\n const reopenAt = raw[\"reopenAt\"]\n const probeId = parseIdentifier(raw[\"probeId\"])\n const probeAt = raw[\"probeAt\"]\n return {\n state,\n failures,\n openCount,\n ...(isFiniteNumber(reopenAt) ? { reopenAt } : {}),\n ...(probeId !== undefined ? { probeId } : {}),\n ...(isFiniteNumber(probeAt) ? { probeAt } : {}),\n }\n}\n\nfunction parseWindow(raw: unknown): ResourceWindow | undefined {\n if (!isRecord(raw)) return undefined\n const kind = parseVocab(raw[\"kind\"], [\"rate-limit\", \"quota\"] as const)\n const until = raw[\"until\"]\n if (kind === undefined || !isFiniteNumber(until)) return undefined\n return { kind, until }\n}\n\nfunction parseRecord(raw: unknown): ResourceRecord | undefined {\n if (!isRecord(raw)) return undefined\n const key = parseKey(raw[\"key\"])\n const health = parseVocab(raw[\"health\"], HEALTH_STATES)\n const breaker = parseBreaker(raw[\"breaker\"])\n const updatedAt = raw[\"updatedAt\"]\n if (key === undefined || health === undefined || breaker === undefined) return undefined\n if (!isFiniteNumber(updatedAt)) return undefined\n const window = parseWindow(raw[\"window\"])\n // Windowed states lift only when their window elapses: without a valid\n // window the record would block the resource permanently, so it is dropped\n // (the resource reads as healthy until fresh evidence arrives).\n if ((health === \"rate_limited\" || health === \"quota_exhausted\") && window === undefined) {\n return undefined\n }\n return {\n key,\n health,\n breaker,\n ...(window !== undefined ? { window } : {}),\n updatedAt,\n }\n}\n\nexport function parseHealthPayload(raw: unknown): ResourceRecord[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== HEALTH_VERSION) return []\n const list = raw[\"records\"]\n if (!Array.isArray(list)) return []\n const parsed: ResourceRecord[] = []\n for (const entry of list.slice(0, 512)) {\n const record = parseRecord(entry)\n if (record !== undefined) parsed.push(record)\n }\n return parsed\n}\n","/**\n * Bounded health-record store: a persistence mirror of the in-memory\n * resource-health registry. The store keeps the newest-updated records\n * (bounded, least-recently-updated evicted) and persists on every replace.\n * As everywhere else in `state/`, memory is only advanced after a successful\n * write, so memory and disk never diverge; write failures propagate to the\n * caller — the wiring layer's fail-open wrapper decides how to degrade\n * (ADP-031).\n */\nimport { parseHealthPayload } from \"./parse.js\"\nimport { MAX_HEALTH_RECORDS, HEALTH_VERSION } from \"./types.js\"\nimport type { HealthPayload, HealthStorage } from \"./types.js\"\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\n/**\n * The bounded record set worth persisting: the most recently updated\n * records — stale scopes matter less than the resources that are actually\n * failing right now.\n */\nexport function retainedHealthRecords(records: readonly ResourceRecord[]): ResourceRecord[] {\n return records.length > MAX_HEALTH_RECORDS\n ? [...records]\n .sort((left, right) => right.updatedAt - left.updatedAt)\n .slice(0, MAX_HEALTH_RECORDS)\n : [...records]\n}\n\nexport class HealthRecordStore {\n #records: ResourceRecord[] = []\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: HealthStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseHealthPayload(raw)\n }\n\n /** All retained records. */\n snapshot(): readonly ResourceRecord[] {\n return this.#records\n }\n\n /** Replace the whole record set with a fresh registry snapshot (bounded). */\n replace(records: readonly ResourceRecord[]): Promise<void> {\n return this.#serialize(() => this.#replace(records))\n }\n\n async #replace(records: readonly ResourceRecord[]): Promise<void> {\n const next = retainedHealthRecords(records)\n // Persist BEFORE committing memory: a write failure must leave memory\n // and disk consistent (the caller decides how to fail open).\n const payload: HealthPayload = {\n version: HEALTH_VERSION,\n records: next,\n }\n await this.storage.write(payload)\n this.#records = next\n }\n\n // Reloads and writes share one queue; otherwise a slow persistence call\n // can restore older state after a newer call has already committed.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n","// covers: [\"ADP-009\", \"ADP-010\", \"ADP-011\", \"ADP-059\"]\n/**\n * Resource health shared by every Pi process on this machine. Each\n * transaction restores the registry from the health file under its lock,\n * lets the caller assess or observe, and writes the swept snapshot back — so\n * one process's 429 steers the next admission in another, and a half-open\n * breaker admits one probe across all of them (ADP-059). No Pi imports.\n */\nimport { classifyFailure } from \"@coool/adaptive-core/health/classifier/classify\"\nimport type { FailureClassification } from \"@coool/adaptive-core/health/classifier/types\"\nimport {\n DEFAULT_HEALTH_CONFIG,\n failureEvent,\n ResourceHealthRegistry,\n} from \"@coool/adaptive-core/health/index\"\nimport type {\n Assessment,\n ProbeTicket,\n ResourceKey,\n} from \"@coool/adaptive-core/health/resource-health/types\"\nimport { schedulerHealthKey } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { retainedHealthRecords } from \"@coool/adaptive-core/state/health/store\"\nimport { HEALTH_VERSION } from \"@coool/adaptive-core/state/health/types\"\nimport { failureEvidence, type FailedMessage } from \"./evidence.js\"\nimport type { JsonFile } from \"./store.js\"\n\nexport interface SharedHealth {\n readonly file: JsonFile\n readonly clock: () => number\n /** Probe ids must be unique across every process sharing the file. */\n readonly newId: () => string\n}\n\n/** Run `change` against the shared registry and persist what it leaves behind. */\nexport function withHealth<R>(\n shared: SharedHealth,\n change: (registry: ResourceHealthRegistry) => R,\n): Promise<R> {\n return shared.file.update((current) => {\n const registry = new ResourceHealthRegistry(shared.clock, DEFAULT_HEALTH_CONFIG, shared.newId)\n registry.restore(parseHealthPayload(current))\n const result = change(registry)\n return {\n next: { version: HEALTH_VERSION, records: retainedHealthRecords(registry.snapshot()) },\n result,\n }\n })\n}\n\nfunction keyOf(ref: ModelRef): ResourceKey {\n return { providerID: ref.providerID, modelID: ref.id }\n}\n\n/**\n * Assess the candidates of one admission. Assessing a due open breaker issues\n * a probe ticket; every ticket the admission does not dispatch must be\n * handed back with `releaseUnselected`, or the probe stays in flight until it\n * times out.\n */\nexport function assessCandidates(\n registry: ResourceHealthRegistry,\n candidates: readonly ModelRef[],\n): { readonly health: Record<string, Assessment>; readonly tickets: readonly ProbeTicket[] } {\n const health: Record<string, Assessment> = {}\n const tickets: ProbeTicket[] = []\n for (const ref of candidates) {\n const assessment = registry.assess(keyOf(ref))\n health[schedulerHealthKey(ref)] = assessment\n if (assessment.kind === \"probe\") tickets.push(assessment.ticket)\n }\n return { health, tickets }\n}\n\nexport function releaseUnselected(\n registry: ResourceHealthRegistry,\n tickets: readonly ProbeTicket[],\n selected: ModelRef | undefined,\n): void {\n for (const ticket of tickets)\n if (ticket.key.providerID !== selected?.providerID || ticket.key.modelID !== selected.id)\n registry.releaseProbe(ticket)\n}\n\n/**\n * Record how one dispatched request ended. User cancellations are not\n * provider evidence. Only the dispatching process sees the outcome of a\n * half-open record, so a failure there is that probe's outcome; a success\n * closes the breaker from any state. Returns the failure classification of\n * an errored dispatch, for the receipt outcome.\n */\nexport function observeOutcome(\n registry: ResourceHealthRegistry,\n ref: ModelRef,\n message: FailedMessage,\n): FailureClassification | undefined {\n const key = keyOf(ref)\n if (message.stopReason === \"aborted\") return undefined\n if (message.stopReason !== \"error\") {\n registry.observe({ kind: \"success\", key })\n return undefined\n }\n const classification = classifyFailure(failureEvidence(message))\n const breaker = registry.recordFor(key)?.breaker\n if (breaker?.state === \"half_open\" && breaker.probeId !== undefined)\n registry.reportProbe(\n { id: breaker.probeId, key },\n { success: false, category: classification.category },\n )\n registry.observe(failureEvent(key, classification))\n return classification\n}\n","/**\n * Passive Codex/ChatGPT capacity telemetry (ADP-020).\n *\n * The only consumed evidence is the `x-codex-*` response-header family\n * (including LiteLLM's `llm_provider-x-codex-*` relay form), captured from the\n * `http.response` hook by the wiring-supplied allowlist. Verified wire facts:\n * `x-codex-primary-used-percent` (5h window), `x-codex-secondary-used-percent`\n * (weekly window), `x-codex-{primary,secondary}-window-minutes`,\n * `x-codex-{primary,secondary}-reset-after-seconds`, and\n * `x-codex-{primary,secondary}-reset-at` — where `reset-at` is documented to\n * sometimes arrive as an EMPTY STRING while `reset-after-seconds` is present.\n * Everything is validated; unparseable telemetry produces no estimate rather\n * than a guess.\n */\n\nexport const CODEX_SENSOR_ID = \"codex-headers\"\n\n/** The telemetry windows Codex headers report. Primary is the 5h window. */\nexport const CODEX_WINDOW_KINDS = [\"primary\", \"secondary\"] as const satisfies readonly string[]\n\nexport type CodexWindowKind = (typeof CODEX_WINDOW_KINDS)[number]\n\nexport interface CodexWindow {\n /** Usage percentage in [0, 100] — the window exists only if this is valid. */\n readonly usedPercent: number\n /** Validated finite non-negative seconds until reset, when reported. */\n readonly resetAfterSeconds?: number | undefined\n /** Validated finite non-negative epoch-seconds reset timestamp, when reported. */\n readonly resetAtSeconds?: number | undefined\n}\n\n/** One validated header observation. `null` windows are simply absent. */\nexport interface CodexUsage {\n readonly primary?: CodexWindow | undefined\n readonly secondary?: CodexWindow | undefined\n}\n","/**\n * Untrusted-header validation. Header values arrive from provider responses\n * (or relays); every field is parsed defensively and a window is admitted only\n * when its usage percentage is trustworthy. A usage above 100% voids the\n * snapshot rather than leaving the other window to speak for it. Reset fields that fail validation\n * are dropped field-wise — they cannot invalidate a valid percentage.\n */\nimport type { CodexUsage, CodexWindow, CodexWindowKind } from \"./types.js\"\nimport { CODEX_WINDOW_KINDS } from \"./types.js\"\n\n/**\n * LiteLLM relays Codex headers under a provider prefix, e.g.\n * `llm_provider-x-codex-primary-used-percent`. Matching on the substring keeps\n * the parser independent of which relay prefix is used.\n */\nexport const CODEX_HEADER_MARK = \"x-codex-\"\n\n/**\n * Allowlist predicate for the `http.response` capture option: matches plain\n * and LiteLLM-prefixed Codex telemetry header names (case already lowered by\n * the caller). Only quota telemetry passes — no other response header is ever\n * captured.\n */\nexport function isCodexHeaderName(lowercaseName: string): boolean {\n return lowercaseName.includes(CODEX_HEADER_MARK)\n}\n\ninterface WindowAccumulator {\n usedPercent?: number | undefined\n /** A usage above 100% was reported: the window is exhausted, not absent. */\n overshoot?: boolean | undefined\n resetAfterSeconds?: number | undefined\n resetAtSeconds?: number | undefined\n}\n\nfunction finiteAtLeast(value: string, min: number): number | undefined {\n // An empty (or whitespace-only) value must not fall through Number(\"\") === 0.\n const trimmed = value.trim()\n if (trimmed === \"\") {\n return undefined\n }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed) || parsed < min) {\n return undefined\n }\n return parsed\n}\n\nfunction emptyAccumulator(): WindowAccumulator {\n return {\n usedPercent: undefined,\n overshoot: undefined,\n resetAfterSeconds: undefined,\n resetAtSeconds: undefined,\n }\n}\n\nfunction takenValue(accumulator: WindowAccumulator, suffix: string): number | undefined {\n switch (suffix) {\n case \"used-percent\":\n return accumulator.usedPercent\n case \"reset-after-seconds\":\n return accumulator.resetAfterSeconds\n case \"reset-at\":\n return accumulator.resetAtSeconds\n default:\n return undefined\n }\n}\n\nfunction applyField(accumulator: WindowAccumulator, suffix: string, value: string): void {\n // First valid value per field wins; invalid or duplicate values are ignored.\n if (takenValue(accumulator, suffix) !== undefined) {\n return\n }\n switch (suffix) {\n case \"used-percent\": {\n // The percentage is the window's existence test: out of range or\n // unparseable values never admit a window.\n const usedPercent = finiteAtLeast(value, 0)\n if (usedPercent === undefined) {\n return\n }\n if (usedPercent > 100) {\n accumulator.overshoot = true\n return\n }\n accumulator.usedPercent = usedPercent\n return\n }\n case \"reset-after-seconds\": {\n const resetAfterSeconds = finiteAtLeast(value, 0)\n if (resetAfterSeconds !== undefined) {\n accumulator.resetAfterSeconds = resetAfterSeconds\n }\n return\n }\n case \"reset-at\": {\n // Documented wire quirk: reset-at can be an empty string while\n // reset-after-seconds carries the real value. Empty and unparseable\n // values are dropped, never guessed at.\n const resetAtSeconds = finiteAtLeast(value, 0)\n if (resetAtSeconds !== undefined) {\n accumulator.resetAtSeconds = resetAtSeconds\n }\n return\n }\n default:\n // window-minutes and unknown suffixes carry no reading information.\n return\n }\n}\n\nfunction windowOf(accumulator: WindowAccumulator): CodexWindow | undefined {\n const usedPercent = accumulator.usedPercent\n if (usedPercent === undefined) {\n return undefined\n }\n const { resetAfterSeconds, resetAtSeconds } = accumulator\n return {\n usedPercent,\n ...(resetAfterSeconds !== undefined ? { resetAfterSeconds } : {}),\n ...(resetAtSeconds !== undefined ? { resetAtSeconds } : {}),\n }\n}\n\n/**\n * Parse captured response headers into a validated usage snapshot. Header\n * lookup is case-insensitive and accepts LiteLLM-prefixed names; fields\n * accumulate per window in any order. Returns `null` when no window carries a\n * trustworthy usage percentage.\n */\nexport function parseCodexUsage(captured: Readonly<Record<string, string>>): CodexUsage | null {\n const accumulators: Record<CodexWindowKind, WindowAccumulator | undefined> = {\n primary: undefined,\n secondary: undefined,\n }\n for (const [rawName, value] of Object.entries(captured)) {\n const mark = rawName.toLowerCase().indexOf(CODEX_HEADER_MARK)\n if (mark < 0) {\n continue\n }\n const rest = rawName.slice(mark + CODEX_HEADER_MARK.length).toLowerCase()\n const separator = rest.indexOf(\"-\")\n const kind = rest.slice(0, separator)\n if (!(CODEX_WINDOW_KINDS as readonly string[]).includes(kind)) {\n continue\n }\n const key = kind as CodexWindowKind\n const accumulator = accumulators[key] ?? emptyAccumulator()\n applyField(accumulator, rest.slice(separator + 1), value)\n accumulators[key] = accumulator\n }\n // An overshooting window is exhausted, yet its percentage is not\n // trustworthy: dropping just that window would let the other one present\n // the subscription as usable, so the whole snapshot is void.\n if (accumulators.primary?.overshoot === true || accumulators.secondary?.overshoot === true) {\n return null\n }\n const primary = windowOf(accumulators.primary ?? emptyAccumulator())\n const secondary = windowOf(accumulators.secondary ?? emptyAccumulator())\n if (primary === undefined && secondary === undefined) {\n return null\n }\n return {\n ...(primary !== undefined ? { primary } : {}),\n ...(secondary !== undefined ? { secondary } : {}),\n }\n}\n","/**\n * Codex usage → `CapacityReading` conversion. The binding constraint is the\n * most-consumed window (ties read the primary window, deterministic). Ratios\n * are exact percent/100 fractions; the reset timestamp is anchored to when the\n * headers were observed, preferring the relative `reset-after-seconds` over\n * the absolute `reset-at` epoch-seconds field.\n *\n * Confidence grades telemetry completeness: a binding window with BOTH a\n * usage percentage and a validated reset field is `high` (self-consistent,\n * provider-generated, actionable for draining); a percentage alone is\n * `medium`. An usage snapshot with no window at all yields a no-measurement\n * reading that the capacity merge layer discards as pure noise.\n */\nimport type { Confidence } from \"../../health/capacity/types.js\"\nimport type { CapacityReading } from \"../../health/capacity/types.js\"\nimport type { CodexUsage, CodexWindow } from \"./types.js\"\n\nexport const CODEX_EVIDENCE = \"x-codex headers\"\n\nfunction hasReset(window: CodexWindow): boolean {\n return window.resetAfterSeconds !== undefined || window.resetAtSeconds !== undefined\n}\n\n/**\n * The window whose exhaustion binds first: higher usage wins, ties → primary.\n * Returns `undefined` only for a snapshot with no window at all.\n */\nexport function bindingWindow(usage: CodexUsage): CodexWindow | undefined {\n const primary = usage.primary\n const secondary = usage.secondary\n if (primary === undefined) {\n return secondary\n }\n if (secondary === undefined) {\n return primary\n }\n return secondary.usedPercent > primary.usedPercent ? secondary : primary\n}\n\nexport function readingFromUsage(usage: CodexUsage, observedAt: number): CapacityReading {\n const window = bindingWindow(usage)\n if (window === undefined) {\n // No measured field — the capacity merge layer rejects this as noise.\n return { confidence: \"low\", observedAt, evidence: CODEX_EVIDENCE }\n }\n const usedRatio = window.usedPercent / 100\n const remainingRatio = 1 - usedRatio\n let resetAt: number | undefined\n if (window.resetAfterSeconds !== undefined) {\n resetAt = observedAt + window.resetAfterSeconds * 1000\n } else if (window.resetAtSeconds !== undefined) {\n resetAt = window.resetAtSeconds * 1000\n }\n const confidence: Confidence = hasReset(window) ? \"high\" : \"medium\"\n return {\n usedRatio,\n remainingRatio,\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n evidence: CODEX_EVIDENCE,\n }\n}\n","/**\n * The passive-header `CapacitySensor` (ADP-020). Holds the latest validated\n * header observation; `read()` converts it to a reading. No polling, no\n * endpoint calls, no credential handling — WebSocket-backed providers bypass\n * the HTTP hook entirely (verified limitation), so this sensor reports\n * `null` (no estimate) whenever no trustworthy headers have been observed.\n * An unparseable observation CLEARS the stored usage: present-but-invalid\n * telemetry is distrust, and a stale quota estimate must never linger.\n */\nimport type { ResourceKey } from \"../../health/resource-health/types.js\"\nimport type { CapacityReading, CapacitySensor } from \"../../health/capacity/types.js\"\nimport { parseCodexUsage } from \"./parse.js\"\nimport { readingFromUsage } from \"./reading.js\"\nimport type { CodexUsage } from \"./types.js\"\nimport { CODEX_SENSOR_ID } from \"./types.js\"\n\nexport class CodexCapacitySensor implements CapacitySensor {\n readonly id = CODEX_SENSOR_ID\n readonly resource: ResourceKey\n #usage: CodexUsage | null = null\n #observedAt = 0\n\n constructor(resource: ResourceKey) {\n this.resource = resource\n }\n\n /**\n * Record one captured-header observation. Unparseable telemetry clears the\n * previous estimate instead of keeping it (present-but-invalid = distrust).\n */\n observe(captured: Readonly<Record<string, string>>, observedAt: number): void {\n this.#usage = parseCodexUsage(captured)\n if (this.#usage !== null) {\n this.#observedAt = observedAt\n }\n }\n\n read(): Promise<CapacityReading | null> {\n const usage = this.#usage\n if (usage === null) {\n return Promise.resolve(null)\n }\n return Promise.resolve(readingFromUsage(usage, this.#observedAt))\n }\n}\n","import { CONFIDENCE_LEVELS } from \"../../health/capacity/types.js\"\nimport type { CapacityReading } from \"../../health/capacity/types.js\"\nimport type { ResourceKey } from \"../../health/resource-health/types.js\"\nimport { CAPACITY_VERSION, MAX_CAPACITY_READINGS, type PersistedCapacityReading } from \"./types.js\"\n\n// Defensive readers: persisted data is untrusted. Every parser is total —\n// accepts unknown, returns typed records, and drops anything invalid — so a\n// corrupted file can never take the plugin down (ADP-031). An older plugin\n// reading a newer payload drops unknown-vocabulary entries; the version field\n// guards the schema itself.\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\n/**\n * A non-empty bounded identifier. Over-long values are rejected, not\n * truncated: the writer stores keys as-is, so a truncated key would name a\n * different resource.\n */\nfunction parseIdentifier(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || raw === \"\" || raw.length > 128) return undefined\n return raw\n}\n\nfunction parseKey(raw: unknown): ResourceKey | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = parseIdentifier(raw[\"providerID\"])\n if (providerID === undefined) return undefined\n const accountID = parseIdentifier(raw[\"accountID\"])\n const modelID = parseIdentifier(raw[\"modelID\"])\n const variantID = parseIdentifier(raw[\"variantID\"])\n // A present-but-unusable scope field would silently widen the key.\n if (raw[\"accountID\"] !== undefined && accountID === undefined) return undefined\n if (raw[\"modelID\"] !== undefined && modelID === undefined) return undefined\n if (raw[\"variantID\"] !== undefined && variantID === undefined) return undefined\n // Scope fields must form a valid prefix: a variant without a model is not\n // addressable against a model inventory and is not a real resource.\n if (variantID !== undefined && modelID === undefined) return undefined\n return {\n providerID,\n ...(accountID !== undefined ? { accountID } : {}),\n ...(modelID !== undefined ? { modelID } : {}),\n ...(variantID !== undefined ? { variantID } : {}),\n }\n}\n\nfunction parseRatio(raw: unknown): number | undefined {\n return isFiniteNumber(raw) && raw >= 0 && raw <= 1 ? raw : undefined\n}\n\nfunction parseReading(raw: unknown): CapacityReading | undefined {\n if (!isRecord(raw)) return undefined\n const confidence = CONFIDENCE_LEVELS.find((level) => level === raw[\"confidence\"])\n if (confidence === undefined) return undefined\n const observedAt = raw[\"observedAt\"]\n if (!isFiniteNumber(observedAt) || observedAt < 0) return undefined\n const usedRatio = parseRatio(raw[\"usedRatio\"])\n const remainingRatio = parseRatio(raw[\"remainingRatio\"])\n const retryAfterMs =\n isFiniteNumber(raw[\"retryAfterMs\"]) && raw[\"retryAfterMs\"] >= 0\n ? raw[\"retryAfterMs\"]\n : undefined\n const resetAt = isFiniteNumber(raw[\"resetAt\"]) && raw[\"resetAt\"] >= 0 ? raw[\"resetAt\"] : undefined\n // A reading with none of the measured fields carries no information and is\n // discarded (mirrors the domain rule in health/capacity/types.ts).\n if (\n usedRatio === undefined &&\n remainingRatio === undefined &&\n retryAfterMs === undefined &&\n resetAt === undefined\n ) {\n return undefined\n }\n const evidence = raw[\"evidence\"]\n return {\n ...(usedRatio !== undefined ? { usedRatio } : {}),\n ...(remainingRatio !== undefined ? { remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n ...(typeof evidence === \"string\" && evidence.length > 0\n ? { evidence: evidence.slice(0, 128) }\n : {}),\n }\n}\n\nfunction parseEntry(raw: unknown): PersistedCapacityReading | undefined {\n if (!isRecord(raw)) return undefined\n const key = parseKey(raw[\"key\"])\n if (key === undefined) return undefined\n const reading = parseReading(raw[\"reading\"])\n if (reading === undefined) return undefined\n return { key, reading }\n}\n\n// Every parser is total: accepts unknown, returns typed records, and drops\n// anything invalid — a corrupted file can never take the plugin down\n// (ADP-031). An older plugin reading newer records may drop\n// unknown-vocabulary entries — records are bounded mirrors of an in-memory\n// registry, and the payload version guards the schema itself.\nexport function parseCapacityPayload(raw: unknown): PersistedCapacityReading[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== CAPACITY_VERSION) return []\n if (!Array.isArray(raw[\"readings\"])) return []\n const list = raw[\"readings\"]\n const readings: PersistedCapacityReading[] = []\n for (const entry of list.slice(0, MAX_CAPACITY_READINGS)) {\n const parsed = parseEntry(entry)\n if (parsed !== undefined) readings.push(parsed)\n }\n return readings\n}\n","// covers: [\"ADP-020\", \"ADP-021\", \"ADP-031\", \"ADP-051\", \"ADP-056\", \"ADP-059\"]\nimport { isDeepStrictEqual } from \"node:util\"\nimport {\n capacitySignals,\n mergeReadings,\n normalizeReading,\n} from \"@coool/adaptive-core/health/capacity/merge\"\nimport type { CapacityReading } from \"@coool/adaptive-core/health/capacity/types\"\nimport { resourceChain, resourceKeyID } from \"@coool/adaptive-core/health/resource-health/key\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport {\n schedulerHealthKey,\n type SchedulerInput,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport {\n CodexCapacitySensor,\n isCodexHeaderName,\n} from \"@coool/adaptive-core/sensors/codex-capacity/index\"\nimport { parseCapacityPayload } from \"@coool/adaptive-core/state/capacity/parse\"\nimport {\n CAPACITY_VERSION,\n MAX_CAPACITY_READINGS,\n type PersistedCapacityReading,\n} from \"@coool/adaptive-core/state/capacity/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport interface SharedCapacity {\n readonly file: JsonFile\n readonly clock: () => number\n}\n\nexport interface CapacityView {\n readonly capacity: SchedulerInput[\"capacity\"]\n /** Fresh readings for status and reset-aware parking; null means unknown. */\n readonly readings: Readonly<Record<string, CapacityReading | null>>\n}\n\nfunction parse(raw: unknown): PersistedCapacityReading[] {\n if (raw === undefined) return []\n const readings = parseCapacityPayload(raw)\n // The core mirror reader is intentionally tolerant. A shared file must not\n // be rewritten after that reader dropped malformed fields or newer schema.\n if (!isDeepStrictEqual(raw, { version: CAPACITY_VERSION, readings }))\n throw new Error(\"Adaptive capacity: invalid capacity.json payload\")\n return readings\n}\n\nfunction capturedHeaders(raw: unknown): Record<string, string> {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw))\n throw new Error(\"Adaptive capacity: headers must be an object\")\n const headers: Record<string, string> = {}\n for (const [name, value] of Object.entries(raw)) {\n if (!isCodexHeaderName(name.toLowerCase())) continue\n if (typeof value !== \"string\")\n throw new Error(\"Adaptive capacity: Codex header values must be strings\")\n headers[name] = value\n }\n return headers\n}\n\n/**\n * Observe only a known dispatched provider, never the selected virtual model.\n * Codex limits are provider-wide. Raw headers, account ids and credentials are\n * never persisted: the core sensor emits numbers and a fixed source label.\n * Missing/invalid telemetry adds nothing; previous observations age out using\n * the same freshness rule as the core mirror.\n */\nexport async function observeCodexHeaders(\n shared: SharedCapacity,\n providerID: unknown,\n headers: unknown,\n): Promise<void> {\n try {\n if (typeof providerID !== \"string\" || providerID === \"\" || providerID.length > 128)\n throw new Error(\"Adaptive capacity: providerID must be a bounded nonempty string\")\n const sensor = new CodexCapacitySensor({ providerID })\n sensor.observe(capturedHeaders(headers), shared.clock())\n const reading = normalizeReading(await sensor.read())\n if (reading === null) return\n const entry = { key: sensor.resource, reading }\n await shared.file.update((current) => {\n // Merge inside the cross-process lock so a peer's newer observation\n // cannot be overwritten by a snapshot read before acquiring it.\n const byKey = new Map(parse(current).map((item) => [resourceKeyID(item.key), item]))\n const id = resourceKeyID(entry.key)\n const previous = byKey.get(id)\n if (previous === undefined || reading.observedAt > previous.reading.observedAt)\n byKey.set(id, entry)\n const readings = [...byKey.values()]\n .sort((a, b) => b.reading.observedAt - a.reading.observedAt)\n .slice(0, MAX_CAPACITY_READINGS)\n return { next: { version: CAPACITY_VERSION, readings }, result: undefined }\n })\n } catch {\n // Neither a header getter nor a storage adapter's exception is safe to log.\n logFailOpen(\"capacity.observe\", \"Capacity observation unavailable\")\n }\n}\n\n/** Read the shared mirror afresh; the core owns scope, freshness and draining. */\nexport async function readCapacity(\n shared: SharedCapacity,\n candidates: readonly ModelRef[],\n): Promise<CapacityView> {\n const capacity: Record<string, ReturnType<typeof capacitySignals>> = {}\n const readings: Record<string, CapacityReading | null> = {}\n for (const ref of candidates) readings[schedulerHealthKey(ref)] = null\n try {\n const entries = await shared.file.update((current) => ({\n next: undefined,\n result: parse(current),\n }))\n const now = shared.clock()\n for (const ref of candidates) {\n const chain = new Set(\n resourceChain({ providerID: ref.providerID, modelID: ref.id, variantID: ref.variant }).map(\n resourceKeyID,\n ),\n )\n const reading = mergeReadings(\n entries\n .filter((entry) => chain.has(resourceKeyID(entry.key)))\n .map((entry) => entry.reading),\n now,\n )\n const id = schedulerHealthKey(ref)\n readings[id] = reading\n if (reading !== null) capacity[id] = capacitySignals(reading)\n }\n } catch {\n logFailOpen(\"capacity.read\", \"Shared capacity unavailable\")\n }\n return { capacity, readings }\n}\n","import { observeCodexHeaders, type SharedCapacity } from \"../capacity.js\"\n\n/** Pi strips model metadata from response hooks. Overlap is not attributable. */\nexport function dispatchCapacity(shared: SharedCapacity) {\n let provider: string | undefined\n let ambiguous = false\n return {\n selected(selected: string) {\n if (provider !== undefined) ambiguous = true\n provider = selected\n },\n clear() {\n provider = undefined\n ambiguous = false\n },\n async response(headers: unknown) {\n if (!ambiguous && provider !== undefined) await observeCodexHeaders(shared, provider, headers)\n },\n }\n}\n","import { replaceControlCharacters, truncateToWidth } from \"@earendil-works/pi-tui\"\nimport { object } from \"../settings.js\"\nimport type { AdaptiveNote } from \"../ui/notes.js\"\n\nexport const NOTE_ENTRY = \"adaptive.note\"\n\ninterface NoteComponent {\n render(width: number): string[]\n invalidate(): void\n}\ninterface EntryHost {\n registerEntryRenderer(\n type: string,\n renderer: (\n entry: { readonly data?: unknown },\n options: { readonly expanded: boolean },\n theme: { fg(color: \"dim\", text: string): string },\n ) => NoteComponent | undefined,\n ): void\n}\n\n/** Sanitizes persisted/user-controlled identifiers before they reach the terminal. */\nexport function fitLine(text: string, width: number): string {\n return truncateToWidth(replaceControlCharacters(text), Math.max(0, width), \"…\")\n}\n\nexport function registerEntries(pi: EntryHost): void {\n pi.registerEntryRenderer(NOTE_ENTRY, (entry, options, theme) => {\n const data: unknown = entry.data\n if (!object(data) || data[\"version\"] !== 1 || typeof data[\"text\"] !== \"string\") return undefined\n const text = data[\"text\"]\n const id = data[\"receiptID\"]\n const detail =\n options.expanded && typeof id === \"number\" ? ` · receipt #${String(id)} · /adaptive why` : \"\"\n return {\n render: (width) => [theme.fg(\"dim\", fitLine(`Adaptive · ${text}${detail}`, width))],\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n })\n}\n\nexport function appendNote(\n pi: { appendEntry(type: string, data: AdaptiveNote): void },\n note: AdaptiveNote,\n): void {\n pi.appendEntry(NOTE_ENTRY, note)\n}\n","/**\n * Operating-mode wrapper (GOAL operating modes). OBSERVE and CONTROL run the\n * identical core; OBSERVE wraps the result without applying it. OFF never\n * reaches the scheduler, but the total wrapper maps it to an explicit defer\n * so the union stays closed.\n */\nimport type { Decision, OperatingMode } from \"./types.js\"\n\nexport function forMode(decision: Decision, mode: OperatingMode): Decision {\n if (mode === \"observe\") {\n return { kind: \"observe-only\", would: decision }\n }\n if (mode === \"active\") {\n return decision\n }\n return { kind: \"defer\", reason: \"adaptive-off\" }\n}\n","import { capacitySignals } from \"../../health/capacity/merge.js\"\nimport { DEFAULT_CAPACITY_CONFIG, type CapacityReading } from \"../../health/capacity/types.js\"\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\n/**\n * Parked-work wake planning (ADP-024): when every resource of a parked\n * unit's tier is blocked, nothing else is guaranteed to reach a safe\n * boundary again (`experimental.idle` only follows successful work), so the\n * supervisor arms one timer for the earliest moment a candidate resource\n * becomes usable. All times are epoch ms; `undefined` means \"unknown\" (no\n * stated reset — e.g. an auth quarantine or an in-flight probe).\n */\n\n/** Wake slightly after the window ends so the resource is past its reset. */\nexport const WAKE_GRACE_MS = 1_000\n/** Shortest wake delay: a due target never spins the timer. */\nexport const MIN_WAKE_MS = 1_000\n/** Re-check cadence when no candidate states when it recovers. */\nexport const UNKNOWN_WAKE_MS = 5 * 60_000\n/**\n * Longest single timer. Longer waits (weekly limits) re-arm in steps, which\n * also keeps the delay far below the 2^31 ms setTimeout overflow and\n * re-anchors the schedule after laptop sleep or wall-clock jumps.\n */\nexport const MAX_WAKE_MS = 30 * 60_000\n/** First backoff step after a wake that resumed nothing; doubles per miss. */\nexport const FRUITLESS_BASE_MS = 5_000\n\n/**\n * When one health record stops blocking admission: windowed states lift at\n * their window end, an open breaker at its reopen time. Unavailable (no\n * window, permanent until reset) and half-open (a probe decides) are unknown.\n */\nfunction recordUsableAt(record: ResourceRecord, now: number): number | undefined {\n if (record.health === \"unavailable\" || record.breaker.state === \"half_open\") {\n return undefined\n }\n let at = now\n if (record.health === \"quota_exhausted\" || record.health === \"rate_limited\") {\n if (record.window === undefined) return undefined\n at = Math.max(at, record.window.until)\n }\n if (record.breaker.state === \"open\") {\n at = Math.max(at, record.breaker.reopenAt ?? now)\n }\n return at\n}\n\n/**\n * When a resource becomes usable: the latest of its health chain (a blocked\n * ancestor blocks every descendant) and its capacity estimate. An exhausted\n * estimate clears at its stated reset or when the reading goes stale,\n * whichever comes first — stale readings stop blocking admission.\n */\nexport function resourceUsableAt(\n chain: readonly (ResourceRecord | undefined)[],\n reading: CapacityReading | null,\n now: number,\n): number | undefined {\n let at = now\n for (const record of chain) {\n if (record === undefined) continue\n const usable = recordUsableAt(record, now)\n if (usable === undefined) return undefined\n at = Math.max(at, usable)\n }\n if (reading !== null && capacitySignals(reading).exhausted) {\n const stale = reading.observedAt + DEFAULT_CAPACITY_CONFIG.maxAgeMs\n const reset = reading.resetAt ?? stale\n at = Math.max(at, Math.min(reset, stale))\n }\n return at\n}\n\n/** Earliest known time among candidates; unknown when none is known. */\nexport function earliestUsable(times: readonly (number | undefined)[]): number | undefined {\n let earliest: number | undefined\n for (const time of times) {\n if (time !== undefined && (earliest === undefined || time < earliest)) earliest = time\n }\n return earliest\n}\n\nexport interface WakePlan {\n /** When the parked work is due for a resume sweep. */\n readonly dueAt: number\n /** Timer delay; shorter than `dueAt - now` when capped by MAX_WAKE_MS. */\n readonly delayMs: number\n /**\n * Whether the timer fires before `dueAt` by design (capped delay). An\n * uncapped fire is due even when the clock reads a little early: timers\n * and wall clocks drift, and a clock stepped back must not skip the sweep.\n */\n readonly capped: boolean\n}\n\n/**\n * Plans the next wake for the parked units' resume times. `fruitless` counts\n * consecutive wake sweeps that resumed nothing: each one doubles the minimum\n * delay (capped), so a resource that looks usable but keeps refusing work\n * cannot spin the timer. No targets → no wake.\n */\nexport function planWake(\n targets: readonly (number | undefined)[],\n now: number,\n fruitless: number,\n): WakePlan | undefined {\n if (targets.length === 0) return undefined\n const known = earliestUsable(targets)\n let dueAt = known === undefined ? Number.POSITIVE_INFINITY : known + WAKE_GRACE_MS\n if (targets.includes(undefined)) dueAt = Math.min(dueAt, now + UNKNOWN_WAKE_MS)\n const floor =\n fruitless === 0 ? MIN_WAKE_MS : Math.min(MAX_WAKE_MS, FRUITLESS_BASE_MS * 2 ** (fruitless - 1))\n dueAt = Math.max(dueAt, now + floor)\n const capped = dueAt - now > MAX_WAKE_MS\n return { dueAt, delayMs: capped ? MAX_WAKE_MS : dueAt - now, capped }\n}\n","// covers: [\"ADP-024\", \"ADP-060\"]\nimport { MAX_PARKED_ATTEMPTS } from \"@coool/adaptive-core/execution/parking/plan\"\nimport { isTierName, type TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { JsonFile } from \"./store.js\"\n\n/** Metadata only: user input stays in Pi's own session file, never this index. */\nexport interface Parked {\n readonly session: string\n readonly token: string\n readonly tier: TierName\n readonly due: number\n readonly wakes: number\n readonly claimed: boolean\n}\n\nexport interface ParkingSources {\n readonly file: JsonFile\n readonly clock: () => number\n readonly timer: (callback: () => void, delay: number) => () => void\n}\n\n/**\n * Failed wake deliveries before a parked task stops auto-waking (the same\n * give-up budget OpenCode derives from MAX_PARKED_ATTEMPTS). A wake that\n * re-parks because the tier is still blocked does not consume the budget:\n * waiting for a stated reset is free, only resumed work that failed again\n * counts.\n */\nexport const MAX_WAKES = MAX_PARKED_ATTEMPTS\nexport const SHORT_WAIT_MS = 120_000\nexport const PARK_ENTRY = \"adaptive.parked\"\nexport class WaitCancelled extends Error {\n constructor() {\n super(\"Adaptive wait cancelled\")\n }\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\nexport function parseParked(value: unknown): Parked {\n const session = field(value, \"session\")\n const token = field(value, \"token\")\n const tier = field(value, \"tier\")\n const due = field(value, \"due\")\n const wakes = field(value, \"wakes\")\n const claimed = field(value, \"claimed\")\n if (typeof session !== \"string\" || session.length === 0)\n throw new Error(\"Adaptive parked: session must be a non-empty string\")\n if (typeof token !== \"string\" || token.length === 0)\n throw new Error(\"Adaptive parked: token must be a non-empty string\")\n if (typeof tier !== \"string\" || !isTierName(tier))\n throw new Error(\"Adaptive parked: tier must be quick, standard, or advanced\")\n if (typeof due !== \"number\" || !Number.isFinite(due) || due < 0)\n throw new Error(\"Adaptive parked: due must be a finite timestamp\")\n // Manual retries after the give-up may keep failing, so `wakes` has no\n // upper bound: MAX_WAKES is policy (stop auto-waking), not a format limit.\n if (typeof wakes !== \"number\" || !Number.isSafeInteger(wakes) || wakes < 0)\n throw new Error(\"Adaptive parked: wakes must be a non-negative integer\")\n if (typeof claimed !== \"boolean\") throw new Error(\"Adaptive parked: claimed must be boolean\")\n return { session, token, tier, due, wakes, claimed }\n}\n\nfunction records(value: unknown): Parked[] {\n if (value === undefined) return []\n const rows = field(value, \"records\")\n if (field(value, \"version\") !== 1 || !Array.isArray(rows) || rows.length > 512)\n throw new Error(\"Adaptive parked: expected version 1 and at most 512 records\")\n return rows.map(parseParked)\n}\n\nexport function savePark(file: JsonFile, record: Parked): Promise<void> {\n return file.update((value) => ({\n next: {\n version: 1,\n records: [...records(value).filter((row) => row.session !== record.session), record].slice(\n -512,\n ),\n },\n result: undefined,\n }))\n}\n\nexport function findPark(file: JsonFile, session: string): Promise<Parked | undefined> {\n return file.update((value) => ({\n next: undefined,\n result: records(value).find((row) => row.session === session && !row.claimed),\n }))\n}\n\n/**\n * Claim before dispatch under the same cross-process file lock. The claim\n * does not touch `wakes`: only a re-park after the delivered task failed\n * again does (parkingAfterRun). `manual` retries a given-up task on the\n * user's explicit request instead of silently refusing it.\n */\nexport function claimPark(\n file: JsonFile,\n record: Parked,\n now: number,\n manual = false,\n): Promise<boolean> {\n return file.update((value) => {\n const rows = records(value)\n const found = rows.find((row) => row.session === record.session && row.token === record.token)\n const claimed =\n found !== undefined &&\n !found.claimed &&\n found.due <= now &&\n (manual || found.wakes < MAX_WAKES)\n return {\n next: claimed\n ? {\n version: 1,\n records: rows.map((row) => (row === found ? { ...row, claimed: true } : row)),\n }\n : undefined,\n result: claimed,\n }\n })\n}\n\nexport function cancelPark(file: JsonFile, session: string): Promise<void> {\n return file.update((value) => ({\n next: { version: 1, records: records(value).filter((row) => row.session !== session) },\n result: undefined,\n }))\n}\n\n/** Abortable ticks, shared by countdowns and long owned headless waits. */\nexport async function waitUntil(\n sources: ParkingSources,\n due: number,\n signal: AbortSignal,\n tick: (remaining: number) => void,\n): Promise<void> {\n while (sources.clock() < due) {\n if (signal.aborted) throw new WaitCancelled()\n const remaining = due - sources.clock()\n tick(remaining)\n await new Promise<void>((resolve, reject) => {\n const abort = () => {\n cancel()\n reject(new WaitCancelled())\n }\n const cancel = sources.timer(\n () => {\n signal.removeEventListener(\"abort\", abort)\n resolve()\n },\n Math.min(remaining, 1_000),\n )\n signal.addEventListener(\"abort\", abort, { once: true })\n })\n }\n if (signal.aborted) throw new WaitCancelled()\n}\n","/** Extract and join text from message content. */\nexport function contentText(content, separator = \"\\n\") {\n if (typeof content === \"string\")\n return content;\n return content\n .filter((block) => block.type === \"text\")\n .map((block) => block.text)\n .join(separator);\n}\n/** Render a system message as a complete prompt: its content followed by its sections. */\nexport function getSystemMessageText(message) {\n const parts = [contentText(message.content)];\n for (const text of Object.values(message.sections ?? {})) {\n if (text !== null)\n parts.push(text);\n }\n return parts.filter((part) => part.length > 0).join(\"\\n\\n\");\n}\n/**\n * Render a later system message for APIs that accept system messages mid-conversation.\n * Section changes are framed by name so the model can relate them to the leading prompt.\n * This framing is request-time only and may change between versions.\n */\nexport function renderSystemMessageUpdate(message) {\n const parts = [];\n const text = contentText(message.content);\n if (text.length > 0)\n parts.push(text);\n for (const [name, value] of Object.entries(message.sections ?? {})) {\n parts.push(value === null\n ? `Removed system prompt section \"${name}\".`\n : `Updated system prompt section \"${name}\":\\n\\n${value}`);\n }\n return parts.join(\"\\n\\n\");\n}\n/**\n * `text.slice(start, end)` as a string of its own. V8 represents a slice of 13 or more characters as a view that keeps\n * all of `text` alive, so a short excerpt kept from a large text (a 500-character error message cut from a megabyte\n * response body) would keep the whole text alive as long as the excerpt lives. Appending a character and slicing it off\n * again makes V8 copy just the slice.\n */\nexport function ownedSlice(text, start, end = text.length) {\n return `${text.slice(start, end)} `.slice(0, -1);\n}\n//# sourceMappingURL=text.js.map","import { getSystemMessageText } from \"./text.js\";\nconst CHARS_PER_TOKEN = 3.5;\nconst ESTIMATED_IMAGE_CHARS = 4800;\nexport function calculateContextTokens(usage) {\n return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n}\nfunction safeJsonStringify(value) {\n try {\n return JSON.stringify(value) ?? \"undefined\";\n }\n catch {\n return \"[unserializable]\";\n }\n}\nfunction estimateTextAndImageContentChars(content) {\n if (typeof content === \"string\")\n return content.length;\n let chars = 0;\n for (const block of content)\n chars += block.type === \"text\" ? block.text.length : ESTIMATED_IMAGE_CHARS;\n return chars;\n}\nexport function estimateTextTokens(text) {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\nexport function estimateTextAndImageContentTokens(content) {\n return Math.ceil(estimateTextAndImageContentChars(content) / CHARS_PER_TOKEN);\n}\nexport function estimateMessageTokens(message) {\n let chars = 0;\n if (message.role === \"system\") {\n return (estimateTextTokens(getSystemMessageText(message)) +\n estimateToolsTokens(message.toolsAdded) +\n estimateToolsTokens(message.toolsRemoved));\n }\n if (message.role === \"user\")\n return estimateTextAndImageContentTokens(message.content);\n if (message.role === \"toolResult\")\n return estimateTextAndImageContentTokens(message.content);\n for (const block of message.content) {\n if (block.type === \"text\") {\n chars += block.text.length;\n }\n else if (block.type === \"thinking\") {\n chars += block.thinking.length;\n }\n else {\n chars += block.name.length + safeJsonStringify(block.arguments).length;\n }\n }\n return Math.ceil(chars / CHARS_PER_TOKEN);\n}\nfunction getLastAssistantUsageInfo(messages) {\n let latestPrefixTimestamp = Number.NEGATIVE_INFINITY;\n let usageInfo;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (message.role === \"assistant\") {\n const assistant = message;\n // A newer prefix message was inserted after this response (for example, a\n // compaction summary), so its usage cannot describe the current prefix.\n const usageAppliesToPrefix = assistant.timestamp >= latestPrefixTimestamp;\n if (usageAppliesToPrefix &&\n assistant.stopReason !== \"aborted\" &&\n assistant.stopReason !== \"error\" &&\n calculateContextTokens(assistant.usage) > 0) {\n usageInfo = { usage: assistant.usage, index: i };\n }\n }\n latestPrefixTimestamp = Math.max(latestPrefixTimestamp, message.timestamp);\n }\n return usageInfo;\n}\nexport function estimateContextTokens(context) {\n const messages = \"messages\" in context ? context.messages : context;\n const usageInfo = getLastAssistantUsageInfo(messages);\n if (usageInfo) {\n const usageTokens = calculateContextTokens(usageInfo.usage);\n let trailingTokens = 0;\n for (let i = usageInfo.index + 1; i < messages.length; i++) {\n trailingTokens += estimateMessageTokens(messages[i]);\n }\n return { tokens: usageTokens + trailingTokens, usageTokens, trailingTokens, lastUsageIndex: usageInfo.index };\n }\n let tokens = 0;\n for (const message of messages)\n tokens += estimateMessageTokens(message);\n return { tokens, usageTokens: 0, trailingTokens: tokens, lastUsageIndex: null };\n}\nfunction estimateToolsTokens(tools) {\n if (!tools || tools.length === 0)\n return 0;\n return estimateTextTokens(safeJsonStringify(tools));\n}\n//# sourceMappingURL=estimate.js.map","import {\n clampThinkingLevel,\n getSupportedThinkingLevels,\n type Api,\n type Message,\n type Model,\n type ModelThinkingLevel,\n} from \"@earendil-works/pi-ai\"\nimport { estimateContextTokens } from \"@earendil-works/pi-ai/utils/estimate\"\nimport type { CandidateModel, Demand } from \"@coool/adaptive-core/routing/compatibility/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { ModelSummary } from \"@coool/adaptive-core/flow/tiers\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport type { ProposalModel } from \"../ui/proposal.js\"\n\nexport function availablePhysicalModels(registry: { getAvailable(): Model<Api>[] }): Model<Api>[] {\n return registry\n .getAvailable()\n .filter((model) => model.provider !== \"adaptive\" && model.api !== \"pi-virtual\")\n}\n\n/** All thinking variants are explicit SDK capabilities, never inferred from names. */\nexport function modelInventory(\n models: readonly Model<Api>[],\n declarations: readonly ToolCapability[],\n): CandidateModel[] {\n return models.flatMap((model) => {\n const declared = declarations.find(\n (entry) => entry.providerID === model.provider && entry.id === model.id,\n )\n const base: CandidateModel = {\n providerID: model.provider,\n modelID: model.id,\n enabled: true,\n providerEnabled: true,\n capabilities: {\n input: model.input,\n output: [\"text\"],\n ...(declared === undefined ? {} : { tools: declared.tools }),\n },\n limit: { context: model.contextWindow },\n }\n return [\n base,\n ...getSupportedThinkingLevels(model).map((variant) => ({\n ...base,\n variant,\n variantAvailable: true,\n })),\n ]\n })\n}\n\nexport function modelSummaries(models: readonly Model<Api>[]): ModelSummary[] {\n return models.map((model) => ({\n providerID: model.provider,\n modelID: model.id,\n name: model.name,\n variants: getSupportedThinkingLevels(model),\n }))\n}\n\nexport function proposalModels(models: readonly Model<Api>[]): ProposalModel[] {\n return models.map((model) => ({\n ref: { providerID: model.provider, id: model.id },\n inputCost: model.cost.input,\n outputCost: model.cost.output,\n reasoning: model.reasoning,\n contextWindow: model.contextWindow,\n thinkingLevels: getSupportedThinkingLevels(model),\n }))\n}\n\nexport function requestDemand(messages: readonly Message[], tools: readonly string[]): Demand {\n return {\n tools: tools.length > 0,\n contextTokens: estimateContextTokens(messages).tokens,\n input: messages.some(\n (message) =>\n typeof message.content !== \"string\" &&\n message.content.some((part) => part.type === \"image\"),\n )\n ? [\"text\", \"image\"]\n : [\"text\"],\n }\n}\n\nexport function thinkingLevelFor(\n model: Model<Api>,\n ref: ModelRef,\n requested: ModelThinkingLevel,\n): ModelThinkingLevel {\n if (ref.variant === undefined) return clampThinkingLevel(model, requested)\n const level = getSupportedThinkingLevels(model).find((candidate) => candidate === ref.variant)\n if (level === undefined)\n throw new Error(\"Adaptive variant is unavailable. Check the tier's thinking level.\")\n return level\n}\n","import type { Api, Model } from \"@earendil-works/pi-ai\"\nimport type { ExtensionContext, ModelRouteRequest } from \"@earendil-works/pi-coding-agent\"\nimport { ResourceHealthRegistry } from \"@coool/adaptive-core/health/index\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { planWake, resourceUsableAt } from \"@coool/adaptive-core/execution/parking/wake\"\nimport { resourceChain } from \"@coool/adaptive-core/health/resource-health/key\"\nimport { checkCompatibility } from \"@coool/adaptive-core/routing/compatibility/gate\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type {\n AdmissionDecision,\n SchedulerInput,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { schedulerHealthKey } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readCapacity } from \"../capacity.js\"\nimport { assessCandidates, releaseUnselected, withHealth } from \"../health.js\"\nimport { admissionCandidates, routeAdmission, VIRTUAL_IDS, type VirtualID } from \"../router.js\"\nimport { requestedTier } from \"../session.js\"\nimport {\n parseTaskState,\n planRoute,\n type BranchEntry,\n type RoutePlan,\n type TaskState,\n} from \"../task.js\"\nimport { WaitCancelled } from \"../parking.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport type { RoutingFeedback } from \"./status-chip.js\"\nimport {\n availablePhysicalModels,\n modelInventory,\n requestDemand,\n thinkingLevelFor,\n} from \"./inventory.js\"\n\nexport interface RouteContext {\n readonly modelRegistry: { getAvailable(): Model<Api>[] }\n readonly sessionManager: {\n getBranch(): readonly BranchEntry[]\n getSessionId?(): string\n buildSessionProjection?: ExtensionContext[\"sessionManager\"][\"buildSessionProjection\"]\n }\n readonly hasUI?: boolean\n readonly mode?: string\n readonly signal?: AbortSignal | undefined\n readonly ui?: Pick<\n ExtensionContext[\"ui\"],\n \"setStatus\" | \"setWidget\" | \"setWorkingMessage\" | \"notify\" | \"confirm\"\n >\n}\n\nexport function physical(registry: RouteContext[\"modelRegistry\"]): Model<Api>[] {\n return availablePhysicalModels(registry)\n}\n\nexport interface Admission {\n readonly decision: AdmissionDecision\n readonly due: number\n}\n\n/** One scheduler for preview, dispatch, and re-admission after a wait. */\nexport async function prepareAdmission(\n id: VirtualID,\n request: ModelRouteRequest,\n ctx: RouteContext,\n sources: AdaptiveSources,\n activeTools: () => readonly string[],\n preview = false,\n resumedInput?: TaskState,\n degraded?: () => void,\n) {\n const current = await sources.settings()\n const declarations = await sources.capabilities()\n const models = physical(ctx.modelRegistry)\n const state = parseTaskState(request.state)\n const computed = planRoute({\n id,\n reason: request.reason,\n state,\n branch: ctx.sessionManager.getBranch(),\n requestedTier: requestedTier(ctx.sessionManager.getBranch()),\n failed:\n request.failed === undefined\n ? undefined\n : {\n model: { providerID: request.failed.model.provider, id: request.failed.model.id },\n message: request.failed.message,\n },\n newId: sources.newId,\n })\n const plan =\n resumedInput === undefined\n ? computed\n : { ...computed, tier: resumedInput.tier, state: resumedInput }\n const previous = request.previous?.model\n const input = {\n tier: plan.tier,\n sticky: plan.sticky,\n settings: current,\n previous:\n previous === undefined\n ? undefined\n : {\n providerID: previous.provider,\n id: previous.id,\n ...(request.previous?.thinkingLevel === undefined\n ? {}\n : { variant: request.previous.thinkingLevel }),\n },\n inventory: modelInventory(models, declarations),\n demand: requestDemand(request.messages, activeTools()),\n }\n const decide = (\n health: SchedulerInput[\"health\"],\n capacity: SchedulerInput[\"capacity\"],\n ): AdmissionDecision => routeAdmission({ ...input, health, capacity, exclude: plan.exclude })\n /**\n * ADP-003: a defer (an unusable pin) keeps ordinary behaviour — the tier's\n * first resource that passes the compatibility gates, ignoring the pin.\n */\n const deferFallback = () =>\n current.tiers[plan.tier].find((ref) =>\n input.inventory.some(\n (entry) =>\n entry.providerID === ref.providerID &&\n entry.modelID === ref.id &&\n entry.variant === ref.variant &&\n checkCompatibility(entry, input.demand).compatible,\n ),\n )\n const choose = async (ignoreHealth = false): Promise<Admission> => {\n const now = sources.health.clock()\n const fallback = () => ({ decision: decide({}, {}), due: now })\n if (ignoreHealth || plan.sticky) return fallback()\n const candidates = admissionCandidates(current, plan.tier)\n const view = await readCapacity(sources.capacity, candidates)\n // A usage sample describes its old window. Keep it for status, but once\n // its stated reset passes it cannot block admission into the new window.\n const capacity = Object.fromEntries(\n Object.entries(view.capacity).filter(([key]) => {\n const reset = view.readings[key]?.resetAt\n return reset === undefined || reset > now\n }),\n )\n try {\n const assess = (registry: ResourceHealthRegistry) => {\n const { health, tickets } = assessCandidates(registry, candidates)\n const decision = decide(health, capacity)\n releaseUnselected(\n registry,\n tickets,\n !preview && decision.kind === \"apply\" ? decision.model : undefined,\n )\n const targets = candidates.flatMap((ref) => {\n const entry = input.inventory.find(\n (candidate) =>\n candidate.providerID === ref.providerID &&\n candidate.modelID === ref.id &&\n candidate.variant === ref.variant,\n )\n if (entry === undefined || !checkCompatibility(entry, input.demand).compatible) return []\n const chain = resourceChain({\n providerID: ref.providerID,\n modelID: ref.id,\n variantID: ref.variant,\n }).map((key) => registry.recordFor(key))\n return [resourceUsableAt(chain, view.readings[schedulerHealthKey(ref)] ?? null, now)]\n })\n const wake = planWake(targets, now, 0)\n return { decision, due: wake?.dueAt ?? now + 300_000 }\n }\n if (preview) {\n // Preview may simulate a due probe, but never leases or mutates shared health.\n const registry = new ResourceHealthRegistry(sources.health.clock)\n registry.restore(parseHealthPayload(await sources.health.file.read()))\n return assess(registry)\n }\n return await withHealth(sources.health, assess)\n } catch (error) {\n degraded?.()\n logFailOpen(\"health\", error)\n return fallback()\n }\n }\n return { choose, plan, models, state, deferFallback }\n}\n\nexport interface RouteParking {\n takeInput(): TaskState | undefined\n blocked(\n plan: RoutePlan,\n admission: Admission,\n request: ModelRouteRequest,\n ctx: RouteContext,\n ): Promise<RoutePlan | undefined>\n}\n\nexport function virtualModels(\n sources: AdaptiveSources,\n activeTools: () => readonly string[],\n parking?: RouteParking,\n dispatched?: (\n model: Model<Api>,\n info: {\n decision: AdmissionDecision\n unit: string | undefined\n tier: TierName\n session: string | undefined\n retry: boolean\n state: TaskState | undefined\n },\n ) => void,\n feedback?: (ctx: RouteContext) => RoutingFeedback & { readonly context: RouteContext },\n) {\n return VIRTUAL_IDS.map((id) => ({\n provider: \"adaptive\",\n id,\n name: `Adaptive ${id === \"auto\" ? \"Auto\" : id}`,\n async route(request: ModelRouteRequest, ctx: RouteContext) {\n const report = feedback?.(ctx)\n const prepared = await prepareAdmission(\n id,\n request,\n ctx,\n sources,\n activeTools,\n false,\n request.reason === \"user\" ? parking?.takeInput() : undefined,\n () => report?.show({ kind: \"degraded\" }),\n ).catch((error: unknown) => {\n report?.show({ kind: \"degraded\" })\n throw error\n })\n let plan = prepared.plan\n let admission: Admission =\n (plan.state?.hops ?? 0) >= 3 && request.reason === \"retry\"\n ? {\n decision: { kind: \"park\", reason: \"all-blocked\", detail: \"retry budget spent\" },\n due: sources.health.clock() + 300_000,\n }\n : await prepared.choose()\n if (admission.decision.kind === \"park\" && admission.decision.reason === \"no-candidates\") {\n report?.show({ kind: \"setup\" })\n throw new Error(\"Adaptive unavailable: no-candidates. Check your tier settings.\")\n }\n for (\n let attempt = 0;\n admission.decision.kind === \"park\" && parking !== undefined && attempt < 4;\n attempt += 1\n ) {\n try {\n const resumed = await parking.blocked(plan, admission, request, report?.context ?? ctx)\n if (resumed === undefined) break\n plan = resumed\n admission = await prepared.choose()\n } catch (error) {\n if (error instanceof WaitCancelled) throw error\n report?.show({ kind: \"degraded\" })\n logFailOpen(\"parking\", error)\n admission = await prepared.choose(true)\n break\n }\n }\n const { decision } = admission\n let selectedRef: ModelRef\n if (decision.kind === \"defer\") {\n const fallback = prepared.deferFallback()\n if (fallback === undefined) {\n report?.show({ kind: \"setup\" })\n throw new Error(\n `Adaptive is not set up: ${decision.reason}. Run /adaptive to set up tiers.`,\n )\n }\n selectedRef = fallback\n } else {\n if (decision.kind !== \"apply\")\n throw new Error(`Adaptive unavailable: ${decision.reason}. Check your tier settings.`)\n selectedRef = decision.model\n }\n const selected = prepared.models.find(\n (model) => model.provider === selectedRef.providerID && model.id === selectedRef.id,\n )\n if (selected === undefined) {\n report?.show({ kind: \"degraded\" })\n throw new Error(\"Adaptive inventory changed. Try again.\")\n }\n report?.dispatched(selected, {\n tier: plan.tier,\n retry: request.reason === \"retry\",\n state: plan.state,\n })\n dispatched?.(selected, {\n decision,\n unit: plan.state?.unit,\n tier: plan.tier,\n session: ctx.sessionManager.getSessionId?.(),\n retry: request.reason === \"retry\",\n state: plan.state,\n })\n return {\n model: selected,\n thinkingLevel: thinkingLevelFor(selected, selectedRef, request.thinkingLevel),\n state: plan.state === prepared.state ? request.state : plan.state,\n }\n },\n }))\n}\n","// covers: [\"ADP-015\", \"ADP-055\"]\nimport {\n ESCALATION_TOOL_NAME,\n MAX_ESCALATIONS_PER_TASK,\n parseEscalationRequest,\n} from \"@coool/adaptive-core/execution/escalation/index\"\nimport { isTierName, nextTier } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { VIRTUAL_IDS, type VirtualID } from \"../router.js\"\nimport { branchState, TIER_TOOL, type BranchEntry } from \"../task.js\"\n\n/** The structural subset of Pi's `ExtensionToolContext` the tools read. */\nexport interface ToolContext {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly sessionManager: { getBranch(): readonly BranchEntry[] }\n}\n\ninterface ToolResult {\n readonly content: [{ readonly type: \"text\"; readonly text: string }]\n readonly details: Record<string, unknown>\n readonly isError?: true\n}\n\nfunction reply(text: string, details: Record<string, unknown> = {}): ToolResult {\n return { content: [{ type: \"text\", text }], details }\n}\n\nfunction rejected(text: string): ToolResult {\n return { ...reply(text), isError: true }\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\n/** The Adaptive virtual entry the user selected, if any. */\nexport function selectedVirtual(model: ToolContext[\"model\"]): VirtualID | undefined {\n return model?.provider === \"adaptive\" ? VIRTUAL_IDS.find((id) => id === model.id) : undefined\n}\n\n/**\n * Resolve routing eligibility and the selected task together. Physical model\n * pins always win; tier pins require the user's explicit escalation opt-in.\n */\nfunction routing(\n settings: SettingsV1,\n model: ToolContext[\"model\"],\n escalateFromPinned: boolean,\n): { readonly id: VirtualID } | { readonly ignored: string } {\n const id = selectedVirtual(model)\n if (id === undefined)\n return { ignored: \"Adaptive is not routing this session: the user picked a model.\" }\n if (settings.pin !== null)\n return { ignored: `The user pinned ${settings.pin.providerID}/${settings.pin.id}.` }\n if (id !== \"auto\" && !escalateFromPinned) return { ignored: `The user pinned Adaptive ${id}.` }\n return { id }\n}\n\nexport function tierTool(settings: () => Promise<SettingsV1>) {\n return {\n name: TIER_TOOL,\n label: \"Adaptive tier\",\n description:\n \"Declare the capability tier of the task you are starting: quick (routine edits, mechanical steps), standard (the default), or advanced (multi-step design, broad refactors, hard debugging). The declaration applies from the next user prompt and stays in force for this session until you declare a different tier. Only declare when the task's tier differs from the default; never use this to work around unavailability.\",\n parameters: {\n type: \"object\",\n properties: {\n tier: {\n type: \"string\",\n enum: [\"quick\", \"standard\", \"advanced\"],\n description: \"The tier the task needs.\",\n },\n },\n required: [\"tier\"],\n additionalProperties: false,\n },\n async execute(\n _toolCallId: string,\n params: unknown,\n _signal: unknown,\n _onUpdate: unknown,\n ctx: ToolContext,\n ): Promise<ToolResult> {\n const requested = field(params, \"tier\")\n if (typeof requested !== \"string\" || !isTierName(requested))\n return rejected(\"adaptive_tier rejected: tier must be quick, standard, or advanced.\")\n const current = await settings()\n const route = routing(current, ctx.model, false)\n if (\"ignored\" in route) return reply(`${route.ignored} The tier request was not recorded.`)\n // A selected virtual model is active regardless of the global default.\n return reply(`Tier request recorded: ${requested}. It applies from the next user prompt.`, {\n tier: requested,\n })\n },\n }\n}\n\nexport function escalationTool(\n settings: () => Promise<SettingsV1>,\n escalateFromPinned: () => Promise<boolean>,\n) {\n return {\n name: ESCALATION_TOOL_NAME,\n label: \"Adaptive escalate\",\n description:\n \"Request stronger model capability for the current task. Provide a short reason and the concrete evidence (what failed or was blocked). Adaptive records the request and weighs it only if this run then fails on a capability gap (for example context overflow or a content-policy rejection), within a finite budget; recording alone does not switch models. This is not a planning or task-management tool.\",\n parameters: {\n type: \"object\",\n properties: {\n reason: {\n type: \"string\",\n minLength: 1,\n description: \"Short reason why the current task needs stronger capability.\",\n },\n evidence: {\n type: \"string\",\n minLength: 1,\n description: \"Concrete evidence of the capability gap: what failed or was blocked.\",\n },\n },\n required: [\"reason\", \"evidence\"],\n additionalProperties: false,\n },\n async execute(\n _toolCallId: string,\n params: unknown,\n _signal: unknown,\n _onUpdate: unknown,\n ctx: ToolContext,\n ): Promise<ToolResult> {\n const request = parseEscalationRequest(params)\n if (request === undefined)\n return rejected(\n \"adaptive_escalate rejected: reason and evidence are required non-empty strings.\",\n )\n const current = await settings()\n const route = routing(current, ctx.model, await escalateFromPinned())\n if (\"ignored\" in route)\n return reply(\n `${route.ignored} Adaptive will not escalate; tell the user if you need a stronger model.`,\n )\n const state = branchState(ctx.sessionManager.getBranch(), route.id)\n const tier = state?.tier ?? (route.id === \"auto\" ? \"standard\" : route.id)\n const used = state?.escalations ?? 0\n const next = nextTier(tier)\n const details = { reason: request.reason, evidence: request.evidence }\n if (next === undefined)\n return reply(\n `Recorded, but ${tier} is already the strongest tier; tell the user if you need a stronger model.`,\n details,\n )\n if (used >= MAX_ESCALATIONS_PER_TASK)\n return reply(\n `Recorded, but this task already used its ${String(MAX_ESCALATIONS_PER_TASK)} escalations.`,\n details,\n )\n return reply(\n `Recorded. If this run fails on a capability gap, the task continues on ${next} (${String(used)} of ${String(MAX_ESCALATIONS_PER_TASK)} escalations used).`,\n details,\n )\n },\n }\n}\n","// covers: [\"ADP-029\"]\nimport type { ExtensionAPI, InputEvent, InputEventResult } from \"@earendil-works/pi-coding-agent\"\nimport type { Api, Model } from \"@earendil-works/pi-ai\"\nimport { convertToLlm } from \"@earendil-works/pi-coding-agent\"\nimport { forMode } from \"@coool/adaptive-core/routing/scheduler/mode\"\nimport type { Decision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport { readPreferences } from \"../preferences.js\"\nimport { recordReceipt } from \"../receipts.js\"\nimport { effectiveMode } from \"../session.js\"\nimport { decisionNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { appendNote } from \"./entries.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport { prepareAdmission, type RouteContext } from \"./routing.js\"\nimport { selectedVirtual } from \"./tools.js\"\n\ntype Host = Pick<ExtensionAPI, \"appendEntry\" | \"getActiveTools\">\ninterface ObserveContext extends RouteContext {\n readonly model: Model<Api> | undefined\n}\n\ntype ObserveFeedback =\n { readonly kind: \"observing\"; readonly tier: TierName } | { readonly kind: \"degraded\" }\n\n/** The last decision a transcript note was written for, across handlers. */\nexport interface NoteTracker {\n last: Decision | undefined\n}\n\n/**\n * Manual-model sessions run the identical scheduler; nothing is ever applied\n * and the model keeps the user's choice (ADP-029). Runs on the same `input`\n * boundary the virtual dispatch uses, and never intercepts.\n */\nexport function observeInput(\n pi: Host,\n sources: AdaptiveSources,\n tracker: NoteTracker,\n feedback?: (ctx: ObserveContext) => (state: ObserveFeedback) => void,\n): (event: InputEvent, ctx: ObserveContext) => Promise<InputEventResult> {\n return async (event, ctx) => {\n if (event.source === \"extension\") return { action: \"continue\" }\n let report: ((state: ObserveFeedback) => void) | undefined\n try {\n const model = ctx.model\n if (model === undefined || selectedVirtual(model) !== undefined) return { action: \"continue\" }\n const captured = feedback?.(ctx)\n report = (state) => {\n try {\n captured?.(state)\n } catch (error) {\n logFailOpen(\"status\", error)\n }\n }\n const settings = await sources.settings()\n if (effectiveMode(model, settings.mode, ctx.sessionManager.getBranch()) !== \"observe\")\n return { action: \"continue\" }\n if (ctx.sessionManager.buildSessionProjection === undefined) return { action: \"continue\" }\n const history = convertToLlm(ctx.sessionManager.buildSessionProjection().messages)\n const status = { degraded: false }\n const prepared = await prepareAdmission(\n \"auto\",\n {\n model,\n reason: \"user\",\n thinkingLevel: \"off\",\n messages: [\n ...history,\n {\n role: \"user\",\n timestamp: sources.health.clock(),\n content: [{ type: \"text\", text: event.text }, ...(event.images ?? [])],\n },\n ],\n },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n undefined,\n () => {\n status.degraded = true\n },\n )\n const chosen = await prepared.choose()\n if (status.degraded) report({ kind: \"degraded\" })\n else report({ kind: \"observing\", tier: prepared.plan.tier })\n const decision = forMode(chosen.decision, \"observe\")\n const session = ctx.sessionManager.getSessionId?.()\n if (session !== undefined) {\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.health.clock(),\n sessionID: session,\n tier: prepared.plan.tier,\n decision,\n })\n const { verbosity } = await readPreferences(sources.preferences)\n if (shouldWriteNote(verbosity, decision, tracker.last)) {\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(decision, prepared.plan.tier),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = decision\n }\n }\n } catch (error) {\n report?.({ kind: \"degraded\" })\n logFailOpen(\"observe\", error)\n }\n return { action: \"continue\" }\n }\n}\n","import type { ImageContent } from \"@earendil-works/pi-ai\"\nimport { MAX_WAKES, PARK_ENTRY, type Parked } from \"../parking.js\"\nimport { parseTaskState, type TaskState } from \"../task.js\"\nimport type { RouteContext } from \"./routing.js\"\n\nexport interface ParkedInput {\n readonly text: string\n readonly images?: ImageContent[]\n}\nexport interface ParkPayload {\n readonly token: string\n readonly state: TaskState\n readonly input?: ParkedInput\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\n/** Only the host session, not the global parked index, holds user input. */\nexport function parkedPayload(ctx: RouteContext, token: string): ParkPayload | undefined {\n const data = ctx.sessionManager\n .getBranch()\n .findLast(\n (entry) =>\n entry.type === \"custom\" &&\n entry.customType === PARK_ENTRY &&\n field(entry.data, \"token\") === token,\n )?.data\n if (data === undefined) return undefined\n const state = parseTaskState(field(data, \"state\"))\n if (state === undefined) throw new Error(\"Adaptive parked: state missing\")\n const input = field(data, \"input\")\n if (input === undefined) return { token, state }\n const text = field(input, \"text\")\n if (typeof text !== \"string\") throw new Error(\"Adaptive parked: input.text must be a string\")\n const images = field(input, \"images\")\n if (images === undefined) return { token, state, input: { text } }\n if (!Array.isArray(images)) throw new Error(\"Adaptive parked: input.images must be an array\")\n const parsed: ImageContent[] = images.map((image: unknown) => {\n const data = field(image, \"data\")\n const mimeType = field(image, \"mimeType\")\n if (\n field(image, \"type\") !== \"image\" ||\n typeof data !== \"string\" ||\n typeof mimeType !== \"string\"\n )\n throw new Error(\"Adaptive parked: input.images entry must be an image\")\n return { type: \"image\", data, mimeType }\n })\n return { token, state, input: { text, images: parsed } }\n}\n\nexport function clearParked(ctx: RouteContext): void {\n ctx.ui?.setStatus(\"adaptive\", undefined)\n ctx.ui?.setWidget(\"adaptive\", undefined)\n ctx.ui?.setWorkingMessage()\n}\n\nexport function showParked(ctx: RouteContext, record: Parked): void {\n if (!ctx.hasUI) return\n const when = new Date(record.due).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" })\n const exhausted = record.wakes >= MAX_WAKES\n ctx.ui?.setStatus(\n \"adaptive\",\n `${record.tier} parked · ${exhausted ? \"needs your input\" : `resumes ${when}`}`,\n )\n ctx.ui?.setWidget(\"adaptive\", [\n `Parked: no available ${record.tier} model`,\n exhausted\n ? \"Automatic retries used up · /adaptive resume tries now\"\n : `Resumes ${when} · /adaptive resume tries now`,\n \"Send a message or pick a model to cancel.\",\n ])\n}\n","import type { ExtensionAPI, InputEvent, InputEventResult } from \"@earendil-works/pi-coding-agent\"\nimport type { Api, Model } from \"@earendil-works/pi-ai\"\nimport { CONTINUATION_PROMPT } from \"@coool/adaptive-core/execution/continuation/prompts\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport {\n cancelPark,\n claimPark,\n findPark,\n MAX_WAKES,\n PARK_ENTRY,\n savePark,\n SHORT_WAIT_MS,\n waitUntil,\n WaitCancelled,\n type Parked,\n} from \"../parking.js\"\nimport {\n CONTINUATION_TYPE,\n startTask,\n type Recovery,\n type RoutePlan,\n type TaskState,\n} from \"../task.js\"\nimport type { AdaptiveSources, SettleContext } from \"./extension.js\"\nimport { prepareAdmission, type RouteContext, type RouteParking } from \"./routing.js\"\nimport { selectedVirtual } from \"./tools.js\"\nimport {\n clearParked as clear,\n showParked as card,\n parkedPayload as payload,\n type ParkedInput as Input,\n type ParkPayload as Payload,\n} from \"./parked-view.js\"\nimport type { AdmissionDecision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readPreferences } from \"../preferences.js\"\nimport { recordReceipt } from \"../receipts.js\"\nimport { decisionNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { appendNote } from \"./entries.js\"\nimport type { NoteTracker } from \"./observe.js\"\n\ntype Host = Pick<ExtensionAPI, \"appendEntry\" | \"sendUserMessage\" | \"sendMessage\" | \"getActiveTools\">\ninterface ParkingContext extends RouteContext {\n readonly model: Model<Api> | undefined\n}\ninterface ParkingHandlers extends RouteParking {\n readonly input: (event: InputEvent, ctx: ParkingContext) => Promise<InputEventResult>\n modelSelect(\n model: { readonly provider: string; readonly id: string },\n ctx: RouteContext,\n ): Promise<void>\n sessionStart(ctx: ParkingContext): Promise<void>\n /** `/adaptive resume`: wake this session's parked task now. */\n resume(ctx: RouteContext): Promise<void>\n /**\n * Drop the parked record of a wake lineage whose run just finished. Task-id\n * scoped: a park from another task in the same session is left alone.\n */\n clearServed(\n task: string,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<void>\n /** `/adaptive cancel`: drop this session's wait and parked record. */\n cancel(ctx: RouteContext): Promise<void>\n readonly shutdown: () => void\n recover(\n recovery: Recovery,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<boolean>\n}\n/** Session-bound lifecycle; only TUI wakes may outlive their owning handler. */\nexport function parkingHandlers(\n pi: Host,\n sources: AdaptiveSources,\n tracker: NoteTracker = { last: undefined },\n): ParkingHandlers {\n let active: AbortController | undefined\n let disarm: (() => void) | undefined\n let generation = 0\n let resumedInput: TaskState | undefined\n const stop = () => {\n generation += 1\n resumedInput = undefined\n active?.abort()\n active = undefined\n disarm?.()\n disarm = undefined\n }\n const cancel = async (ctx: RouteContext) => {\n stop()\n clear(ctx)\n const session = ctx.sessionManager.getSessionId?.()\n if (\n session !== undefined &&\n ctx.sessionManager.getBranch().some((entry) => entry.customType === PARK_ENTRY)\n )\n await cancelPark(sources.parking.file, session)\n }\n const noteResume = async (owned: number, tier: RoutePlan[\"tier\"]): Promise<void> => {\n try {\n const { verbosity } = await readPreferences(sources.preferences)\n if (owned !== generation || verbosity === \"quiet\") return\n appendNote(pi, { version: 1, text: `${tier} resumed · retrying parked work` })\n } catch (error) {\n logFailOpen(\"notes\", error)\n }\n }\n const wake = async (\n ctx: RouteContext,\n record: Parked,\n saved: Payload,\n now = sources.parking.clock(),\n manual = false,\n ) => {\n const owned = generation\n if (!(await claimPark(sources.parking.file, record, now, manual))) {\n clear(ctx)\n return\n }\n if (owned !== generation) return\n clear(ctx)\n if (saved.input !== undefined) {\n resumedInput = { ...saved.state, wakes: record.wakes, wakeToken: record.token }\n const content = [\n { type: \"text\" as const, text: saved.input.text },\n ...(saved.input.images ?? []),\n ]\n pi.sendUserMessage(content, { expandPromptTemplates: false })\n } else {\n pi.sendMessage(\n {\n customType: CONTINUATION_TYPE,\n content: CONTINUATION_PROMPT,\n display: false,\n details: {\n task: saved.state.task,\n token: record.token,\n tier: record.tier,\n escalations: saved.state.escalations,\n restarts: saved.state.restarts,\n wakes: record.wakes,\n wakeToken: record.token,\n tried: [],\n },\n },\n { triggerTurn: true },\n )\n }\n await noteResume(owned, record.tier)\n }\n const arm = (ctx: RouteContext, record: Parked, saved: Payload) => {\n card(ctx, record)\n if (record.wakes >= MAX_WAKES) return\n const owned = generation\n disarm = sources.parking.timer(\n () => {\n if (owned !== generation) return\n if (sources.parking.clock() < record.due) {\n arm(ctx, record, saved)\n return\n }\n void wake(ctx, record, saved).catch((error: unknown) => {\n logFailOpen(\"parking\", error)\n })\n },\n Math.max(0, Math.min(1_800_000, record.due - sources.parking.clock())),\n )\n }\n const persist = async (ctx: RouteContext, state: TaskState, due: number, input?: Input) => {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) throw new Error(\"Adaptive parked: session id missing\")\n const record: Parked = {\n session,\n token: sources.newId(),\n tier: state.tier,\n due,\n wakes: state.wakes ?? 0,\n claimed: false,\n }\n const saved: Payload = { token: record.token, state, ...(input === undefined ? {} : { input }) }\n // Pi's session is already a user-content store; the shared index is metadata only.\n pi.appendEntry(PARK_ENTRY, saved)\n await savePark(sources.parking.file, record)\n card(ctx, record)\n // Give-up is a terminal event: no auto wake will fire again, so say so once.\n if (record.wakes >= MAX_WAKES) {\n try {\n appendNote(pi, {\n version: 1,\n text: `Gave up after ${String(record.wakes)} failed resumes · /adaptive resume tries now`,\n })\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n return { record, saved }\n }\n const wait = async (ctx: RouteContext, due: number, signal?: AbortSignal) => {\n const controller = new AbortController()\n active = controller\n const combined =\n signal === undefined ? controller.signal : AbortSignal.any([signal, controller.signal])\n try {\n await waitUntil(sources.parking, due, combined, (remaining) => {\n if (!ctx.hasUI) return\n const seconds = Math.ceil(remaining / 1_000)\n const countdown = `${String(Math.floor(seconds / 60))}:${String(seconds % 60).padStart(2, \"0\")}`\n const text = `Waiting for a model · ${countdown} · Esc cancels`\n ctx.ui?.setStatus(\"adaptive\", text)\n ctx.ui?.setWorkingMessage(text)\n })\n } finally {\n if (active === controller) active = undefined\n clear(ctx)\n }\n }\n\n /** Parks are receipted and noted like every other routing decision (ADP-030/058). */\n const parkNote = async (\n session: string,\n tier: RoutePlan[\"tier\"],\n decision: AdmissionDecision,\n unit: string,\n ): Promise<void> => {\n try {\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.parking.clock(),\n sessionID: session,\n unitID: unit,\n tier,\n decision,\n })\n const { verbosity } = await readPreferences(sources.preferences)\n if (!shouldWriteNote(verbosity, decision, tracker.last)) return\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(decision, tier),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = decision\n } catch (error) {\n logFailOpen(\"receipts\", error)\n }\n }\n\n const input = async (event: InputEvent, ctx: ParkingContext): Promise<InputEventResult> => {\n if (event.source === \"extension\") return { action: \"continue\" }\n let parked = false\n const owned = generation + 1\n try {\n await cancel(ctx)\n if (owned !== generation) return { action: \"handled\" }\n const model = ctx.model\n if (model === undefined) return { action: \"continue\" }\n const id = selectedVirtual(model)\n // A virtual selection schedules in every global mode (effectiveMode).\n if (id === undefined || event.streamingBehavior !== undefined) return { action: \"continue\" }\n const prepared = await prepareAdmission(\n id,\n {\n model,\n reason: \"user\",\n thinkingLevel: \"off\",\n messages: [\n {\n role: \"user\",\n timestamp: sources.parking.clock(),\n content: [{ type: \"text\", text: event.text }, ...(event.images ?? [])],\n },\n ],\n },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n )\n const admission = await prepared.choose()\n if (owned !== generation) return { action: \"handled\" }\n if (\n admission.decision.kind !== \"park\" ||\n admission.decision.reason === \"no-candidates\" ||\n admission.due - sources.parking.clock() <= SHORT_WAIT_MS\n )\n return { action: \"continue\" }\n // Pi buffers extension entries until its first conversation message. Let the\n // host persist that message; route() can park before any provider dispatch.\n if (\n !ctx.sessionManager\n .getBranch()\n .some(\n (entry) =>\n entry.type === \"message\" &&\n (entry.message?.role === \"user\" || entry.message?.role === \"assistant\"),\n )\n )\n return { action: \"continue\" }\n const state = startTask(prepared.plan.tier, sources.newId)\n const { record, saved } = await persist(ctx, state, admission.due, {\n text: event.text,\n ...(event.images === undefined ? {} : { images: event.images }),\n })\n await parkNote(record.session, prepared.plan.tier, admission.decision, state.unit)\n parked = true\n if (owned !== generation) return { action: \"handled\" }\n if (ctx.mode === \"tui\") arm(ctx, record, saved)\n else {\n await wait(ctx, record.due, ctx.signal)\n await wake(ctx, record, saved)\n }\n return { action: \"handled\" }\n } catch (error) {\n if (error instanceof WaitCancelled) {\n if (owned === generation) await cancel(ctx)\n } else logFailOpen(\"parking\", error)\n return {\n action:\n parked || error instanceof WaitCancelled || owned !== generation ? \"handled\" : \"continue\",\n }\n }\n }\n const modelSelect: ParkingHandlers[\"modelSelect\"] = async (model, ctx) => {\n if (selectedVirtual(model) !== undefined) return\n try {\n await cancel(ctx)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n const sessionStart: ParkingHandlers[\"sessionStart\"] = async (ctx) => {\n stop()\n if (ctx.mode !== \"tui\" || selectedVirtual(ctx.model) === undefined) return\n try {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) return\n const record = await findPark(sources.parking.file, session)\n if (record === undefined) return\n const saved = payload(ctx, record.token)\n if (saved === undefined) return\n if (record.due <= sources.parking.clock() && record.wakes < MAX_WAKES) {\n if (await ctx.ui?.confirm(\"Parked task\", \"Resume the parked task now?\")) {\n // A person pressing Enter is a manual resume: it bypasses the give-up\n // budget just like /adaptive resume does.\n await wake(ctx, record, saved, record.due, true)\n } else await cancel(ctx)\n } else arm(ctx, record, saved)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n const resume: ParkingHandlers[\"resume\"] = async (ctx) => {\n const session = ctx.sessionManager.getSessionId?.()\n const record = session === undefined ? undefined : await findPark(sources.parking.file, session)\n const saved = record === undefined ? undefined : payload(ctx, record.token)\n if (record === undefined || saved === undefined) {\n ctx.ui?.notify(\"Nothing is parked in this session.\", \"info\")\n return\n }\n stop()\n // Resuming early is a request to try again now; routing parks again if the tier is still\n // blocked. Manual resume bypasses the automatic give-up budget — the person decided.\n await wake(ctx, record, saved, record.due, true)\n }\n const clearServed = async (\n task: string,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<void> => {\n try {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) return\n const record = await findPark(sources.parking.file, session)\n if (record === undefined) return\n const saved = payload(ctx, record.token)\n // Another task's park stays parked; only the served lineage is stale now.\n if (saved?.state.task !== task) return\n stop()\n clear(ctx)\n await cancelPark(sources.parking.file, session)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n return {\n input,\n modelSelect,\n sessionStart,\n resume,\n clearServed,\n cancel,\n shutdown: stop,\n async recover(recovery, ctx) {\n const id = selectedVirtual(ctx.model)\n const model = ctx.modelRegistry.getAvailable()[0]\n if (id === undefined || model === undefined) return false\n let parked = false\n const owned = generation\n try {\n const state: TaskState = {\n version: 1,\n task: recovery.task,\n unit: sources.newId(),\n tier: recovery.tier,\n escalations: recovery.escalations,\n restarts: recovery.restarts,\n wakes: recovery.wakes ?? 0,\n ...(recovery.wakeToken === undefined ? {} : { wakeToken: recovery.wakeToken }),\n tried: recovery.tried,\n }\n const prepared = await prepareAdmission(\n id,\n { model, reason: \"user\", thinkingLevel: \"off\", messages: [] },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n state,\n )\n const admission = await prepared.choose()\n if (owned !== generation) return true\n if (\n admission.decision.kind !== \"park\" ||\n admission.decision.reason === \"no-candidates\" ||\n admission.due - sources.parking.clock() <= SHORT_WAIT_MS\n )\n return false\n const { record, saved } = await persist(ctx, state, admission.due)\n await parkNote(record.session, prepared.plan.tier, admission.decision, state.unit)\n parked = true\n if (owned !== generation) return true\n if (ctx.mode === \"tui\" || record.wakes >= MAX_WAKES) arm(ctx, record, saved)\n else {\n await wait(ctx, record.due, ctx.signal)\n await wake(ctx, record, saved)\n }\n return true\n } catch (error) {\n if (error instanceof WaitCancelled) {\n if (owned === generation) await cancel(ctx)\n } else logFailOpen(\"parking\", error)\n return parked || owned !== generation\n }\n },\n takeInput() {\n const state = resumedInput\n resumedInput = undefined\n return state\n },\n async blocked(plan, admission, request, ctx): Promise<RoutePlan | undefined> {\n const state = plan.state\n if (request.reason === \"direct\" || state === undefined) return undefined\n const owned = generation\n try {\n if (admission.due - sources.parking.clock() <= SHORT_WAIT_MS) {\n await wait(ctx, admission.due, request.signal)\n return plan\n }\n const { record, saved } = await persist(ctx, state, admission.due)\n if (owned !== generation) return undefined\n // A throwing route never commits its returned state. Save it before parking\n // so an owned hidden continuation can consume the wake token after restart.\n pi.appendEntry(\"pi.virtual-model-state\", {\n provider: \"adaptive\",\n modelId: request.model.id,\n state,\n })\n await parkNote(record.session, plan.tier, admission.decision, state.unit)\n if (ctx.mode === \"tui\" || record.wakes >= MAX_WAKES) {\n arm(ctx, record, saved)\n return undefined\n }\n await wait(ctx, record.due, request.signal)\n if (!(await claimPark(sources.parking.file, record, sources.parking.clock())))\n return undefined\n await noteResume(owned, record.tier)\n if (owned !== generation) return undefined\n return {\n ...plan,\n state: {\n ...state,\n unit: sources.newId(),\n wakes: record.wakes,\n wakeToken: record.token,\n hops: 0,\n tried: [],\n },\n }\n } catch (error) {\n if (error instanceof WaitCancelled && owned === generation) await cancel(ctx)\n throw error\n }\n },\n }\n}\n","import type { StatusSnapshot } from \"../status.js\"\n\n/** How often a view re-reads parked sessions: wakes land at second granularity, a few seconds' lag is fine. */\nexport const WAITING_POLL_MS = 10_000\n\nconst DAY_MS = 24 * 60 * 60_000\nconst WEEK_DAYS = 6\n\n/** Parked sessions by id, mapped to when their tier is next expected to be usable (null = unknown). */\nexport function waitingSessions(snapshot: StatusSnapshot): Record<string, number | null> {\n const sessions: Record<string, number | null> = {}\n for (const entry of snapshot.waiting) sessions[entry.sessionID] = entry.resumeAt\n return sessions\n}\n\nfunction startOfDay(at: number): number {\n const date = new Date(at)\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()\n}\n\nfunction clock(date: Date): string {\n return `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`\n}\n\n/**\n * Short human text for a parked session (ADP-024): \"waiting · resumes 18:42\". Weekly limits reset days away, so\n * a later day gains its weekday, and beyond a week its date. Local fields, not the locale formatter, keep the\n * text identical across hosts.\n */\nexport function waitingLabel(resumeAt: number | null, now: number): string {\n if (resumeAt === null) return \"waiting\"\n if (resumeAt <= now) return \"waiting · resuming\"\n const date = new Date(resumeAt)\n // Calendar days, not elapsed time: 01:00 tomorrow is \"Sun 01:00\" even when it is only two hours away.\n const days = Math.round((startOfDay(resumeAt) - startOfDay(now)) / DAY_MS)\n if (days === 0) return `waiting · resumes ${clock(date)}`\n // toDateString is spec-fixed (\"Sat Nov 07 2026\"), unlike toLocaleString.\n const day = date.toDateString()\n if (days <= WEEK_DAYS) return `waiting · resumes ${day.slice(0, 3)} ${clock(date)}`\n return `waiting · resumes ${day.slice(4, 7)} ${String(date.getDate())} ${clock(date)}`\n}\n","import { isDeepStrictEqual } from \"node:util\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { resourceChain, resourceKeyID } from \"@coool/adaptive-core/health/resource-health/key\"\nimport type { ResourceRecord } from \"@coool/adaptive-core/health/resource-health/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport function parseSharedHealth(raw: unknown): ResourceRecord[] {\n if (raw === undefined) return []\n const records = parseHealthPayload(raw)\n if (!isDeepStrictEqual(raw, { version: 1, records }))\n throw new Error(\"Adaptive health: invalid health.json payload\")\n return records\n}\n\nexport async function readSharedHealth(file: Pick<JsonFile, \"read\">): Promise<ResourceRecord[]> {\n return parseSharedHealth(await file.read())\n}\n\n/** Explicit reset also clears inherited blockers; the UI warns that siblings may be affected. */\nexport function resetResourceHealth(file: JsonFile, ref: ModelRef): Promise<void> {\n return file.update((current) => {\n const chain = new Set(\n resourceChain({ providerID: ref.providerID, modelID: ref.id, variantID: ref.variant }).map(\n resourceKeyID,\n ),\n )\n const records = parseSharedHealth(current).filter(\n (record) => !chain.has(resourceKeyID(record.key)),\n )\n return { next: { version: 1, records }, result: undefined }\n })\n}\n","import type { HostCopy, HostDeferReason } from \"@coool/adaptive-core/flow/host-copy\"\nimport type { ParkReason } from \"@coool/adaptive-core/routing/scheduler/types\"\n\nconst defer: Record<HostDeferReason, string> = {\n \"routing-defer\":\n \"No routing rule applied. Pi keeps the manual model; an Adaptive entry needs a compatible configured model in its tier.\",\n \"adaptive-off\": \"Adaptive is off. Pi keeps your selected model.\",\n \"pin-unverifiable\":\n \"The pinned resource is not available in Pi. Check credentials or change the pin in /adaptive.\",\n \"pin-incompatible\":\n \"The pinned resource cannot handle this request. Change the pin or tier in /adaptive.\",\n}\nconst park: Record<ParkReason, string> = {\n \"all-blocked\":\n \"Every model in the required tier is unavailable. Work waits for recovery; /adaptive resume or cancel manages the wait.\",\n \"no-candidates\": \"This tier has no configured models. Open /adaptive tiers to add one.\",\n \"no-compatible-resource\":\n \"No configured model fits this request. Check context, inputs and tool capabilities with /adaptive doctor.\",\n \"pin-blocked\":\n \"Your pinned resource is unavailable. Adaptive does not silently replace a pin; change it in /adaptive.\",\n}\n\nexport const PI_COPY: HostCopy = {\n inviteTitle: \"Pi Adaptive\",\n modelSearchPlaceholder: \"Search Pi models\",\n receiptExplanation: (reason) => defer[reason],\n parkExplanation: (reason) => park[reason],\n}\n","export interface DoctorCheck {\n readonly state: \"ok\" | \"warning\" | \"error\"\n readonly message: string\n readonly action?: string\n}\n\nfunction parts(version: string): readonly [number, number, number] | undefined {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(version)) return undefined\n const [major, minor, patch] = version.split(\".\")\n return [Number(major), Number(minor), Number(patch)]\n}\n\nfunction compare(\n a: readonly [number, number, number],\n b: readonly [number, number, number],\n): number {\n for (const index of [0, 1, 2] as const) {\n const difference = a[index] - b[index]\n if (difference !== 0) return difference\n }\n return 0\n}\n\nexport function versionChecks(\n version: string,\n minimum: string,\n testedUpTo: string | undefined,\n): DoctorCheck[] {\n const actual = parts(version)\n const floor = parts(minimum)\n const tested = testedUpTo === undefined ? undefined : parts(testedUpTo)\n if (actual === undefined || floor === undefined)\n return [\n {\n state: \"warning\",\n message: `Pi ${version}: version support could not be checked`,\n action: \"Pick a normal model and report this version.\",\n },\n ]\n if (actual[0] !== 1 || compare(actual, floor) < 0)\n return [\n {\n state: \"error\",\n message: `Pi ${version} is unsupported (requires ≥${minimum} <2)`,\n action: \"Install a supported Pi version or pick a normal model.\",\n },\n ]\n const checks: DoctorCheck[] = [\n { state: \"ok\", message: `Pi ${version} (supported: ≥${minimum} <2)` },\n ]\n if (tested === undefined)\n checks.push({\n state: \"warning\",\n message: \"Packed-host tested-up-to evidence is not recorded\",\n action: \"Run the complete Pi host matrix before release.\",\n })\n else if (compare(actual, tested) > 0)\n checks.push({\n state: \"warning\",\n message: `Pi ${version} is newer than last tested ${String(testedUpTo)}`,\n action: \"If routing misbehaves, pick a normal model and report it.\",\n })\n else checks.push({ state: \"ok\", message: `Packed hosts tested up to ${String(testedUpTo)}` })\n return checks\n}\n\nconst LABELS: Record<DoctorCheck[\"state\"], string> = { ok: \"OK\", warning: \"CHECK\", error: \"FIX\" }\n\nconst SEVERITY: readonly DoctorCheck[\"state\"][] = [\"error\", \"warning\", \"ok\"]\n\n/** Problems first: the first screen answers \"is anything wrong, and what do I do\". */\nexport function doctorLines(checks: readonly DoctorCheck[]): string[] {\n const count = (state: DoctorCheck[\"state\"]) =>\n checks.filter((check) => check.state === state).length\n const problems = count(\"error\") + count(\"warning\")\n return [\n problems === 0\n ? `All ${String(checks.length)} checks OK`\n : `${String(count(\"error\"))} to fix · ${String(count(\"warning\"))} to check · ${String(count(\"ok\"))} OK`,\n ...SEVERITY.flatMap((state) => checks.filter((check) => check.state === state)).flatMap(\n (check) => [\n `${LABELS[check.state]} ${check.message}`,\n ...(check.action === undefined ? [] : [` ${check.action}`]),\n ],\n ),\n ]\n}\n","export interface ToolCapability {\n readonly providerID: string\n readonly id: string\n readonly tools: boolean\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nexport async function loadToolCapabilities(\n path: string,\n read: (path: string) => Promise<string>,\n): Promise<readonly ToolCapability[]> {\n let text: string\n try {\n text = await read(path)\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return []\n throw error\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n throw new Error(\"Adaptive capabilities: invalid JSON\")\n }\n return parseToolCapabilities(raw)\n}\n\nexport function parseToolCapabilities(raw: unknown): readonly ToolCapability[] {\n if (\n !(object(raw) && Array.isArray(raw[\"models\"])) ||\n Object.keys(raw).some((key) => key !== \"models\")\n )\n throw new Error(\"Adaptive capabilities.models: expected an array in a models-only object\")\n const seen = new Set<string>()\n return raw[\"models\"].map((entry: unknown, index: number) => {\n const field = `Adaptive capabilities.models[${String(index)}]`\n if (!object(entry)) throw new Error(`${field}: expected an object`)\n const providerID = entry[\"providerID\"]\n const id = entry[\"id\"]\n const tools = entry[\"tools\"]\n if (typeof providerID !== \"string\" || providerID.trim().length === 0)\n throw new Error(`${field}.providerID: expected a non-empty string`)\n if (typeof id !== \"string\" || id.trim().length === 0)\n throw new Error(`${field}.id: expected a non-empty string`)\n if (typeof tools !== \"boolean\") throw new Error(`${field}.tools: expected a boolean`)\n if (Object.keys(entry).some((key) => ![\"providerID\", \"id\", \"tools\"].includes(key)))\n throw new Error(`${field}: unknown field`)\n const key = JSON.stringify([providerID, id])\n if (seen.has(key)) throw new Error(`${field}: duplicate model`)\n seen.add(key)\n return { providerID, id, tools }\n })\n}\n\nexport function updateToolCapability(file: JsonFile, ref: ModelRef, tools: boolean): Promise<void> {\n return file.update((current) => {\n const entries = current === undefined ? [] : parseToolCapabilities(current)\n const entry = { providerID: ref.providerID, id: ref.id, tools }\n const models = [\n ...entries.filter((model) => model.providerID !== ref.providerID || model.id !== ref.id),\n entry,\n ]\n parseToolCapabilities({ models })\n return { next: { models }, result: undefined }\n })\n}\nimport type { JsonFile } from \"./store.js\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\n","import type { AdaptiveView } from \"@coool/adaptive-core/flow/controller\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { JsonFile } from \"../store.js\"\nimport { NOTE_VERBOSITIES, readPreferences, updatePreferences } from \"../preferences.js\"\nimport { updateToolCapability } from \"../capabilities.js\"\n\nexport const DEFAULT_MODEL_HELP =\n 'In Pi settings.json, set:\\n{\\n \"defaultProvider\": \"adaptive\",\\n \"defaultModel\": \"auto\"\\n}\\nPi exposes no extension API to save this default. Your current model is unchanged.'\n\nexport async function preferencesAction(view: AdaptiveView, file: JsonFile): Promise<void> {\n const current = await readPreferences(file)\n const choice = await view.select({\n title: \"Preferences\",\n options: [\n { title: `Transcript notes: ${current.verbosity}`, value: \"notes\" },\n {\n title: `Escalate from a pinned tier: ${current.escalateFromPinned ? \"on\" : \"off\"}`,\n value: \"escalate\",\n },\n ],\n })\n if (choice === \"notes\") {\n const verbosity = await view.select({\n title: \"Transcript notes\",\n options: NOTE_VERBOSITIES.map((value) => ({ title: value, value })),\n })\n if (verbosity === undefined) return\n await updatePreferences(file, { verbosity })\n } else if (choice === \"escalate\") {\n const confirmed = await view.confirm({\n title: \"Change pinned-tier escalation?\",\n message: current.escalateFromPinned\n ? \"Stop automatic capability escalation from pinned tiers?\"\n : \"Allow a failed task to move one tier above your pin, only with capability evidence and within the task budget?\",\n })\n if (confirmed !== true) return\n await updatePreferences(file, { escalateFromPinned: !current.escalateFromPinned })\n } else return\n view.toast(\"Preferences saved\", \"success\")\n}\n\nexport async function healthAction(\n view: AdaptiveView,\n models: readonly ModelRef[],\n reset: (model: ModelRef) => Promise<void>,\n): Promise<void> {\n const ref = await view.select({\n title: \"Health · select a resource to reset\",\n options: models.map((model) => ({\n title: resourceLabel(model),\n value: model,\n description: \"Mark healthy (also clears inherited provider limits)\",\n })),\n })\n if (ref === undefined) return\n if (\n !(await view.confirm({\n title: \"Reset resource health?\",\n message: `Reset ${resourceLabel(ref)} and its inherited provider limits? Other models on this provider may be affected. This does not restore actual provider quota.`,\n }))\n )\n return\n await reset(ref)\n view.toast(\"Health reset\", \"success\")\n}\n\nexport async function confirmToolCapability(\n view: AdaptiveView,\n file: JsonFile,\n ref: ModelRef,\n tools: boolean,\n): Promise<void> {\n if (\n !(await view.confirm({\n title: \"Confirm tool capability\",\n message: `${resourceLabel(ref)}: record tool support as ${tools ? \"supported\" : \"unsupported\"}? Only confirm this from provider documentation or a verified request.`,\n }))\n )\n return\n await updateToolCapability(file, ref, tools)\n view.toast(\"Tool capability saved\", \"success\")\n}\n","/**\n * Status-view helpers (ADP-033): flatten the status snapshot into one page\n * showing every configured model with its state, grouped by tier in priority\n * order. Pure and deterministic; local wall-clock rendering is derived from\n * the snapshot's own timestamps.\n */\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../status.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\n/** Configured resources in tier order (quick → standard → advanced). */\nexport function healthEntries(\n snapshot: StatusSnapshot,\n): { tier: TierName; status: TierResourceStatus }[] {\n const entries: { tier: TierName; status: TierResourceStatus }[] = []\n for (const tier of TIERS) {\n for (const status of snapshot.tiers[tier]) entries.push({ tier, status })\n }\n return entries\n}\n\n/** Local date and time: quota windows may reset days or weeks from now. */\nexport function clockTime(until: number): string {\n const at = new Date(until)\n const hours = String(at.getHours()).padStart(2, \"0\")\n const minutes = String(at.getMinutes()).padStart(2, \"0\")\n const month = String(at.getMonth() + 1).padStart(2, \"0\")\n const day = String(at.getDate()).padStart(2, \"0\")\n return `${String(at.getFullYear())}-${month}-${day} ${hours}:${minutes}`\n}\n\nfunction pinnedTo(ref: TierResourceStatus[\"ref\"], pin: StatusSnapshot[\"pin\"]): boolean {\n if (pin === null) return false\n return pin.providerID === ref.providerID && pin.id === ref.id && pin.variant === ref.variant\n}\n\n/** Everything after the health state: capacity usage, window, breaker, pin. */\nfunction stateSuffix(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n let suffix = \"\"\n if (status.windowed) {\n suffix +=\n status.windowUntil === null\n ? \", windowed (deadline unknown)\"\n : `, windowed until ${clockTime(status.windowUntil)}`\n }\n if (status.usedPercent !== null) {\n suffix += `, used ${String(status.usedPercent)}%`\n if (status.resetAt !== null) suffix += `, resets ${clockTime(status.resetAt)}`\n }\n if (status.breaker === \"open\") suffix += \", breaker open\"\n else if (status.breaker === \"half_open\") suffix += \", probing\"\n if (pinnedTo(status.ref, pin)) suffix += \" (pinned)\"\n return suffix\n}\n\n/** The STATE column of the status table: window, breaker, pin markers. */\nexport function stateCell(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n return stateSuffix(status, pin).replace(/^[, ]+/, \"\") || \"-\"\n}\n\n/**\n * The whole inventory as a column-aligned table (header row first): models\n * grouped in tier order (quick → standard → advanced), one row per model,\n * columns padded to the widest cell so the grid reads at a glance. There is\n * no per-resource selection step: the table IS the view.\n */\nexport function statusTable(snapshot: StatusSnapshot): string[] {\n const header = [\"MODEL\", \"TIER\", \"HEALTH\", \"STATE\"]\n const rows = healthEntries(snapshot).map(({ tier, status }) => [\n resourceLabel(status.ref),\n tier,\n status.health,\n stateCell(status, snapshot.pin),\n ])\n // Header and rows are built together, always four cells wide — the column\n // index cannot be out of range.\n const widths = header.map((cell, column) =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n Math.max(cell.length, ...rows.map((row) => row[column]!.length)),\n )\n const render = (cells: string[]): string =>\n cells\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map((cell, column) => cell.padEnd(widths[column]!))\n .join(\" \")\n .trimEnd()\n return [render(header), ...rows.map(render)]\n}\n\n/** Narrow hosts keep health and capacity visible instead of clipping wide model columns. */\nexport function compactStatus(snapshot: StatusSnapshot): string[] {\n return healthEntries(snapshot).flatMap(({ tier, status }) => [\n resourceLabel(status.ref),\n `${tier} · ${status.health}`,\n ...stateCell(status, snapshot.pin)\n .split(\", \")\n .map((part) => ` ${part}`),\n \"\",\n ])\n}\n\n/** Empty-state copy for the status view when nothing is configured. */\nexport const STATUS_EMPTY_MESSAGE = \"No models configured yet — open Models to add some.\"\n","/**\n * Main-menu and mode-menu view models for `/adaptive` (ADP-033): pure data\n * that the controller feeds into `ui.dialog.select`. Descriptions are dynamic\n * where state makes them more informative (health counters, tier contents).\n */\nimport { OPERATING_MODES } from \"../routing/scheduler/types.js\"\nimport type { OperatingMode } from \"../routing/scheduler/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot } from \"../status.js\"\nimport type { SettingsV1 } from \"../state/settings/index.js\"\nimport type { SelectOption } from \"./options.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\nexport const MAIN_MENU_ITEMS = [\"status\", \"models\", \"mode\", \"tier\", \"pin\", \"receipts\"] as const\nexport type MainMenuChoice = (typeof MAIN_MENU_ITEMS)[number]\n\n/** \"3 resources · 1 windowed\" — the status line under the menu entry. */\nexport function statusSummary(status: StatusSnapshot | undefined): string {\n if (status === undefined) return \"how every configured model is doing\"\n const total = TIERS.reduce((sum, tier) => sum + status.tiers[tier].length, 0)\n if (total === 0) return \"no models configured yet\"\n const windowed = TIERS.reduce(\n (sum, tier) => sum + status.tiers[tier].filter((entry) => entry.windowed).length,\n 0,\n )\n const windowedNote = windowed === 0 ? \"\" : ` · ${String(windowed)} windowed`\n return `${String(total)} resource${total === 1 ? \"\" : \"s\"}${windowedNote}`\n}\n\n/** \"quick: 1 · standard: 0 · advanced: 2\" — what is configured where. */\nexport function modelsSummary(settings: SettingsV1): string {\n const parts = TIERS.map((tier: TierName) => `${tier}: ${String(settings.tiers[tier].length)}`)\n return parts.join(\" · \")\n}\n\nfunction tierRequestDescription(tierRequest: TierName | null | undefined): string {\n if (tierRequest === undefined) return \"pin a tier for the current session\"\n if (tierRequest === null) return \"not pinned — the routing ladder decides\"\n return `pinned to ${tierRequest} — steers this session`\n}\n\nfunction modeMarker(\n mode: OperatingMode,\n input: { override: OperatingMode | null; effective: OperatingMode },\n): \"override\" | \"current\" | undefined {\n if (mode === input.override) return \"override\"\n if (mode === input.effective) return \"current\"\n return undefined\n}\n\nexport function mainMenuOptions(\n settings: SettingsV1,\n status: StatusSnapshot | undefined,\n tierRequest?: TierName | null,\n effectiveMode: OperatingMode = settings.mode,\n): SelectOption<MainMenuChoice>[] {\n const optionFor = (item: MainMenuChoice): SelectOption<MainMenuChoice> => {\n switch (item) {\n case \"status\":\n return {\n title: \"Status\",\n value: item,\n description: statusSummary(status),\n }\n case \"models\":\n return {\n title: \"Models\",\n value: item,\n description: modelsSummary(settings),\n }\n case \"mode\":\n return {\n title: \"Mode\",\n value: item,\n description: `currently ${effectiveMode}`,\n }\n case \"tier\":\n return {\n title: \"Tier\",\n value: item,\n description: tierRequestDescription(tierRequest),\n }\n case \"pin\":\n return {\n title: \"Pin\",\n value: item,\n description:\n settings.pin === null\n ? \"force one resource\"\n : `pinned to ${resourceLabel(settings.pin)}`,\n }\n case \"receipts\":\n return { title: \"Receipts\", value: item, description: \"why each turn ran the model it ran\" }\n }\n }\n return MAIN_MENU_ITEMS.map(optionFor)\n}\n\nexport function modeOptions(current: OperatingMode): SelectOption<OperatingMode>[] {\n return OPERATING_MODES.map((mode) => ({\n title: mode === current ? `${mode} (current)` : mode,\n value: mode,\n description: modeDescription(mode),\n }))\n}\n\n/** What one mode does — shared by the global and the per-session menus. */\nexport function modeDescription(mode: OperatingMode): string {\n switch (mode) {\n case \"off\":\n return \"Adaptive does nothing\"\n case \"observe\":\n return \"Record decisions without applying them\"\n case \"active\":\n return \"Apply routing and recovery decisions\"\n }\n}\n\n/** One per-session mode-menu pick: follow the global mode, or set an override. */\nexport type SessionModeChoice = { kind: \"global\" } | { kind: \"mode\"; mode: OperatingMode }\n\n/** Which mode the user steers inside a session: the global default or the session override. */\nexport type ModeTarget = \"global\" | \"session\"\n\n/**\n * The first select of the in-session mode flow (ADP-054): ask which mode to\n * steer before showing any mode list — the global default or this session's\n * override. Each row names the current value so the user can tell at a\n * glance which side needs changing.\n */\nexport function modeTargetOptions(\n global: OperatingMode,\n effective: OperatingMode,\n): SelectOption<ModeTarget>[] {\n return [\n {\n title: \"Global mode…\",\n description: `applies to every session without an override (now ${global})`,\n value: \"global\",\n },\n {\n title: \"This session…\",\n description: `override for this session only (now ${effective})`,\n value: \"session\",\n },\n ]\n}\n\n/**\n * The per-session mode menu (ADP-054): first \"Follow global\" (clearing the\n * override), then every mode. An existing override is marked \"(override)\" —\n * distinct from the effective mode's \"(current)\" — so the user can tell a\n * set override apart from a session merely inheriting the global mode.\n */\nexport function sessionModeOptions(input: {\n global: OperatingMode\n override: OperatingMode | null\n effective: OperatingMode\n}): SelectOption<SessionModeChoice>[] {\n const options: SelectOption<SessionModeChoice>[] = [\n {\n title: `Follow global (${input.global})`,\n description: \"clear this session's override\",\n value: { kind: \"global\" },\n },\n ]\n for (const mode of OPERATING_MODES) {\n const marker = modeMarker(mode, input)\n options.push({\n title: marker === undefined ? mode : `${mode} (${marker})`,\n value: { kind: \"mode\", mode },\n description: modeDescription(mode),\n })\n }\n return options\n}\n\n/** What one tier is for — shared by the tier editor and the per-session menu. */\nfunction tierDescription(tier: TierName): string {\n switch (tier) {\n case \"quick\":\n return \"routine edits, mechanical steps\"\n case \"standard\":\n return \"the default\"\n case \"advanced\":\n return \"multi-step design, broad refactors\"\n }\n}\n\n/** One per-session tier-menu pick: follow the routing ladder, or pin a tier. */\nexport type SessionTierChoice = { kind: \"ladder\" } | { kind: \"tier\"; tier: TierName }\n\n/**\n * The per-session tier menu (ADP-055): first \"Follow routing ladder\" (clearing\n * the request), then every tier. A pinned request is marked \"(pinned)\" so the\n * user can tell the sticky request apart from the ordinary ladder.\n */\nexport function sessionTierOptions(input: {\n pinned: TierName | null\n}): SelectOption<SessionTierChoice>[] {\n const options: SelectOption<SessionTierChoice>[] = [\n {\n title: \"Follow routing ladder\",\n description: \"clear this session's tier request\",\n value: { kind: \"ladder\" },\n },\n ]\n for (const tier of TIERS) {\n options.push({\n title: tier === input.pinned ? `${tier} (pinned)` : tier,\n value: { kind: \"tier\", tier },\n description: tierDescription(tier),\n })\n }\n return options\n}\n","/**\n * Shared option shapes for the dialog-driven /adaptive flow (TUI and GUI). These mirror the subset of\n * the host `ui.dialog.select` contract the Adaptive flows use; `tui.tsx` and `gui.tsx` adapt\n * them to the real plugin types (structural superset).\n */\nexport interface SelectOption<Value> {\n readonly title: string\n readonly value: Value\n readonly description?: string\n}\n\n/** Friendly one-line rendering of an API failure for toasts. */\nexport function errorText(error: unknown): string {\n if (error instanceof Error) return error.message\n // RPC failures surface as plain objects ({type, message}); String() would\n // render \"[object Object]\" and throw away the only diagnostic the user gets.\n if (typeof error === \"object\" && error !== null) {\n const message = (error as { message?: unknown }).message\n if (typeof message === \"string\" && message.length > 0) return message\n // JSON.stringify throws on BigInt values, which host payloads can carry;\n // stringify them as strings instead of losing the whole diagnostic.\n return JSON.stringify(error, (_, value: unknown) =>\n typeof value === \"bigint\" ? String(value) : value,\n )\n }\n return String(error)\n}\n","/**\n * Receipt view models (ADP-030/033): one-line summaries and bounded detail\n * text for the `/adaptive` receipts browser. No secrets — receipt content is\n * already bounded at write time; this layer only formats.\n */\nimport type {\n ApplyReason,\n Decision,\n ParkReason,\n SchedulerDeferReason,\n} from \"../routing/scheduler/types.js\"\nimport { resourceLabel } from \"./tiers.js\"\nimport type { Receipt, ReceiptOutcome } from \"../state/receipts/types.js\"\nimport type { HostCopy, HostDeferReason } from \"./host-copy.js\"\n\nexport function summarizeDecision(decision: Decision): string {\n switch (decision.kind) {\n case \"apply\": {\n const tier = decision.tier === undefined ? \"\" : ` [${decision.tier}]`\n return `apply ${resourceLabel(decision.model)}${tier} (${decision.reason})`\n }\n case \"defer\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `defer: ${decision.reason}${detail}`\n }\n case \"park\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `park: ${decision.reason}${detail}`\n }\n case \"escalate\": {\n return `escalate ${decision.step} → ${resourceLabel(decision.target)} [${decision.tier}]`\n }\n case \"observe-only\": {\n return `observe: ${summarizeDecision(decision.would)}`\n }\n }\n}\n\nexport function outcomeLine(outcome: ReceiptOutcome | undefined): string {\n if (outcome === undefined) return \"pending\"\n if (outcome.status === \"succeeded\") return \"succeeded\"\n if (outcome.status === \"failed\") return `failed (${outcome.category})`\n return `interrupted (${outcome.reason})`\n}\n\nexport function receiptLine(receipt: Receipt): string {\n return `#${String(receipt.id)} ${summarizeDecision(receipt.decision)} — ${outcomeLine(receipt.outcome)}`\n}\n\nexport function receiptDetail(receipt: Receipt, copy: HostCopy, now: number = Date.now()): string {\n return [\n `id: ${String(receipt.id)}`,\n `when: ${relativeTime(receipt.at, now)} (${new Date(receipt.at).toISOString()})`,\n `session: ${receipt.sessionID}`,\n `unit: ${receipt.unitID ?? \"-\"}`,\n `tier: ${receipt.tier ?? \"-\"}`,\n `decision: ${summarizeDecision(receipt.decision)}`,\n `outcome: ${outcomeLine(receipt.outcome)}`,\n \"\",\n `What happened: ${whatHappened(receipt, copy)}`,\n ].join(\"\\n\")\n}\n\n/** \"just now\" / \"2m ago\" / \"3h ago\" / \"5d ago\" for a receipt timestamp. */\nexport function relativeTime(at: number, now: number): string {\n const seconds = Math.max(0, Math.floor((now - at) / 1000))\n if (seconds < 60) return \"just now\"\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${String(minutes)}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${String(hours)}h ago`\n return `${String(Math.floor(hours / 24))}d ago`\n}\n\n/**\n * Plain-language explanation for a receipt, keyed on the finite reason\n * vocabulary (the maps are total over it).\n */\nexport function whatHappened(receipt: Receipt, copy: HostCopy): string {\n const decision = receipt.decision\n switch (decision.kind) {\n case \"apply\":\n return applyExplanation[decision.reason]\n case \"defer\":\n if (\n decision.reason === \"routing-defer\" ||\n decision.reason === \"adaptive-off\" ||\n decision.reason === \"pin-unverifiable\" ||\n decision.reason === \"pin-incompatible\"\n )\n return copy.receiptExplanation(decision.reason)\n return deferExplanation[decision.reason]\n case \"park\":\n return copy.parkExplanation?.(decision.reason) ?? parkExplanation[decision.reason]\n case \"escalate\":\n return `This turn needed stronger capability, so Adaptive moved it to ${resourceLabel(decision.target)}.`\n case \"observe-only\":\n return \"Adaptive is observing: this is what it would have done, without applying it.\"\n }\n}\n\nconst applyExplanation: Record<ApplyReason, string> = {\n pin: \"Adaptive routed to the resource you pinned.\",\n preferred:\n \"Adaptive chose this resource: it is the preferred resource for the tier and was available.\",\n fallback:\n \"The preferred resource was unavailable, so Adaptive moved the turn to the next resource in the tier.\",\n probe:\n \"Adaptive sent this turn as a recovery probe after an outage, to check whether the resource works again.\",\n draining: \"Adaptive routed to this resource while its provider was draining capacity.\",\n}\n\nconst deferExplanation: Record<Exclude<SchedulerDeferReason, HostDeferReason>, string> = {\n \"escalation-not-justified\":\n \"No structured capability evidence justified escalation, so Adaptive kept the current capability.\",\n \"escalation-budget-exhausted\":\n \"This unit has used its escalation budget; no further escalation is allowed.\",\n \"escalation-ceiling\":\n \"Adaptive is already at the highest capability tier; no stronger tier is configured.\",\n \"escalation-no-candidate\":\n \"No stronger resource was eligible to escalate to (unavailable, blocked, or not configured).\",\n}\n\nconst parkExplanation: Record<ParkReason, string> = {\n \"all-blocked\":\n \"Every resource in the tier is currently unavailable, so the turn ran without Adaptive routing.\",\n \"no-candidates\":\n \"There are no models configured for this tier, so the turn ran without Adaptive routing.\",\n \"no-compatible-resource\":\n \"No configured resource fits this turn's requirements, so the turn ran without Adaptive routing.\",\n \"pin-blocked\": \"The pinned resource is unavailable and no fallback is allowed while pinned.\",\n}\n\n/** Receipts shown per dialog page (bounded view). */\nexport const RECEIPTS_PAGE_SIZE = 20\n\nexport function receiptPage(receipts: readonly Receipt[]): Receipt[] {\n return receipts.slice(0, RECEIPTS_PAGE_SIZE)\n}\n","/**\n * The `/adaptive` keyboard-flow controller (ADP-033): a pure-ish state machine\n * over two seams — the typed RPC API and the host dialogs/toasts. It holds no\n * local settings state: every mutation goes through `settings.set` and the\n * returned snapshot becomes the new local view (the server is the single\n * source of truth, ADP-036).\n *\n * Flow contract: `undefined` selections always mean \"cancel this step\" — the\n * menu loop continues or exits; API failures toast and keep the loop alive.\n */\nimport type { OperatingMode } from \"../routing/scheduler/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { ModelRef } from \"../routing/work-unit/types.js\"\nimport type { SettingsPatch, SettingsV1 } from \"../state/settings/index.js\"\nimport type { PatchResult } from \"../state/settings/types.js\"\nimport type { SessionModeSetResult } from \"../state/session-modes/index.js\"\nimport type { TierRequestSetResult } from \"../state/tier-requests/types.js\"\nimport type { Receipt } from \"../state/receipts/types.js\"\nimport type { StatusSnapshot } from \"../status.js\"\nimport { STATUS_EMPTY_MESSAGE, statusTable, compactStatus } from \"./status.js\"\nimport {\n mainMenuOptions,\n modeOptions,\n modeTargetOptions,\n sessionModeOptions,\n sessionTierOptions,\n type MainMenuChoice,\n} from \"./menu.js\"\nimport {\n modelPickerOptions,\n moveResource,\n moveResourceToTop,\n removeResource,\n resourceLabel,\n tierEditorOptions,\n tierMenuOptions,\n variantOptions,\n type ModelSummary,\n} from \"./tiers.js\"\nimport { errorText, type SelectOption } from \"./options.js\"\nimport type { HostCopy } from \"./host-copy.js\"\nimport { receiptDetail, receiptLine, receiptPage, RECEIPTS_PAGE_SIZE } from \"./receipts.js\"\n\nexport interface AdaptiveView {\n select<Value>(options: {\n title: string\n placeholder?: string\n options: readonly SelectOption<Value>[]\n }): Promise<Value | undefined>\n /** A select with footer actions (page flips): the action closes the\n * dialog and is reported separately from an option pick. */\n selectPaged<Value>(spec: {\n title: string\n options: readonly { title: string; value: Value }[]\n actions: readonly { title: string; value: string; bind: string }[]\n }): Promise<{ picked: Value | undefined; action: string | undefined }>\n confirm(options: { title: string; message: string }): Promise<boolean | undefined>\n alert(options: { title: string; message: string }): Promise<void>\n /** A column-aligned text table (header row first); Escape closes it. */\n table(spec: { title: string; lines: string[]; compactLines?: string[] }): Promise<void>\n toast(message: string, variant: \"success\" | \"error\"): void\n}\n\nexport interface AdaptiveApi {\n settings: () => Promise<SettingsV1>\n setSettings: (patch: SettingsPatch) => Promise<PatchResult>\n status: () => Promise<StatusSnapshot>\n receipts: () => Promise<Receipt[]>\n /** The session's mode override (`null` = follows the global mode). */\n sessionMode: (sessionID: string) => Promise<OperatingMode | null>\n setSessionMode: (sessionID: string, mode: OperatingMode | null) => Promise<SessionModeSetResult>\n /** The session's pinned tier request (`null` = follows the routing ladder). */\n tierRequest: (sessionID: string) => Promise<TierName | null>\n setTierRequest: (sessionID: string, tier: string | null) => Promise<TierRequestSetResult>\n}\n\nexport type ModelLister = () => readonly ModelSummary[]\n\nexport interface AdaptiveEnv {\n copy: HostCopy\n api: AdaptiveApi\n view: AdaptiveView\n models: ModelLister\n /**\n * The session the command was opened from (ADP-054). Present only when the\n * palette command ran inside a session screen — the mode menu then steers\n * that session's override instead of the global mode.\n */\n sessionID?: string | undefined\n /** Pi exposes these local operations; hosts without them keep the original menu. */\n actions?: {\n health(): Promise<void>\n parked(): Promise<void>\n doctor(): Promise<void>\n preferences(): Promise<void>\n defaults(): Promise<void>\n }\n}\n\nexport const INVITE_MESSAGE =\n \"Adaptive starts in Observe mode: routing decisions are recorded as receipts, \" +\n \"but no model is switched. Open /adaptive to configure tiers or switch to Active.\"\n\n/** Tracks whether this dialog session already showed the save toast. */\nexport interface SaveFeedback {\n once: boolean\n}\n\n/** Run one API call; on failure toast and return undefined. */\nasync function tryApi<T>(env: AdaptiveEnv, run: () => Promise<T>): Promise<T | undefined> {\n try {\n return await run()\n } catch (error) {\n env.view.toast(errorText(error), \"error\")\n return undefined\n }\n}\n\n/**\n * Apply one patch; alert on validation errors, toast on success. The host\n * never auto-dismisses toasts, so the success toast is shown only on the\n * first successful save of a dialog session — later saves stay silent\n * (the updated menu already reflects them).\n */\nasync function applySettings(\n env: AdaptiveEnv,\n patch: SettingsPatch,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const result = await tryApi(env, () => env.api.setSettings(patch))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid settings\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result.settings\n}\n\n/**\n * Persist one session-mode override; alert on errors, toast on success. Same\n * once-toast semantics as `applySettings` — the success toast is shown only\n * on the first successful save of a dialog session.\n */\nasync function applySessionMode(\n env: AdaptiveEnv,\n sessionID: string,\n mode: OperatingMode | null,\n feedback: SaveFeedback,\n): Promise<SessionModeSetResult | undefined> {\n const result = await tryApi(env, () => env.api.setSessionMode(sessionID, mode))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid settings\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result\n}\n\n/**\n * Persist one session tier request; alert on errors, toast on success. Same\n * once-toast semantics as `applySettings` — the success toast is shown only\n * on the first successful save of a dialog session.\n */\nasync function applyTierRequest(\n env: AdaptiveEnv,\n sessionID: string,\n tier: string | null,\n feedback: SaveFeedback,\n): Promise<TierRequestSetResult | undefined> {\n const result = await tryApi(env, () => env.api.setTierRequest(sessionID, tier))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid tier request\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result\n}\n\nexport async function runAdaptive(env: AdaptiveEnv, initial?: MainMenuChoice): Promise<void> {\n const loaded = await tryApi(env, () => env.api.settings())\n if (loaded === undefined) return\n let settings = loaded\n const feedback: SaveFeedback = { once: false }\n const sessionID = env.sessionID\n // The session's current override: fetched once when the flow starts inside\n // a session; a failure degrades to \"follow global\" (the menu still works).\n let override: OperatingMode | null =\n sessionID === undefined\n ? null\n : ((await tryApi(env, () => env.api.sessionMode(sessionID))) ?? null)\n if (!settings.inviteDismissed) {\n await env.view.confirm({ title: env.copy.inviteTitle, message: INVITE_MESSAGE })\n const pick = await env.view.select({\n title: env.copy.inviteTitle,\n options: [\n { title: \"Open the menu now\", value: true },\n { title: \"Later\", value: false },\n ],\n })\n const dismissed = await applySettings(env, { inviteDismissed: true }, feedback)\n if (dismissed !== undefined) settings = dismissed\n if (pick !== true) return\n }\n let next = initial\n for (;;) {\n // Fresh status and settings on every pass: the menu rows pair the two,\n // and the server is the single source of truth (ADP-036). A failed read\n // degrades silently to the last known values — the menu descriptions\n // must not spam a toast on every loop iteration (the flows that need\n // status toast through tryApi themselves).\n const [freshSettings, status] = await Promise.all([\n env.api.settings().catch(() => undefined),\n env.api.status().catch(() => undefined),\n ])\n if (freshSettings !== undefined) settings = freshSettings\n // The session's pinned tier request: fetched per loop so the entry\n // description tracks the latest request; a failure degrades to the\n // generic description (the menu still works).\n const tierPinned =\n sessionID === undefined\n ? undefined\n : await env.api.tierRequest(sessionID).catch(() => undefined)\n const choice =\n next ??\n (await env.view.select<\n MainMenuChoice | \"health\" | \"parked\" | \"doctor\" | \"preferences\" | \"defaults\"\n >({\n title: `Adaptive (${override ?? settings.mode})`,\n options: [\n ...mainMenuOptions(settings, status, tierPinned, override ?? settings.mode),\n ...(env.actions === undefined\n ? []\n : [\n {\n title: \"Health\",\n value: \"health\" as const,\n description: \"inspect or reset resource health\",\n },\n {\n title: \"Parked work\",\n value: \"parked\" as const,\n description: \"resume or cancel waiting work\",\n },\n {\n title: \"Doctor\",\n value: \"doctor\" as const,\n description: \"check setup and compatibility\",\n },\n {\n title: \"Preferences\",\n value: \"preferences\" as const,\n description: \"transcript notes and pinned-tier escalation\",\n },\n {\n title: \"Use Adaptive for new sessions\",\n value: \"defaults\" as const,\n description: \"Pi settings to copy\",\n },\n ]),\n ],\n }))\n next = undefined\n if (choice === undefined) return\n if (\n choice === \"health\" ||\n choice === \"parked\" ||\n choice === \"doctor\" ||\n choice === \"preferences\" ||\n choice === \"defaults\"\n ) {\n await tryApi(env, async () => {\n await env.actions?.[choice]()\n })\n continue\n }\n if (choice === \"status\") {\n await runStatusView(env)\n continue\n }\n if (choice === \"models\") {\n settings = (await runTierEditor(env, feedback)) ?? settings\n continue\n }\n if (choice === \"mode\") {\n const next = await runModeMenu(env, settings, feedback, sessionID, override)\n if (next !== undefined) {\n settings = next.settings\n override = next.override\n }\n continue\n }\n if (choice === \"tier\") {\n if (sessionID === undefined) {\n // The tier request only exists inside a session; on home the pick is\n // explained (not silently dropped) and the menu re-opens.\n await env.view.alert({\n title: \"This session\",\n message:\n \"This session's tier request can only be changed inside a session. Open a session and run /adaptive from there.\",\n })\n continue\n }\n await runTierRequestMenu(env, sessionID, feedback)\n continue\n }\n if (choice === \"pin\") {\n settings = (await runPinMenu(env, settings, feedback)) ?? settings\n continue\n }\n await runReceiptsView(env)\n }\n}\n\n/** What one mode-menu pass changed (settings and/or the session override). */\ninterface ModeMenuOutcome {\n settings: SettingsV1\n override: OperatingMode | null\n}\n\nasync function runModeMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n feedback: SaveFeedback,\n sessionID: string | undefined,\n override: OperatingMode | null,\n): Promise<ModeMenuOutcome | undefined> {\n // Every screen gets the same first question — which mode to steer — so a\n // user who opens the menu on home learns the two-level structure before\n // they ever run the command inside a session.\n for (;;) {\n const target = await env.view.select({\n title: \"Operating mode\",\n options: modeTargetOptions(settings.mode, override ?? settings.mode),\n })\n if (target === undefined) return undefined\n if (target === \"global\") {\n const pick = await env.view.select({\n title: \"Global mode\",\n options: modeOptions(settings.mode),\n })\n if (pick === undefined || pick === settings.mode) return undefined\n const applied = await applySettings(env, { mode: pick }, feedback)\n // The session override is deliberately untouched: changing the global\n // default must not rewrite what a session was pinned to.\n return applied === undefined ? undefined : { settings: applied, override }\n }\n if (sessionID === undefined) {\n // The session override only exists inside a session; on home the pick\n // is explained (not silently dropped) and the target question repeats.\n await env.view.alert({\n title: \"This session\",\n message:\n \"This session's mode can only be changed inside a session. Open a session and run /adaptive from there.\",\n })\n continue\n }\n const pick = await env.view.select({\n title: \"This session's mode\",\n options: sessionModeOptions({\n global: settings.mode,\n override,\n effective: override ?? settings.mode,\n }),\n })\n if (pick === undefined) return undefined\n if (pick.kind === \"global\") {\n if (override === null) return undefined\n const saved = await applySessionMode(env, sessionID, null, feedback)\n return saved === undefined ? undefined : { settings, override: null }\n }\n if (pick.mode === (override ?? settings.mode)) return undefined\n const saved = await applySessionMode(env, sessionID, pick.mode, feedback)\n return saved === undefined ? undefined : { settings, override: pick.mode }\n }\n}\n\n/** The per-session tier-request menu (ADP-055): pin a tier or clear it. */\nasync function runTierRequestMenu(\n env: AdaptiveEnv,\n sessionID: string,\n feedback: SaveFeedback,\n): Promise<void> {\n const pinned = await tryApi(env, () => env.api.tierRequest(sessionID))\n if (pinned === undefined) return\n const pick = await env.view.select({\n title: \"This session's tier\",\n options: sessionTierOptions({ pinned }),\n })\n if (pick === undefined) return\n const next = pick.kind === \"ladder\" ? null : pick.tier\n if (next === pinned) return\n await applyTierRequest(env, sessionID, next, feedback)\n}\n\n/**\n * The status view: every configured model with its state as a column-aligned\n * table (header row, tier order, priority order within tiers). No\n * per-resource selection step — the table IS the view; Escape returns to the\n * menu.\n */\nasync function runStatusView(env: AdaptiveEnv): Promise<void> {\n const snapshot = await tryApi(env, () => env.api.status())\n if (snapshot === undefined) return\n const configured = TIERS.some((tier) => snapshot.tiers[tier].length > 0)\n if (!configured) {\n await env.view.alert({ title: \"Status\", message: STATUS_EMPTY_MESSAGE })\n return\n }\n await env.view.table({\n title: \"Status\",\n lines: statusTable(snapshot),\n compactLines: compactStatus(snapshot),\n })\n}\n\ntype TierEditorOutcome = SettingsV1 | undefined\n\nasync function runTierEditor(env: AdaptiveEnv, feedback: SaveFeedback): Promise<TierEditorOutcome> {\n // The last confirmed server snapshot from this editor session, returned\n // when the editor closes so the menu view stays in sync with the server.\n let saved: SettingsV1 | undefined\n for (;;) {\n // The server is the single source of truth (ADP-036): settings and\n // status are re-fetched on every tier-list pass — entering the editor\n // and after each Escape out of a tier page — so an edit can never\n // clobber a change made outside this dialog. A failed read toasts and\n // closes the editor: the tier list cannot render meaningfully without\n // them.\n const settings = await tryApi(env, () => env.api.settings())\n if (settings === undefined) return saved\n const status = await tryApi(env, () => env.api.status())\n if (status === undefined) return saved\n const tier = await env.view.select({ title: \"Tier\", options: tierMenuOptions(status) })\n if (tier === undefined) return saved\n let pageStatus = status\n let pageSettings = settings\n // The tier page owns the loop until Escape: an add, move, or remove\n // re-opens this page instead of bouncing back to the tier list, so\n // consecutive edits on one tier stay in context. The page's settings\n // and status carry across iterations: each action's save response\n // updates them for the next render.\n for (;;) {\n const choice = await env.view.select({\n title: `Tier: ${tier}`,\n options: tierEditorOptions(pageSettings, tier, pageStatus, env.copy.modelSearchPlaceholder),\n })\n if (choice === undefined) break\n if (choice.kind === \"add\") {\n const next = await runAddModel(env, pageSettings, tier, feedback)\n if (next !== undefined) {\n saved = next\n pageSettings = next\n }\n } else {\n const next = await runResourceMenu(env, pageSettings, tier, choice, feedback)\n if (next !== undefined) {\n saved = next\n pageSettings = next\n }\n }\n // The rows re-pair with the server after every action; a failed read\n // keeps the last known values so the page still renders (the save\n // already reported itself — a failed cosmetic refresh must neither\n // spam a toast nor bounce the page).\n const [freshSettings, freshStatus] = await Promise.all([\n env.api.settings().catch(() => undefined),\n env.api.status().catch(() => undefined),\n ])\n if (freshSettings !== undefined) {\n saved = freshSettings\n pageSettings = freshSettings\n }\n if (freshStatus !== undefined) pageStatus = freshStatus\n }\n }\n}\n\nasync function runAddModel(\n env: AdaptiveEnv,\n settings: SettingsV1,\n tier: TierName,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const models = env.models()\n const pick = await env.view.select({\n title: \"Add model\",\n placeholder: \"Search provider / model / name\",\n options: modelPickerOptions(models),\n })\n if (pick === undefined) return undefined\n const variants = pick.variants\n let variant: string | undefined\n if (variants.length > 0) {\n const choice = await env.view.select({\n title: `Variant: ${pick.providerID}/${pick.modelID}`,\n options: variantOptions(variants),\n })\n if (choice === undefined) return undefined\n variant = choice.variant\n }\n const ref: ModelRef =\n variant === undefined\n ? { providerID: pick.providerID, id: pick.modelID }\n : { providerID: pick.providerID, id: pick.modelID, variant }\n const list = [...settings.tiers[tier], ref]\n return applySettings(env, { tiers: { ...settings.tiers, [tier]: list } }, feedback)\n}\n\ntype ResourceMenuChoice = \"top\" | \"up\" | \"down\" | \"remove\"\n\nfunction resourceMenuOptions(): SelectOption<ResourceMenuChoice>[] {\n return [\n { title: \"Move to top\", value: \"top\", description: \"Make this the primary resource\" },\n { title: \"Move up\", value: \"up\", description: \"Higher priority within the tier\" },\n { title: \"Move down\", value: \"down\", description: \"Lower priority within the tier\" },\n { title: \"Remove\", value: \"remove\" },\n ]\n}\n\nasync function runResourceMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n tier: TierName,\n { index, ref }: { index: number; ref: ModelRef },\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const pick = await env.view.select({\n title: `Resource: ${resourceLabel(ref)}`,\n options: resourceMenuOptions(),\n })\n if (pick === undefined) return undefined\n if (pick === \"remove\") {\n const confirmed = await env.view.confirm({\n title: \"Remove resource\",\n message: `Remove ${resourceLabel(ref)} from ${tier}?`,\n })\n if (confirmed !== true) return undefined\n return applySettings(\n env,\n { tiers: { ...settings.tiers, [tier]: removeResource(settings.tiers[tier], index) } },\n feedback,\n )\n }\n const list =\n pick === \"top\"\n ? moveResourceToTop(settings.tiers[tier], index)\n : moveResource(settings.tiers[tier], index, pick === \"up\" ? -1 : 1)\n return applySettings(env, { tiers: { ...settings.tiers, [tier]: list } }, feedback)\n}\n\ntype PinChoice = { kind: \"clear\" } | { kind: \"pin\"; ref: ModelRef }\n\nfunction pinOptions(settings: SettingsV1): SelectOption<PinChoice>[] {\n const options: SelectOption<PinChoice>[] = [\n { title: \"No pin\", value: { kind: \"clear\" }, description: \"clear the pin\" },\n ]\n for (const tier of TIERS) {\n for (const ref of settings.tiers[tier]) {\n options.push({\n title: `${resourceLabel(ref)} (${tier})`,\n description: \"route every turn to this resource, even in active mode\",\n value: { kind: \"pin\", ref },\n })\n }\n }\n return options\n}\n\nasync function runPinMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const configured = TIERS.some((tier) => settings.tiers[tier].length > 0)\n if (!configured) {\n await env.view.alert({ title: \"Pin\", message: \"(no configured resources to pin)\" })\n return undefined\n }\n const pick = await env.view.select({ title: \"Pin\", options: pinOptions(settings) })\n if (pick === undefined) return undefined\n return applySettings(env, { pin: pick.kind === \"clear\" ? null : pick.ref }, feedback)\n}\n\nasync function runReceiptsView(env: AdaptiveEnv): Promise<void> {\n const all = await tryApi(env, () => env.api.receipts())\n if (all === undefined) return\n if (all.length === 0) {\n await env.view.alert({\n title: \"Receipts\",\n message: \"No decisions recorded yet.\",\n })\n return\n }\n // Paginated browse: every page is a bounded view, and the page flips are\n // footer actions (not list items) — they close the dialog and the loop\n // reopens it at the new offset. Viewing a detail returns to the same\n // page; Escape (no pick, no action) leaves the browser.\n for (let offset = 0; ;) {\n const page = receiptPage(all.slice(offset))\n const hasNext = offset + RECEIPTS_PAGE_SIZE < all.length\n const result = await env.view.selectPaged({\n title: `Receipts (${String(all.length)}, newest first)`,\n options: page.map((receipt) => ({ title: receiptLine(receipt), value: receipt })),\n actions: [\n ...(offset > 0 ? [{ title: \"Previous page\", value: \"prev\", bind: \"ctrl+b\" }] : []),\n ...(hasNext ? [{ title: \"Next page\", value: \"next\", bind: \"ctrl+f\" }] : []),\n ],\n })\n if (result.action === \"next\") {\n offset += RECEIPTS_PAGE_SIZE\n continue\n }\n if (result.action === \"prev\") {\n offset = Math.max(0, offset - RECEIPTS_PAGE_SIZE)\n continue\n }\n const pick = result.picked\n if (pick === undefined) return\n await env.view.alert({\n title: `Receipt #${String(pick.id)}`,\n message: receiptDetail(pick, env.copy),\n })\n }\n}\n\n/** Exported for tests: the receipts page size used by the receipts browser. */\nexport { RECEIPTS_PAGE_SIZE }\n\nexport type {\n MainMenuChoice,\n OperatingMode,\n StatusSnapshot,\n SettingsV1,\n SettingsPatch,\n PatchResult,\n Receipt,\n}\n","import type { AdaptiveEnv } from \"@coool/adaptive-core/flow/controller\"\nimport { runAdaptive } from \"@coool/adaptive-core/flow/controller\"\nimport { receiptDetail } from \"@coool/adaptive-core/flow/receipts\"\nimport { PI_COPY } from \"../ui/copy.js\"\n\nexport const SUBCOMMANDS = [\n \"status\",\n \"why\",\n \"tiers\",\n \"health\",\n \"resume\",\n \"cancel\",\n \"observe on\",\n \"observe off\",\n \"doctor\",\n] as const\ninterface CommandContext {\n readonly hasUI: boolean\n readonly ui: { notify(message: string, type: \"warning\" | \"error\" | \"info\"): void }\n}\ninterface CommandOptions<C> {\n env(ctx: C): Promise<AdaptiveEnv>\n resume(ctx: C): Promise<void>\n cancel(ctx: C): Promise<void>\n clock(): number\n}\ninterface CommandHost<C> {\n registerCommand(\n name: string,\n options: {\n description: string\n getArgumentCompletions(prefix: string): { value: string; label: string }[]\n handler(args: string, ctx: C & { waitForIdle(): Promise<void> }): Promise<void>\n },\n ): void\n registerShortcut(\n key: \"ctrl+alt+a\",\n options: {\n description: string\n handler(ctx: C & { isIdle(): boolean }): Promise<void>\n },\n ): void\n}\n\nexport async function runCommand<C extends CommandContext>(\n args: string,\n ctx: C,\n options: CommandOptions<C>,\n): Promise<void> {\n if (!ctx.hasUI) {\n ctx.ui.notify(\"Open /adaptive in an interactive or RPC session.\", \"warning\")\n return\n }\n const command = args.trim().replace(/\\s+/g, \" \")\n const env = await options.env(ctx)\n if (command === \"resume\") {\n await options.resume(ctx)\n return\n }\n if (command === \"cancel\") {\n await options.cancel(ctx)\n return\n }\n if (command === \"doctor\" || command === \"health\") {\n await env.actions?.[command]()\n return\n }\n if (command === \"observe on\" || command === \"observe off\") {\n const result = await env.api.setSettings({ mode: command === \"observe on\" ? \"observe\" : \"off\" })\n env.view.toast(\n result.ok\n ? \"Observation setting saved. Your selected model is unchanged.\"\n : result.errors.join(\"; \"),\n result.ok ? \"success\" : \"error\",\n )\n return\n }\n if (command === \"why\") {\n const latest = (await env.api.receipts()).find((receipt) => receipt.sessionID === env.sessionID)\n await env.view.alert({\n title: \"Latest decision\",\n message:\n latest === undefined\n ? \"No decisions recorded in this session yet.\"\n : receiptDetail(latest, PI_COPY, options.clock()),\n })\n return\n }\n if (command === \"\" || command === \"status\" || command === \"tiers\") {\n if (command === \"\") await runAdaptive(env, undefined)\n else await runAdaptive(env, command === \"tiers\" ? \"models\" : \"status\")\n return\n }\n env.view.toast(`Unknown adaptive command. Use: ${SUBCOMMANDS.join(\", \")}.`, \"error\")\n}\n\nexport function registerCommands<C extends CommandContext>(\n pi: CommandHost<C>,\n options: CommandOptions<C>,\n): void {\n pi.registerCommand(\"adaptive\", {\n description: \"Adaptive settings, decisions and diagnostics\",\n getArgumentCompletions: (prefix) =>\n SUBCOMMANDS.filter((command) => command.startsWith(prefix)).map((command) => ({\n value: command,\n label: command,\n })),\n async handler(args, ctx) {\n await ctx.waitForIdle()\n try {\n await runCommand(args, ctx, options)\n } catch {\n ctx.ui.notify(\n \"Adaptive could not open. Run /adaptive doctor; your model is unchanged.\",\n \"error\",\n )\n }\n },\n })\n pi.registerShortcut(\"ctrl+alt+a\", {\n description: \"Open Adaptive\",\n async handler(ctx) {\n if (!ctx.isIdle()) {\n ctx.ui.notify(\"Wait for the current run before opening Adaptive.\", \"info\")\n return\n }\n try {\n await runCommand(\"\", ctx, options)\n } catch {\n ctx.ui.notify(\n \"Adaptive could not open. Run /adaptive doctor; your model is unchanged.\",\n \"error\",\n )\n }\n },\n })\n}\n","import type { AdaptiveApi } from \"@coool/adaptive-core/flow/controller\"\nimport type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { isTierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { StatusSnapshot } from \"@coool/adaptive-core/status\"\nimport { readSettings, updateSettings } from \"../settings.js\"\nimport { readReceipts } from \"../receipts.js\"\nimport { effectiveMode, requestedTier, SESSION_ENTRY, sessionModeOverride } from \"../session.js\"\nimport type { BranchEntry } from \"../task.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\n\nexport interface ControlOptions {\n readonly settings: JsonFile\n readonly receipts: JsonTransactionFile\n readonly sessionID: string\n readonly branch: () => readonly BranchEntry[]\n readonly model: () => { readonly provider: string; readonly id: string } | undefined\n readonly manualModel: () => ModelRef | undefined\n readonly selectModel: (model: ModelRef) => Promise<boolean>\n readonly append: (type: string, data: unknown) => void\n readonly idle: () => boolean\n readonly status: () => Promise<StatusSnapshot>\n}\n\n/** In-process binding of the shared flow; no second settings or routing state. */\nexport function controlApi(options: ControlOptions): AdaptiveApi {\n const validSession = (id: string) => id === options.sessionID && id.trim() !== \"\"\n return {\n settings: () => readSettings(options.settings),\n setSettings: (patch) => updateSettings(options.settings, patch),\n status: options.status,\n receipts: () => readReceipts(options.receipts),\n async sessionMode(id) {\n if (!validSession(id))\n throw new Error(\"Adaptive sessionID: this command belongs to another session\")\n const settings = await readSettings(options.settings)\n return options.model()?.provider === \"adaptive\"\n ? effectiveMode(options.model(), settings.mode, options.branch())\n : sessionModeOverride(options.branch())\n },\n async setSessionMode(id, mode) {\n if (!validSession(id)) return { ok: false, errors: [\"invalid sessionID\"] }\n if (!options.idle())\n return { ok: false, errors: [\"Wait for the current run before changing its mode.\"] }\n const settings = await readSettings(options.settings)\n const next: OperatingMode = mode ?? settings.mode\n const selected = options.model()\n let target: ModelRef | undefined\n if (next === \"active\") target = { providerID: \"adaptive\", id: \"auto\" }\n else if (selected?.provider === \"adaptive\") target = options.manualModel()\n if (next !== \"active\" && selected?.provider === \"adaptive\" && target === undefined)\n return {\n ok: false,\n errors: [\"Pick a normal model in Pi's model picker to pause Adaptive.\"],\n }\n if (target !== undefined && !(await options.selectModel(target)))\n return {\n ok: false,\n errors: [\"Model could not be selected. Check credentials with /adaptive doctor.\"],\n }\n options.append(SESSION_ENTRY, { version: 1, mode })\n return { ok: true }\n },\n tierRequest(id) {\n if (!validSession(id))\n return Promise.reject(\n new Error(\"Adaptive sessionID: this command belongs to another session\"),\n )\n return Promise.resolve(requestedTier(options.branch()))\n },\n setTierRequest(id, tier) {\n if (!validSession(id)) return Promise.resolve({ ok: false, errors: [\"invalid sessionID\"] })\n if (tier !== null && !isTierName(tier))\n return Promise.resolve({\n ok: false,\n errors: [\"invalid tier: expected quick, standard, advanced, or null\"],\n })\n options.append(SESSION_ENTRY, { version: 1, tier })\n return Promise.resolve({ ok: true })\n },\n }\n}\n","import type { ModelRegistry } from \"@earendil-works/pi-coding-agent\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport { VIRTUAL_IDS } from \"../router.js\"\nimport { versionChecks, type DoctorCheck } from \"../ui/doctor.js\"\n\nexport interface DoctorOptions {\n readonly version: string\n readonly minimum: string\n readonly testedUpTo: string | undefined\n readonly registry: Pick<\n ModelRegistry,\n \"getAll\" | \"find\" | \"hasConfiguredAuth\" | \"getRegisteredProviderConfig\"\n >\n readonly settings: () => Promise<SettingsV1>\n readonly capabilities: () => Promise<readonly ToolCapability[]>\n readonly storage: () => Promise<void>\n readonly health: () => Promise<number>\n readonly parked: () => Promise<number>\n}\n\n/** Probe failures use fixed copy: upstream errors/configs may contain credentials. */\nexport async function doctorChecks(options: DoctorOptions): Promise<DoctorCheck[]> {\n const checks = versionChecks(options.version, options.minimum, options.testedUpTo)\n const missing = VIRTUAL_IDS.filter((id) => options.registry.find(\"adaptive\", id) === undefined)\n checks.push(\n missing.length === 0\n ? { state: \"ok\", message: \"All four Adaptive models registered\" }\n : {\n state: \"error\",\n message: `Missing Adaptive models: ${missing.join(\", \")}`,\n action: \"Reload Pi with the Adaptive extension enabled.\",\n },\n )\n try {\n const settings = await options.settings()\n const capabilities = await options.capabilities()\n const credentialed: string[] = []\n const undeclared = new Set<string>()\n for (const tier of TIERS) {\n if (settings.tiers[tier].length === 0)\n checks.push({\n state: \"warning\",\n message: `${tier}: no configured models`,\n action: \"Open /adaptive tiers to add a model.\",\n })\n for (const ref of settings.tiers[tier]) {\n const model = options.registry.find(ref.providerID, ref.id)\n if (model === undefined)\n checks.push({\n state: \"error\",\n message: `${resourceLabel(ref)} (${tier}): model missing`,\n action: \"Refresh Pi's model catalog or remove this tier entry.\",\n })\n else if (!options.registry.hasConfiguredAuth(model))\n checks.push({\n state: \"error\",\n message: `${resourceLabel(ref)} (${tier}): no credentials configured`,\n action: `Run /login ${ref.providerID}, or remove it from the tier.`,\n })\n else credentialed.push(resourceLabel(ref))\n if (\n !capabilities.some(\n (entry) => entry.providerID === ref.providerID && entry.id === ref.id && entry.tools,\n )\n )\n undeclared.add(resourceLabel(ref))\n }\n }\n if (credentialed.length > 0)\n checks.push({\n state: \"ok\",\n message: `Credentials configured for ${String(credentialed.length)} tier ${credentialed.length === 1 ? \"model\" : \"models\"}`,\n })\n if (undeclared.size > 0)\n checks.push({\n state: \"warning\",\n message: `Tool support not declared: ${[...undeclared].join(\", \")}`,\n action: \"List them in adaptive/capabilities.json; Adaptive never guesses from a name.\",\n })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Settings or capabilities could not be read\",\n action:\n \"Inspect adaptive/settings.json and capabilities.json; corrupt files were not replaced.\",\n })\n }\n try {\n await options.storage()\n checks.push({ state: \"ok\", message: \"Shared storage writable; exclusive lock works\" })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Shared storage or lock unavailable\",\n action: \"Check permissions and other Pi processes in the agent's adaptive directory.\",\n })\n }\n const models = options.registry.getAll()\n const virtuals = models.filter(\n (model) => model.api === \"pi-virtual\" && model.provider !== \"adaptive\",\n )\n for (const model of virtuals)\n checks.push({\n state: \"warning\",\n message: `Other router model: ${model.provider}/${model.id}`,\n action: \"Use one router for a session; do not put another virtual model in Adaptive tiers.\",\n })\n for (const provider of new Set(models.map((model) => model.provider))) {\n if (provider === \"adaptive\") continue\n if (options.registry.getRegisteredProviderConfig(provider)?.streamSimple !== undefined)\n checks.push({\n state: \"warning\",\n message: `Custom request handler: ${provider}`,\n action:\n \"If this handler routes requests too, use one router. No conflict is assumed from a handler alone.\",\n })\n }\n try {\n const limited = await options.health()\n checks.push({\n state: \"ok\",\n message:\n limited === 0\n ? \"Health: no resources limited\"\n : `Health: ${String(limited)} ${limited === 1 ? \"resource\" : \"resources\"} limited`,\n ...(limited === 0\n ? {}\n : { action: \"Inspect /adaptive health; reset only after checking the provider.\" }),\n })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Shared health could not be read\",\n action: \"Inspect adaptive/health.json; do not delete it while another Pi process is running.\",\n })\n }\n try {\n const parked = await options.parked()\n checks.push({\n state: \"ok\",\n message:\n parked === 0\n ? \"No parked work\"\n : `${String(parked)} parked ${parked === 1 ? \"task\" : \"tasks\"}`,\n ...(parked === 0\n ? {}\n : { action: \"Use /adaptive resume or /adaptive cancel in the waiting session.\" }),\n })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Parked work could not be read\",\n action: \"Inspect adaptive/parked.json before resuming; no task was dispatched.\",\n })\n }\n return checks\n}\n","// covers: [\"ADP-004\", \"ADP-005\", \"ADP-063\"]\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { MAX_TIER_RESOURCES, type SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\n\nexport interface ProposalModel {\n readonly ref: ModelRef\n readonly inputCost: number\n readonly outputCost: number\n readonly reasoning: boolean\n readonly contextWindow: number\n readonly thinkingLevels: readonly string[]\n}\n\nfunction identity(model: ProposalModel): string {\n return JSON.stringify([model.ref.providerID, model.ref.id])\n}\n\nfunction cost(model: ProposalModel): number {\n const sum = model.inputCost + model.outputCost\n return Number.isFinite(sum) && model.inputCost >= 0 && model.outputCost >= 0 ? sum : Infinity\n}\n\nfunction order(left: ProposalModel, right: ProposalModel): number {\n const a = cost(left)\n const b = cost(right)\n if (a !== b) return a < b ? -1 : 1\n const l = identity(left)\n const r = identity(right)\n if (l !== r) return l < r ? -1 : 1\n return (\n Number(left.reasoning) - Number(right.reasoning) ||\n left.contextWindow - right.contextWindow ||\n Number(left.thinkingLevels.includes(\"high\")) - Number(right.thinkingLevels.includes(\"high\"))\n )\n}\n\n/** Settings bootstrap only: never consulted during routing, and never persists. */\nexport function proposeTiers(models: readonly ProposalModel[]): SettingsV1[\"tiers\"] {\n const unique = new Map<string, ProposalModel>()\n for (const model of [...models].sort(order)) unique.set(identity(model), model)\n const ordered = [...unique.values()]\n const first = Math.ceil(ordered.length / 3)\n const second = Math.ceil((ordered.length * 2) / 3)\n const refs = (group: readonly ProposalModel[], advanced: boolean): ModelRef[] =>\n group.slice(0, MAX_TIER_RESOURCES).map((model) => ({\n providerID: model.ref.providerID,\n id: model.ref.id,\n ...(advanced && model.reasoning && model.thinkingLevels.includes(\"high\")\n ? { variant: \"high\" }\n : {}),\n }))\n return {\n quick: refs(ordered.slice(0, first), false),\n standard: refs(ordered.slice(first, second), false),\n advanced: refs(\n ordered\n .slice(second)\n .sort(\n (a, b) =>\n Number(b.reasoning) - Number(a.reasoning) ||\n b.contextWindow - a.contextWindow ||\n order(a, b),\n ),\n true,\n ),\n }\n}\n","/**\n * Status snapshot for the control surfaces (ADP-033): a bounded, secret-free\n * view of the settings and the resource-health state of every configured\n * resource. Pure — the supervisor (or any future caller) gathers the inputs.\n */\nimport type { OperatingMode } from \"./routing/scheduler/types.js\"\nimport { schedulerHealthKey } from \"./routing/scheduler/index.js\"\nimport type { ModelRef } from \"./routing/work-unit/types.js\"\nimport type { TierName } from \"./routing/tier-policy/types.js\"\nimport { TIERS } from \"./routing/tier-policy/types.js\"\nimport type { ResourceRecord } from \"./health/resource-health/types.js\"\nimport type { CapacityReading } from \"./health/capacity/types.js\"\nimport { resourceKeyID } from \"./health/resource-health/index.js\"\nimport type { SettingsV1 } from \"./state/settings/index.js\"\n\nexport interface TierResourceStatus {\n ref: ModelRef\n health: ResourceRecord[\"health\"]\n breaker: ResourceRecord[\"breaker\"][\"state\"]\n windowed: boolean\n /**\n * Wall-clock deadline of the active window (ms epoch); null when unwindowed.\n * Null — not undefined: the host RPC encoder rejects JSON objects carrying a\n * present-but-undefined key (\"Expected JSON value\"), which 500'd every\n * status.get once any resource was configured.\n */\n windowUntil: number | null\n /** Used capacity as a rounded whole percent; null when no reading exists. */\n usedPercent: number | null\n /** Wall-clock capacity reset deadline (ms epoch); null when unread. */\n resetAt: number | null\n}\n\n/** A session whose parked work waits for its tier to recover (ADP-024). */\nexport interface WaitingSession {\n sessionID: string\n tier: TierName\n /** When the wake resumes it (ms epoch); null when no resource states a reset. */\n resumeAt: number | null\n}\n\nexport interface StatusSnapshot {\n mode: OperatingMode\n pin: ModelRef | null\n tiers: Readonly<Record<TierName, readonly TierResourceStatus[]>>\n parked: number\n waiting: readonly WaitingSession[]\n receipts: number\n}\n\nexport function buildStatus(input: {\n settings: SettingsV1\n health: readonly ResourceRecord[]\n capacity: Readonly<Record<string, CapacityReading | null>>\n parked: number\n waiting: readonly WaitingSession[]\n receipts: number\n}): StatusSnapshot {\n const byKey = new Map<string, ResourceRecord>()\n for (const record of input.health) byKey.set(resourceKeyID(record.key), record)\n const tiers = {} as Record<TierName, TierResourceStatus[]>\n for (const tier of TIERS) {\n tiers[tier] = input.settings.tiers[tier].map((ref) => {\n const record = byKey.get(schedulerHealthKey(ref))\n const capacityReading = input.capacity[schedulerHealthKey(ref)] ?? null\n return {\n ref,\n health: record?.health ?? \"healthy\",\n breaker: record?.breaker.state ?? \"closed\",\n windowed: record?.window !== undefined,\n windowUntil: record?.window?.until ?? null,\n usedPercent: capacityUsedPercent(capacityReading),\n resetAt: capacityReading?.resetAt ?? null,\n }\n })\n }\n return {\n mode: input.settings.mode,\n pin: input.settings.pin,\n tiers,\n parked: input.parked,\n waiting: input.waiting,\n receipts: input.receipts,\n }\n}\n\n/**\n * Derives the used-capacity percentage from a reading. Readings may carry any\n * subset of the two ratios: usedRatio directly, or the remainder inferred from\n * remainingRatio. A reading with neither ratio is still present (confidence,\n * resetAt may be set) but yields no percentage — null, not undefined.\n */\nfunction capacityUsedPercent(reading: CapacityReading | null): number | null {\n if (reading?.usedRatio !== undefined) return Math.round(reading.usedRatio * 100)\n if (reading?.remainingRatio !== undefined) return Math.round((1 - reading.remainingRatio) * 100)\n return null\n}\n","// covers: [\"ADP-032\", \"ADP-063\"]\nimport {\n runAdaptive,\n type AdaptiveApi,\n type AdaptiveEnv,\n type AdaptiveView,\n} from \"@coool/adaptive-core/flow/controller\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { proposeTiers, type ProposalModel } from \"../ui/proposal.js\"\nimport { migrateSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport { buildStatus } from \"@coool/adaptive-core/status\"\n\n/** The shared tier editor writes a local draft; only the wizard commits it. */\nexport async function editTierProposal(env: AdaptiveEnv, initial: SettingsV1): Promise<SettingsV1> {\n let draft = initial\n await runAdaptive(\n {\n copy: env.copy,\n view: env.view,\n models: env.models,\n api: {\n ...env.api,\n settings: () => Promise.resolve(draft),\n setSettings: (patch) => {\n draft = migrateSettings({ ...draft, ...patch })\n return Promise.resolve({ ok: true, settings: draft })\n },\n status: () =>\n Promise.resolve(\n buildStatus({\n settings: draft,\n health: [],\n capacity: {},\n parked: 0,\n waiting: [],\n receipts: 0,\n }),\n ),\n },\n },\n \"models\",\n )\n return draft\n}\n\nexport interface OnboardingOptions {\n readonly hasUI: boolean\n readonly api: Pick<AdaptiveApi, \"settings\" | \"setSettings\">\n readonly view: AdaptiveView\n readonly models: () => readonly ProposalModel[]\n readonly edit: (draft: SettingsV1) => Promise<SettingsV1>\n readonly activate: () => Promise<boolean>\n}\n\nexport async function runOnboarding(options: OnboardingOptions): Promise<void> {\n const current = await options.api.settings()\n if (current.inviteDismissed) return\n // Print and JSON runs keep stdout/stderr machine-clean; they observe by default.\n if (!options.hasUI) return\n let draft = {\n ...current,\n mode: \"observe\" as const,\n inviteDismissed: true,\n tiers: TIERS.some((tier) => current.tiers[tier].length > 0)\n ? current.tiers\n : proposeTiers(options.models()),\n }\n for (;;) {\n const summary = TIERS.map(\n (tier) =>\n `${tier}: ${draft.tiers[tier].map(resourceLabel).join(\" · \") || \"no models available\"}`,\n ).join(\"\\n\")\n const choice = await options.view.select({\n title: `Adaptive is installed\\n${summary}\\nTool support must be confirmed separately; /adaptive doctor checks it.`,\n options: [\n { title: \"Save tiers and use Adaptive this session\", value: \"use\" },\n { title: \"Save tiers, keep my current model\", value: \"save\" },\n { title: \"Edit suggested tiers…\", value: \"edit\" },\n { title: \"Not now\", value: \"later\" },\n ],\n })\n if (choice === \"edit\") {\n draft = { ...(await options.edit(draft)), mode: \"observe\", inviteDismissed: true }\n continue\n }\n if (choice !== \"save\" && choice !== \"use\") {\n await options.api.setSettings({ inviteDismissed: true })\n return\n }\n const confirmed = await options.view.confirm({\n title: \"Save these tiers?\",\n message: `${summary}\\nGlobal mode stays Observe. Nothing changes until you confirm.`,\n })\n if (confirmed !== true) continue\n const saved = await options.api.setSettings({\n tiers: draft.tiers,\n mode: \"observe\",\n inviteDismissed: true,\n })\n if (!saved.ok) {\n await options.view.alert({ title: \"Could not save tiers\", message: saved.errors.join(\"; \") })\n return\n }\n options.view.toast(\"Tiers saved\", \"success\")\n if (choice === \"use\" && !(await options.activate()))\n options.view.toast(\n \"Tiers saved, but Adaptive could not be selected. Open Pi's model picker.\",\n \"error\",\n )\n return\n }\n}\n","import { isDeepStrictEqual } from \"node:util\"\nimport { buildStatus, type StatusSnapshot } from \"@coool/adaptive-core/status\"\nimport { DEFAULT_HEALTH_CONFIG, ResourceHealthRegistry } from \"@coool/adaptive-core/health/index\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readCapacity, type SharedCapacity } from \"../capacity.js\"\nimport { readSharedHealth } from \"../health-actions.js\"\nimport type { SharedHealth } from \"../health.js\"\nimport { readReceipts } from \"../receipts.js\"\nimport { object } from \"../settings.js\"\nimport { parseParked, type Parked } from \"../parking.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\n\nexport async function readParked(file: Pick<JsonFile, \"read\">): Promise<Parked[]> {\n const raw = await file.read()\n if (raw === undefined) return []\n if (!(object(raw) && Array.isArray(raw[\"records\"])) || raw[\"records\"].length > 512)\n throw new Error(\"Adaptive parked: invalid parked.json payload\")\n const records = raw[\"records\"].map((entry: unknown) => parseParked(entry))\n if (!isDeepStrictEqual(raw, { version: 1, records }))\n throw new Error(\"Adaptive parked: invalid parked.json payload\")\n return records.filter((record) => !record.claimed)\n}\n\ninterface StatusSources {\n settings(): Promise<SettingsV1>\n readonly health: SharedHealth\n readonly capacity: SharedCapacity\n readonly receipts: JsonTransactionFile\n readonly parked: JsonFile\n effectiveMode(global: OperatingMode): OperatingMode\n}\n\nexport async function readStatus(sources: StatusSources): Promise<StatusSnapshot> {\n const [settings, health, receipts, parked] = await Promise.all([\n sources.settings(),\n readSharedHealth(sources.health.file),\n readReceipts(sources.receipts),\n readParked(sources.parked),\n ])\n const refs = TIERS.flatMap((tier) => [...settings.tiers[tier]])\n const capacity = await readCapacity(sources.capacity, refs)\n const registry = new ResourceHealthRegistry(\n sources.health.clock,\n DEFAULT_HEALTH_CONFIG,\n sources.health.newId,\n )\n registry.restore(health)\n // Core status rows are leaf-keyed. Project inherited blockers to each row,\n // without changing the shared health or claiming a half-open probe.\n const projected = refs.flatMap((ref) => {\n const key = {\n providerID: ref.providerID,\n modelID: ref.id,\n ...(ref.variant === undefined ? {} : { variantID: ref.variant }),\n }\n const assessment = registry.evaluate(key)\n const record = registry.recordFor(assessment.kind === \"blocked\" ? assessment.key : key)\n return record === undefined ? [] : [{ ...record, key }]\n })\n return buildStatus({\n settings: { ...settings, mode: sources.effectiveMode(settings.mode) },\n health: projected,\n capacity: capacity.readings,\n parked: parked.length,\n waiting: parked.map((record) => ({\n sessionID: record.session,\n tier: record.tier,\n resumeAt: record.due,\n })),\n receipts: receipts.length,\n })\n}\n","import {\n parseKey,\n replaceControlCharacters,\n visibleWidth,\n wrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\"\nimport type { AdaptiveView } from \"@coool/adaptive-core/flow/controller\"\nimport type { SelectOption } from \"@coool/adaptive-core/flow/options\"\nimport { fitLine } from \"./entries.js\"\n\ninterface Component {\n render(width: number): string[]\n handleInput(data: string): void\n invalidate(): void\n}\ninterface DialogHost {\n readonly mode: string\n readonly ui: {\n select(title: string, choices: string[]): Promise<string | undefined>\n confirm(title: string, message: string): Promise<boolean>\n input(title: string, placeholder?: string): Promise<string | undefined>\n notify(message: string, type: \"info\" | \"error\"): void\n custom<T>(\n factory: (\n tui: { requestRender(): void; terminal: { rows: number } },\n theme: unknown,\n keys: unknown,\n done: (result: T) => void,\n ) => Component,\n ): Promise<T>\n }\n}\n/**\n * Pi draws a two-line footer under a dialog and mis-renders (drops the dialog's last line) a\n * frame exactly as tall as the terminal, so a dialog keeps one spare row.\n */\nfunction available(rows: number): number {\n return rows - 3\n}\ninterface PickResult<T> {\n picked: T | undefined\n action: string | undefined\n}\n\n/** Wrapping keeps whole model names and remedies readable; continuations keep the line's indent. */\nfunction wrap(lines: readonly string[], width: number): string[] {\n return lines.flatMap((raw) => {\n const line = replaceControlCharacters(raw)\n const indent = Math.min(line.length - line.trimStart().length, Math.max(0, width - 1))\n const pad = \" \".repeat(indent)\n return wrapTextWithAnsi(line.slice(indent), Math.max(1, width - indent)).map(\n (part) => `${pad}${part}`,\n )\n })\n}\n\n/** Search and page actions stay keyboard-accessible without becoming fake model rows. */\nexport function picker<T>(\n title: string,\n options: readonly SelectOption<T>[],\n actions: readonly { title: string; value: string; bind: string }[],\n height: number,\n done: (result: PickResult<T>) => void,\n refresh: () => void,\n): Component {\n let query = \"\"\n let selected = 0\n const filtered = () =>\n options.filter((option) =>\n `${option.title} ${option.description ?? \"\"}`.toLowerCase().includes(query.toLowerCase()),\n )\n return {\n render(width) {\n const rows = filtered()\n const headings = wrap(title.split(\"\\n\"), width)\n const count = Math.max(1, available(height) - headings.length - actions.length - 2)\n const offset = Math.max(0, selected - count + 1)\n return [\n ...headings,\n `Search: ${query}`,\n ...rows\n .slice(offset, offset + count)\n .map(\n (row, index) =>\n `${offset + index === selected ? \">\" : \" \"} ${row.title}${row.description === undefined ? \"\" : ` — ${row.description}`}`,\n ),\n ...(rows.length === 0 ? [\"No matches\"] : []),\n `${String(rows.length)} ${rows.length === 1 ? \"choice\" : \"choices\"} · Enter select · Esc back`,\n ...actions.map((action) => `${action.bind}: ${action.title}`),\n ].map((line) => fitLine(line, width))\n },\n handleInput(data) {\n const key = parseKey(data)\n const action = actions.find((candidate) => candidate.bind === key)\n if (action !== undefined) {\n done({ picked: undefined, action: action.value })\n return\n }\n if (key === \"escape\") {\n done({ picked: undefined, action: undefined })\n return\n }\n const rows = filtered()\n if (key === \"enter\") {\n done({ picked: rows[selected]?.value, action: undefined })\n return\n }\n if (key === \"up\") selected = Math.max(0, selected - 1)\n else if (key === \"down\") selected = Math.min(Math.max(0, rows.length - 1), selected + 1)\n else if (key === \"backspace\") {\n query = query.slice(0, -1)\n selected = 0\n } else if (/^[^\\p{C}]+$/u.test(data)) {\n query = `${query}${data}`.slice(0, 128)\n selected = 0\n }\n refresh()\n },\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n}\n\nexport function piView(host: DialogHost): AdaptiveView {\n async function select<T>(\n title: string,\n options: readonly SelectOption<T>[],\n actions: readonly { title: string; value: string; bind: string }[] = [],\n ): Promise<PickResult<T>> {\n if (host.mode === \"tui\")\n return host.ui.custom<PickResult<T>>((tui, _theme, _keys, done) =>\n picker(title, options, actions, tui.terminal.rows, done, () => {\n tui.requestRender()\n }),\n )\n const search =\n options.length > 20\n ? await host.ui.input(title, \"Search provider / model / name (empty shows all)\")\n : \"\"\n if (search === undefined) return { picked: undefined, action: undefined }\n const visible = options.filter((option) =>\n `${option.title} ${option.description ?? \"\"}`.toLowerCase().includes(search.toLowerCase()),\n )\n const labels = visible.map(\n (option, index) =>\n `${String(index + 1)}. ${option.title}${option.description === undefined ? \"\" : ` — ${option.description}`}`,\n )\n const actionLabels = actions.map((action) => `${action.bind}: ${action.title}`)\n const chosen = await host.ui.select(title, [...labels, ...actionLabels])\n const index = chosen === undefined ? -1 : labels.indexOf(chosen)\n const actionIndex = chosen === undefined ? -1 : actionLabels.indexOf(chosen)\n return { picked: visible[index]?.value, action: actions[actionIndex]?.value }\n }\n async function text(\n title: string,\n lines: readonly string[],\n compact: readonly string[] = lines,\n ): Promise<void> {\n if (host.mode !== \"tui\") {\n await host.ui.select(`${title}\\n${compact.join(\"\\n\")}`, [\"Back\"])\n return\n }\n await host.ui.custom<undefined>((tui, _theme, _keys, done) => {\n let offset = 0\n let total = Math.max(lines.length, compact.length)\n const count = Math.max(1, available(tui.terminal.rows) - 2)\n return {\n render(width) {\n const shown = wrap(\n lines.some((line) => visibleWidth(line) > width) ? compact : lines,\n width,\n )\n total = shown.length\n offset = Math.min(offset, Math.max(0, total - count))\n return [\n title,\n ...shown.slice(offset, offset + count),\n \"↑/↓ scroll · Enter or Esc back\",\n ].map((line) => fitLine(line, width))\n },\n handleInput(data) {\n const key = parseKey(data)\n if (key === \"escape\" || key === \"enter\") {\n done(undefined)\n return\n }\n if (key === \"up\") offset = Math.max(0, offset - 1)\n if (key === \"down\") offset = Math.min(Math.max(0, total - count), offset + 1)\n tui.requestRender()\n },\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n })\n }\n return {\n select: async (spec) => (await select(spec.title, spec.options)).picked,\n selectPaged: (spec) => select(spec.title, spec.options, spec.actions),\n confirm: (spec) => host.ui.confirm(spec.title, spec.message),\n alert: (spec) => text(spec.title, spec.message.split(\"\\n\")),\n table: (spec) => text(spec.title, spec.lines, spec.compactLines),\n toast: (message, variant) => {\n host.ui.notify(message, variant === \"error\" ? \"error\" : \"info\")\n },\n }\n}\n","import type {\n ExtensionAPI,\n ExtensionContext,\n ModelChangeEntry,\n} from \"@earendil-works/pi-coding-agent\"\nimport type { AdaptiveEnv } from \"@coool/adaptive-core/flow/controller\"\nimport { waitingLabel } from \"@coool/adaptive-core/flow/waiting\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { readSharedHealth, resetResourceHealth } from \"../health-actions.js\"\nimport { effectiveMode } from \"../session.js\"\nimport { readSettings, updateSettings } from \"../settings.js\"\nimport type { JsonFile } from \"../store.js\"\nimport { PI_COPY } from \"../ui/copy.js\"\nimport { doctorLines } from \"../ui/doctor.js\"\nimport { DEFAULT_MODEL_HELP, healthAction, preferencesAction } from \"./actions.js\"\nimport { registerCommands } from \"./commands.js\"\nimport { controlApi } from \"./control.js\"\nimport { doctorChecks } from \"./doctor.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport { availablePhysicalModels, modelSummaries, proposalModels } from \"./inventory.js\"\nimport { editTierProposal, runOnboarding } from \"./onboarding.js\"\nimport type { parkingHandlers } from \"./parking.js\"\nimport { readParked, readStatus } from \"./status.js\"\nimport { piView } from \"./view.js\"\n\n/** What only the packaged entry knows: the settings file and the Pi version. */\nexport interface HostSources {\n readonly settings: JsonFile\n readonly version: string\n readonly minimum: string\n readonly testedUpTo: string | undefined\n}\n\ntype Host = Pick<ExtensionAPI, \"registerCommand\" | \"registerShortcut\" | \"appendEntry\" | \"setModel\">\n\n/** The `/adaptive` command, its shortcut, and the one-time first-run offer. */\nexport function adaptiveSurface(\n pi: Host,\n sources: AdaptiveSources,\n host: HostSources,\n parking: Pick<ReturnType<typeof parkingHandlers>, \"resume\" | \"cancel\">,\n feedback: (ctx: ExtensionContext) => () => Promise<void>,\n): { onboard(ctx: ExtensionContext): Promise<void> } {\n const select = async (ctx: ExtensionContext, ref: ModelRef): Promise<boolean> => {\n const model = ctx.modelRegistry.find(ref.providerID, ref.id)\n return model !== undefined && (await pi.setModel(model))\n }\n const environment = (ctx: ExtensionContext): Promise<AdaptiveEnv> => {\n const session = ctx.sessionManager.getSessionId()\n const refresh = async (): Promise<void> => {\n // A successful mode change may select a model and invalidate the old\n // footer binding. Rebind to the resulting model, but never a new session.\n if (ctx.sessionManager.getSessionId() === session) await feedback(ctx)()\n }\n const view = piView(ctx)\n const branch = () => ctx.sessionManager.getBranch()\n const control = controlApi({\n settings: host.settings,\n receipts: sources.receipts,\n sessionID: ctx.sessionManager.getSessionId(),\n branch,\n model: () => ctx.model,\n manualModel: () => {\n const change = branch().findLast(\n (entry): entry is ModelChangeEntry =>\n entry.type === \"model_change\" && entry.provider !== \"adaptive\",\n )\n return change === undefined\n ? undefined\n : { providerID: change.provider, id: change.modelId }\n },\n selectModel: (ref) => select(ctx, ref),\n append: (type, data) => {\n pi.appendEntry(type, data)\n },\n idle: () => ctx.isIdle(),\n status: () =>\n readStatus({\n settings: () => readSettings(host.settings),\n health: sources.health,\n capacity: sources.capacity,\n receipts: sources.receipts,\n parked: sources.parking.file,\n effectiveMode: (global) => effectiveMode(ctx.model, global, branch()),\n }),\n })\n const api = {\n ...control,\n async setSettings(patch: Parameters<typeof control.setSettings>[0]) {\n const result = await control.setSettings(patch)\n if (result.ok) await refresh()\n return result\n },\n async setSessionMode(...args: Parameters<typeof control.setSessionMode>) {\n const result = await control.setSessionMode(...args)\n if (result.ok) await refresh()\n return result\n },\n }\n const configured = async () => {\n const settings = await readSettings(host.settings)\n return TIERS.flatMap((tier) => [...settings.tiers[tier]])\n }\n return Promise.resolve({\n copy: PI_COPY,\n api,\n view,\n models: () => modelSummaries(availablePhysicalModels(ctx.modelRegistry)),\n sessionID: ctx.sessionManager.getSessionId(),\n actions: {\n health: async () => {\n await healthAction(view, await configured(), (ref) =>\n resetResourceHealth(sources.health.file, ref),\n )\n },\n parked: async () => {\n const { waiting } = await api.status()\n const now = sources.parking.clock()\n await view.alert({\n title: \"Parked work\",\n message:\n waiting.length === 0\n ? \"No parked work.\"\n : [\n ...waiting.map(\n (entry) =>\n `${entry.sessionID === ctx.sessionManager.getSessionId() ? \"This session\" : entry.sessionID} · ${entry.tier} · ${waitingLabel(entry.resumeAt, now)}`,\n ),\n \"Use /adaptive resume or /adaptive cancel in the waiting session.\",\n ].join(\"\\n\"),\n })\n },\n doctor: async () => {\n const checks = await doctorChecks({\n version: host.version,\n minimum: host.minimum,\n testedUpTo: host.testedUpTo,\n registry: ctx.modelRegistry,\n settings: () => readSettings(host.settings),\n capabilities: sources.capabilities,\n // An update that changes nothing still takes the exclusive lock.\n storage: () => host.settings.update(() => ({ next: undefined, result: undefined })),\n health: async () =>\n (await readSharedHealth(sources.health.file)).filter(\n (record) => record.health !== \"healthy\",\n ).length,\n parked: async () => (await readParked(sources.parking.file)).length,\n })\n await view.table({ title: \"Adaptive doctor\", lines: doctorLines(checks) })\n },\n preferences: () => preferencesAction(view, sources.preferences),\n defaults: () =>\n view.alert({ title: \"Use Adaptive for new sessions\", message: DEFAULT_MODEL_HELP }),\n },\n })\n }\n registerCommands<ExtensionContext>(pi, {\n env: environment,\n resume: (ctx) => parking.resume(ctx),\n cancel: (ctx) => parking.cancel(ctx),\n clock: sources.health.clock,\n })\n return {\n async onboard(ctx) {\n const env = await environment(ctx)\n await runOnboarding({\n hasUI: ctx.hasUI,\n api: {\n settings: () => readSettings(host.settings),\n setSettings: (patch) => updateSettings(host.settings, patch),\n },\n view: env.view,\n models: () => proposalModels(availablePhysicalModels(ctx.modelRegistry)),\n edit: (draft) => editTierProposal(env, draft),\n activate: () => select(ctx, { providerID: \"adaptive\", id: \"auto\" }),\n })\n },\n }\n}\n","import { stripVTControlCharacters } from \"node:util\"\nimport type { ExtensionContext } from \"@earendil-works/pi-coding-agent\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\n\nexport type RoutingStatus =\n | {\n readonly kind: \"routing\" | \"recovering\" | \"escalated\"\n readonly tier: TierName\n readonly model: string\n }\n | { readonly kind: \"observing\"; readonly tier: TierName }\n | { readonly kind: \"degraded\" | \"setup\" }\n\ninterface StatusContext {\n readonly hasUI?: boolean\n readonly ui?: Pick<ExtensionContext[\"ui\"], \"setStatus\">\n}\n\nexport interface RoutingFeedback {\n show(state: RoutingStatus): void\n dispatched(\n model: { readonly id: string },\n info: {\n readonly tier: TierName\n readonly retry: boolean\n readonly state: { readonly escalations: number; readonly restarts: number } | undefined\n },\n ): void\n}\n\nfunction statusText(state: RoutingStatus): string {\n switch (state.kind) {\n case \"routing\":\n return `${state.tier} | ${state.model}`\n case \"recovering\":\n return `Recovering ${state.tier} | ${state.model}`\n case \"escalated\":\n return `Escalated ${state.tier} | ${state.model}`\n case \"observing\":\n return `Observing | would use ${state.tier}`\n case \"degraded\":\n return \"Adaptive degraded | /adaptive doctor\"\n case \"setup\":\n return \"Adaptive: set up tiers | /adaptive\"\n }\n}\n\nfunction terminalText(text: string): string {\n // Provider model IDs are untrusted. ASCII bounds cells as well as characters,\n // leaving room beside Pi's own footer at the supported 60-column minimum.\n const safe = stripVTControlCharacters(text).replace(/[^\\x20-\\x7e]/g, \"?\")\n return safe.length <= 48 ? safe : `${safe.slice(0, 45)}...`\n}\n\n/** One footer key: parking overrides routing until parking clears its status. */\nexport function createStatusChip() {\n let generation = 0\n let routing: string | undefined\n let parking: string | undefined\n let owner: StatusContext[\"ui\"]\n const paint = (ui: StatusContext[\"ui\"], text: string | undefined): void => {\n try {\n ui?.setStatus(\"adaptive\", text)\n } catch (error) {\n logFailOpen(\"status\", error)\n }\n }\n const reset = (): void => {\n generation += 1\n routing = undefined\n parking = undefined\n paint(owner, undefined)\n owner = undefined\n }\n\n return {\n /** Reset before model/session changes and shutdown, not on tool continuations. */\n reset,\n /** Capture before awaiting work; old callbacks cannot repaint a new session. */\n connect<T extends StatusContext>(ctx: T) {\n const owned = generation\n const ui = ctx.hasUI ? ctx.ui : undefined\n let degraded = false\n const render = () => {\n owner = ui\n paint(ui, parking ?? routing)\n }\n const show = (state: RoutingStatus): void => {\n if (owned !== generation) return\n if (state.kind === \"degraded\") degraded = true\n routing = terminalText(statusText(state))\n render()\n }\n const setStatus = (key: string, text: string | undefined): void => {\n if (owned !== generation) return\n if (key !== \"adaptive\") {\n ui?.setStatus(key, text)\n return\n }\n // Do not reformat parking's countdown or resume time. It owns that copy.\n parking = text\n render()\n }\n // Pi contexts have live getters (notably model/sessionManager). A plain\n // spread would freeze them while a command is selecting another model.\n const context = Object.defineProperties(\n { ...ctx },\n {\n ...Object.getOwnPropertyDescriptors(ctx),\n ...(ctx.ui === undefined\n ? {}\n : {\n ui: { value: { ...ctx.ui, setStatus }, enumerable: true, configurable: true },\n }),\n },\n )\n return {\n context,\n clear(): void {\n if (owned === generation) reset()\n },\n show,\n /** Call only after admission, never for a preview or a parked route. */\n dispatched(\n model: { readonly id: string },\n info: {\n readonly tier: TierName\n readonly retry: boolean\n readonly state: { readonly escalations: number; readonly restarts: number } | undefined\n },\n ): void {\n if (owned !== generation) return\n parking = undefined\n if (degraded) {\n show({ kind: \"degraded\" })\n return\n }\n let kind: \"routing\" | \"recovering\" | \"escalated\" = \"routing\"\n if (info.retry || (info.state?.restarts ?? 0) > 0) kind = \"recovering\"\n else if ((info.state?.escalations ?? 0) > 0) kind = \"escalated\"\n show({\n kind,\n tier: info.tier,\n model: model.id,\n })\n },\n /** Substitute only this method in parking's ctx.ui; keep its other methods. */\n setStatus,\n }\n },\n }\n}\n","import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\"\nimport { CONTINUATION_PROMPT } from \"@coool/adaptive-core/execution/continuation/prompts\"\nimport { ESCALATION_TOOL_NAME } from \"@coool/adaptive-core/execution/escalation/index\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport type { Decision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { ReceiptOutcome } from \"@coool/adaptive-core/state/receipts/types\"\nimport { readPreferences } from \"../preferences.js\"\nimport { attachReceiptOutcome, recordReceipt } from \"../receipts.js\"\nimport { effectiveMode, requestedTier } from \"../session.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\nimport { decisionNote, pausedNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { observeOutcome, withHealth, type SharedHealth } from \"../health.js\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport type { ParkingSources } from \"../parking.js\"\nimport type { SharedCapacity } from \"../capacity.js\"\nimport { dispatchCapacity } from \"./dispatch-capacity.js\"\nimport { appendNote, registerEntries } from \"./entries.js\"\nimport { observeInput, type NoteTracker } from \"./observe.js\"\nimport {\n CONTINUATION_TYPE,\n escalationAfterRun,\n restartAfterRun,\n parkingAfterRun,\n servedTask,\n type BranchEntry,\n type Recovery,\n} from \"../task.js\"\nimport { escalationTool, selectedVirtual, tierTool } from \"./tools.js\"\nimport { physical, virtualModels, type RouteContext } from \"./routing.js\"\nimport { parkingHandlers } from \"./parking.js\"\nimport { adaptiveSurface, type HostSources } from \"./adaptive.js\"\nimport { createStatusChip } from \"./status-chip.js\"\n\nexport interface AdaptiveSources {\n readonly settings: () => Promise<SettingsV1>\n readonly capabilities: () => Promise<readonly ToolCapability[]>\n readonly newId: () => string\n readonly health: SharedHealth\n readonly parking: ParkingSources\n readonly capacity: SharedCapacity\n readonly receipts: JsonTransactionFile\n readonly preferences: JsonFile\n}\n\ntype Host = Pick<\n ExtensionAPI,\n | \"registerVirtualModel\"\n | \"getActiveTools\"\n | \"registerTool\"\n | \"on\"\n | \"sendMessage\"\n | \"sendUserMessage\"\n | \"appendEntry\"\n | \"registerCommand\"\n | \"registerShortcut\"\n | \"setModel\"\n | \"registerEntryRenderer\"\n>\n\nexport interface SettleContext extends Omit<RouteContext, \"ui\"> {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly hasUI: boolean\n readonly ui: { notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void }\n}\n\nexport function registerAdaptive(pi: Host, sources: AdaptiveSources, host: HostSources): void {\n const capacity = dispatchCapacity(sources.capacity)\n const status = createStatusChip()\n const refreshStatus = (ctx: ExtensionContext) => {\n const feedback = status.connect(ctx)\n return async (): Promise<void> => {\n if (!ctx.hasUI) return\n try {\n const current = await sources.settings()\n const branch = ctx.sessionManager.getBranch()\n const id = selectedVirtual(ctx.model)\n const mode = effectiveMode(ctx.model, current.mode, branch)\n const tier = id === undefined || id === \"auto\" ? (requestedTier(branch) ?? \"standard\") : id\n if (ctx.model === undefined || mode === \"off\") feedback.clear()\n else if (id === undefined && mode === \"observe\") feedback.show({ kind: \"observing\", tier })\n else if (current.tiers[tier].length === 0) feedback.show({ kind: \"setup\" })\n } catch (error) {\n feedback.show({ kind: \"degraded\" })\n logFailOpen(\"status\", error)\n }\n }\n }\n const tracker: NoteTracker = { last: undefined }\n const dispatched: DispatchTracker = { last: undefined }\n /** Every routed turn writes its decision and keeps the outcome attached (ADP-030). */\n const dispatchRecord = async (\n info: {\n decision: Decision\n unit: string | undefined\n tier: TierName\n session: string | undefined\n retry: boolean\n },\n model: { readonly provider: string; readonly id: string },\n ): Promise<void> => {\n if (info.session === undefined) return\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.health.clock(),\n sessionID: info.session,\n unitID: info.unit,\n tier: info.tier,\n decision: info.decision,\n })\n if (info.decision.kind === \"apply\")\n dispatched.last = {\n unit: info.unit,\n session: info.session,\n provider: model.provider,\n model: model.id,\n }\n const { verbosity } = await readPreferences(sources.preferences)\n if (!shouldWriteNote(verbosity, info.decision, tracker.last)) return\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(info.decision, info.tier, info.retry),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = info.decision\n }\n registerEntries(pi)\n const pausedAt = async (model: { readonly provider: string; readonly id: string }) => {\n try {\n const { verbosity } = await readPreferences(sources.preferences)\n if (verbosity === \"quiet\") return\n appendNote(pi, { version: 1, text: pausedNote(model) })\n tracker.last = undefined\n } catch (error) {\n logFailOpen(\"notes\", error)\n }\n }\n const parking = parkingHandlers(pi, sources, tracker)\n const surface = adaptiveSurface(\n pi,\n sources,\n host,\n {\n resume: (ctx) => parking.resume(status.connect(ctx).context),\n cancel: (ctx) => parking.cancel(status.connect(ctx).context),\n },\n refreshStatus,\n )\n pi.on(\"input\", async (event, ctx) => {\n const feedback = status.connect(ctx)\n const parked = await parking.input(event, feedback.context)\n if (parked.action === \"handled\") return parked\n return observeInput(pi, sources, tracker, () => feedback.show)(event, ctx)\n })\n pi.on(\"model_select\", async (event, ctx) => {\n status.reset()\n const feedback = status.connect(ctx)\n const refresh = refreshStatus(ctx)\n if (selectedVirtual(event.model) === undefined) {\n capacity.clear()\n // Only leaving Adaptive is news; startup and restored sessions are not.\n if (selectedVirtual(event.previousModel) !== undefined) await pausedAt(event.model)\n }\n await parking.modelSelect(event.model, feedback.context)\n await refresh()\n })\n pi.on(\"session_start\", async (_event, ctx) => {\n status.reset()\n const feedback = status.connect(ctx)\n const refresh = refreshStatus(ctx)\n capacity.clear()\n tracker.last = undefined\n await refresh()\n await parking.sessionStart(feedback.context)\n try {\n await surface.onboard(ctx)\n } catch (error) {\n logFailOpen(\"onboarding\", error)\n }\n })\n pi.on(\"session_tree\", async (_event, ctx) => {\n status.reset()\n await refreshStatus(ctx)()\n })\n // Receipt writes run beside the turn; settling them before the outcome is\n // attached and before the session goes away keeps both ordered and never\n // touches a replaced session context.\n let pending: Promise<void> = Promise.resolve()\n pi.on(\"session_shutdown\", async () => {\n status.reset()\n parking.shutdown()\n await pending\n })\n for (const definition of virtualModels(\n sources,\n () => pi.getActiveTools(),\n parking,\n (model, info) => {\n capacity.selected(model.provider)\n pending = pending.then(() =>\n dispatchRecord(info, model).catch((error: unknown) => {\n logFailOpen(\"receipts\", error)\n }),\n )\n },\n (ctx) => status.connect(ctx),\n ))\n pi.registerVirtualModel(definition)\n pi.registerTool(tierTool(sources.settings))\n pi.registerTool(\n escalationTool(\n sources.settings,\n async () => (await readPreferences(sources.preferences)).escalateFromPinned,\n ),\n )\n pi.on(\"message_end\", async (event, ctx) => {\n if (event.message.role === \"assistant\") capacity.clear()\n await pending\n await recordOutcome(event.message, ctx, sources, dispatched)\n })\n pi.on(\"after_provider_response\", (event) => capacity.response(event.headers))\n pi.on(\"agent_settled\", (event, ctx) => {\n capacity.clear()\n const feedback = status.connect(ctx)\n return afterRun(\n event,\n ctx,\n sources,\n (message) => {\n pi.sendMessage(message, { triggerTurn: true })\n },\n (recovery) => parking.recover(recovery, feedback.context),\n (task) => parking.clearServed(task, feedback.context),\n )\n })\n}\n\nexport interface OutcomeContext {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly sessionManager: { getBranch(): readonly BranchEntry[] }\n}\n\n/** The routed dispatch whose receipt outcome is still pending. */\nexport interface DispatchTracker {\n last:\n | {\n readonly unit: string | undefined\n readonly session: string\n readonly provider: string\n readonly model: string\n }\n | undefined\n}\n\ninterface DispatchedMessage {\n readonly role: string\n readonly provider?: string\n readonly model?: string\n readonly stopReason?: string\n readonly errorMessage?: string\n}\n\n/** Record before Pi retries, so re-admission already sees the failure. */\nexport async function recordOutcome(\n message: DispatchedMessage,\n ctx: OutcomeContext,\n sources: AdaptiveSources,\n dispatched: DispatchTracker = { last: undefined },\n): Promise<void> {\n const { provider, model, stopReason } = message\n if (\n message.role !== \"assistant\" ||\n provider === undefined ||\n provider === \"adaptive\" ||\n model === undefined ||\n stopReason === undefined\n )\n return\n try {\n const settings = await sources.settings()\n // OFF never learns: a manual model the user parked away stays untouched.\n if (effectiveMode(ctx.model, settings.mode, ctx.sessionManager.getBranch()) === \"off\") return\n const classification = await withHealth(sources.health, (registry) =>\n observeOutcome(\n registry,\n { providerID: provider, id: model },\n { stopReason, errorMessage: message.errorMessage },\n ),\n )\n const last = dispatched.last\n if (last === undefined) return\n if (last.provider !== provider || last.model !== model) return\n let outcome: ReceiptOutcome = { status: \"succeeded\" }\n if (stopReason === \"aborted\") outcome = { status: \"interrupted\", reason: \"user\" }\n else if (stopReason === \"error\" && classification !== undefined)\n outcome = { status: \"failed\", category: classification.category }\n await attachReceiptOutcome(\n sources.receipts,\n { sessionID: last.session, unitID: last.unit },\n outcome,\n )\n } catch (error) {\n logFailOpen(\"health\", error)\n }\n}\n\ninterface ContinuationMessage {\n readonly customType: string\n readonly content: string\n readonly display: false\n readonly details: unknown\n}\n\nfunction recoveryNotice(recovery: Recovery, escalated: boolean): string {\n if (escalated) return `Adaptive: the task needs more capability; continuing on ${recovery.tier}.`\n const failed = recovery.tried.map((ref) => ref.id).join(\", \")\n return failed === \"\"\n ? `Adaptive: the request failed; continuing on ${recovery.tier}.`\n : `Adaptive: ${failed} failed; continuing on another ${recovery.tier} model.`\n}\n\n/** Terminal recovery is owned by this handler, never a replay of user input. */\nexport async function afterRun(\n event: { readonly aborted: boolean },\n ctx: SettleContext,\n sources: AdaptiveSources,\n send: (message: ContinuationMessage) => void,\n park?: (recovery: Recovery) => Promise<boolean>,\n /** Called for a wake lineage whose run just finished successfully. */\n clear?: (task: string) => Promise<void>,\n): Promise<void> {\n const id = selectedVirtual(ctx.model)\n if (event.aborted || id === undefined) return\n try {\n const settings = await sources.settings()\n const branch = ctx.sessionManager.getBranch()\n const input = {\n id,\n escalateFromPinned: (await readPreferences(sources.preferences)).escalateFromPinned,\n settings: { ...settings, mode: effectiveMode(ctx.model, settings.mode, branch) },\n branch,\n available: physical(ctx.modelRegistry).map((model) => ({\n providerID: model.provider,\n id: model.id,\n })),\n tool: ESCALATION_TOOL_NAME,\n newId: sources.newId,\n }\n const escalation = escalationAfterRun(input)\n const recovery = escalation ?? restartAfterRun(input)\n if (recovery === undefined) {\n const waiting = parkingAfterRun(input)\n if (waiting !== undefined) {\n await park?.(waiting)\n return\n }\n // A resumed lineage that finished leaves a stale park behind when its\n // re-dispatch had to park through a still-blocked window before the\n // follow-up turn succeeded. Drop it so the chip does not promise work\n // that no longer exists.\n const task = servedTask(input)\n if (task !== undefined) await clear?.(task)\n return\n }\n if (await park?.(recovery)) return\n if (ctx.hasUI) ctx.ui.notify(recoveryNotice(recovery, escalation !== undefined))\n send({\n customType: CONTINUATION_TYPE,\n content: CONTINUATION_PROMPT,\n display: false,\n details: recovery,\n })\n } catch (error) {\n logFailOpen(\"escalation\", error)\n }\n}\n","// covers: [\"ADP-059\"]\n/**\n * Shared JSON state for every Pi process on the machine. Pi has no global\n * store and runs subagents as child processes, so health and parking live in\n * files under the agent directory. Each update holds an exclusive lock file\n * across read → change → write and replaces the file atomically, so two\n * processes never interleave a read-modify-write or observe a torn file.\n *\n * Corrupt or unreadable state throws and is never rewritten: callers fail\n * open (route without the state) and leave the file for the user to inspect.\n */\nimport { randomUUID } from \"node:crypto\"\nimport { mkdir, open, readFile, rename, rm, stat, writeFile } from \"node:fs/promises\"\nimport { dirname } from \"node:path\"\n\n// A lock older than this belongs to a crashed process: every holder finishes\n// a read-modify-write of a small file in milliseconds.\nconst STALE_LOCK_MS = 10_000\n// Waiting longer than this for a live holder fails the update (fail-open).\nconst LOCK_TIMEOUT_MS = 1_000\nconst LOCK_RETRY_MS = 10\n\nexport interface JsonFile {\n /** Current value, or `undefined` when the file does not exist. */\n read(): Promise<unknown>\n /**\n * Applies `change` under the lock. A `next` of `undefined` leaves the\n * file untouched (read-only decisions still serialize with writers).\n */\n update<R>(\n change: (current: unknown) => { readonly next: unknown; readonly result: R },\n ): Promise<R>\n}\n\n/** Async core stores must finish their read/modify/write before releasing the lock. */\nexport interface JsonTransactionFile {\n read(): Promise<unknown>\n transaction<R>(\n change: (current: unknown) => Promise<{ readonly next: unknown; readonly result: R }>,\n ): Promise<R>\n}\n\nfunction errorCode(error: unknown): unknown {\n return Reflect.get(Object(error), \"code\")\n}\n\nasync function parse(path: string): Promise<unknown> {\n let text: string\n try {\n text = await readFile(path, \"utf8\")\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") {\n return undefined\n }\n throw error\n }\n try {\n const value: unknown = JSON.parse(text)\n return value\n } catch {\n throw new Error(`Adaptive state: ${path} is not valid JSON`)\n }\n}\n\nasync function acquire(lock: string, clock: () => number): Promise<void> {\n const deadline = clock() + LOCK_TIMEOUT_MS\n for (;;) {\n try {\n const handle = await open(lock, \"wx\")\n await handle.writeFile(String(process.pid))\n await handle.close()\n return\n } catch (error) {\n if (errorCode(error) !== \"EEXIST\") {\n throw error\n }\n }\n // The holder usually released between `open` and `stat`; any failure to\n // inspect the lock just means \"try again until the deadline\".\n const held = await stat(lock).catch(() => undefined)\n if (held !== undefined && clock() - held.mtimeMs > STALE_LOCK_MS) {\n await rm(lock, { force: true })\n continue\n }\n if (clock() >= deadline) {\n throw new Error(`Adaptive state: ${lock} is held by another Pi process`)\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS))\n }\n}\n\nexport function jsonFile(\n path: string,\n clock: () => number = Date.now,\n): JsonFile & JsonTransactionFile {\n const lock = `${path}.lock`\n return {\n read: () => parse(path),\n update(change) {\n return this.transaction((current) => Promise.resolve(change(current)))\n },\n async transaction(change) {\n await mkdir(dirname(path), { recursive: true })\n await acquire(lock, clock)\n try {\n const { next, result } = await change(await parse(path))\n if (next !== undefined) {\n const temporary = `${path}.${randomUUID()}.tmp`\n await writeFile(temporary, `${JSON.stringify(next)}\\n`, { mode: 0o600 })\n await rename(temporary, path)\n }\n return result\n } finally {\n await rm(lock, { force: true })\n }\n },\n }\n}\n","import type { ParkingSources } from \"../parking.js\"\n\n// Owned waits must keep print/json alive. TUI timers are cancelled on shutdown.\nexport const timer: ParkingSources[\"timer\"] = (callback, delay) => {\n const handle = setTimeout(callback, delay)\n return () => {\n clearTimeout(handle)\n }\n}\n","","","import { randomUUID } from \"node:crypto\"\nimport { readFile } from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { getAgentDir, VERSION } from \"@earendil-works/pi-coding-agent\"\nimport { applyPatch, defaultSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport { registerAdaptive } from \"./host/extension.js\"\nimport { loadToolCapabilities } from \"./capabilities.js\"\nimport { jsonFile } from \"./store.js\"\nimport { timer } from \"./host/timer.js\"\nimport baseline from \"../pi-host-baseline.json\" with { type: \"json\" }\nimport matrix from \"../pi-host-matrix.json\" with { type: \"json\" }\n\nexport default function adaptive(pi: Parameters<typeof registerAdaptive>[0]): void {\n const path = join(getAgentDir(), \"adaptive\", \"settings.json\")\n registerAdaptive(\n pi,\n {\n newId: randomUUID,\n capacity: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"capacity.json\")),\n clock: Date.now,\n },\n parking: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"parked.json\")),\n clock: Date.now,\n timer,\n },\n health: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"health.json\")),\n clock: Date.now,\n newId: randomUUID,\n },\n receipts: jsonFile(join(getAgentDir(), \"adaptive\", \"receipts.json\")),\n preferences: jsonFile(join(getAgentDir(), \"adaptive\", \"preferences.json\")),\n settings: async () => {\n let text: string\n try {\n text = await readFile(path, \"utf8\")\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return defaultSettings()\n throw error\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n throw new Error(\"Adaptive settings: invalid JSON\")\n }\n const parsed = applyPatch(defaultSettings(), raw)\n if (!parsed.ok) throw new Error(`Adaptive settings: ${parsed.errors.join(\", \")}`)\n return parsed.settings\n },\n capabilities: () =>\n loadToolCapabilities(join(getAgentDir(), \"adaptive\", \"capabilities.json\"), (file) =>\n readFile(file, \"utf8\"),\n ),\n },\n {\n settings: jsonFile(path),\n version: VERSION,\n minimum: matrix.minimum,\n // The last recorded packed-host matrix; a release records its own after verification.\n testedUpTo: baseline.testedUpTo,\n },\n )\n}\n"],"ignoreList":[50,51],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["isRecord","object","object","isRecord","parseVocab","parse","field","parse","object","isFiniteNumber","failureEvent","isRecord","isFiniteNumber","parseIdentifier","parseKey","failureEvent","parseKey","parse","object","field","field","payload","object","matrix.minimum","baseline.testedUpTo"],"sources":["../../core/src/routing/compatibility/types.ts","../../core/src/health/circuit-breaker/types.ts","../../core/src/health/resource-health/types.ts","../../core/src/health/resource-health/key.ts","../../core/src/routing/scheduler/types.ts","../../core/src/routing/work-unit/types.ts","../../core/src/routing/tier-policy/tier-list.ts","../../core/src/routing/tier-policy/types.ts","../../core/src/state/settings/parse.ts","../../core/src/execution/continuation/prompts.ts","../../core/src/execution/escalation/types.ts","../../core/src/log.ts","../src/settings.ts","../src/preferences.ts","../../core/src/state/receipts/bound.ts","../../core/src/routing/work-unit/interruption.ts","../../core/src/health/classifier/types.ts","../../core/src/state/receipts/parse.ts","../../core/src/state/receipts/store.ts","../src/receipts.ts","../../core/src/routing/compatibility/gate.ts","../../core/src/routing/scheduler/admit.ts","../src/router.ts","../../core/src/health/classifier/classify.ts","../../core/src/routing/scheduler/escalate.ts","../src/evidence.ts","../src/task.ts","../src/session.ts","../../core/src/flow/tiers.ts","../src/ui/notes.ts","../../core/src/health/circuit-breaker/breaker.ts","../../core/src/health/capacity/types.ts","../../core/src/health/capacity/merge.ts","../../core/src/health/resource-health/failure.ts","../../core/src/health/resource-health/transitions.ts","../../core/src/health/resource-health/registry.ts","../../core/src/state/health/parse.ts","../../core/src/state/health/store.ts","../src/health.ts","../../core/src/sensors/codex-capacity/types.ts","../../core/src/sensors/codex-capacity/parse.ts","../../core/src/sensors/codex-capacity/reading.ts","../../core/src/sensors/codex-capacity/sensor.ts","../../core/src/state/capacity/parse.ts","../src/capacity.ts","../src/host/dispatch-capacity.ts","../src/host/entries.ts","../../core/src/routing/scheduler/mode.ts","../../core/src/execution/parking/wake.ts","../src/parking.ts","../../../node_modules/@earendil-works/pi-ai/dist/utils/text.js","../../../node_modules/@earendil-works/pi-ai/dist/utils/estimate.js","../src/host/inventory.ts","../src/host/routing.ts","../src/host/tools.ts","../src/host/observe.ts","../src/host/parked-view.ts","../src/host/parking.ts","../src/health-actions.ts","../src/ui/copy.ts","../../core/src/flow/status.ts","../src/capabilities.ts","../src/host/actions.ts","../../core/src/flow/doctor.ts","../../core/src/flow/waiting.ts","../../core/src/flow/actions.ts","../../core/src/flow/menu.ts","../../core/src/flow/options.ts","../../core/src/flow/receipts.ts","../../core/src/flow/controller.ts","../../core/src/flow/command.ts","../src/host/commands.ts","../src/host/control.ts","../src/ui/doctor.ts","../src/host/doctor.ts","../src/ui/proposal.ts","../../core/src/status.ts","../src/host/onboarding.ts","../src/host/status.ts","../src/host/view.ts","../src/host/adaptive.ts","../src/host/status-chip.ts","../src/host/extension.ts","../src/store.ts","../src/host/timer.ts","../pi-host-baseline.json","../pi-host-matrix.json","../src/index.ts"],"sourcesContent":["/**\n * Compatibility gate (ADP-017): filters candidates on context capacity,\n * tool use, modalities, and model/variant/provider availability BEFORE\n * health/preference ranking. Pure — adapters map OpenCode `Model.Info` /\n * `Provider.Info` into `CandidateModel`, this module never touches\n * `@opencode/plugin` types.\n *\n * Conservative rule: metadata the gate needs but cannot see is treated as\n * NOT satisfying the requirement (e.g. unknown `enabled`, unknown tool\n * support, unknown context limit). Only demand-side quantities that are\n * themselves unknown are skipped — there is nothing to check against.\n */\n\n/** What the executing work needs from a resource. All demand fields are optional. */\nexport interface Demand {\n /** The unit needs tool use. `undefined`/`false` imposes no tool requirement. */\n readonly tools?: boolean | undefined\n /** Input modalities the unit carries (e.g. `\"text\"`, `\"image\"`). */\n readonly input?: readonly string[] | undefined\n /** Output modalities the unit must produce. */\n readonly output?: readonly string[] | undefined\n /** Known or estimated context need in tokens; `undefined` skips the capacity check. */\n readonly contextTokens?: number | undefined\n}\n\n/** Adapter-normalized view of one candidate resource. */\nexport interface CandidateModel {\n readonly providerID: string\n readonly modelID: string\n readonly variant?: string | undefined\n /** Model is enabled in the host inventory. Unknown ⇒ conservative reject. */\n readonly enabled?: boolean | undefined\n /** Provider is available in the host inventory. Unknown ⇒ conservative reject. */\n readonly providerEnabled?: boolean | undefined\n /** The requested variant exists for this model. Unknown ⇒ conservative reject. */\n readonly variantAvailable?: boolean | undefined\n readonly capabilities?:\n | {\n readonly tools?: boolean | undefined\n readonly input?: readonly string[] | undefined\n readonly output?: readonly string[] | undefined\n }\n | undefined\n readonly limit?: { readonly context?: number | undefined } | undefined\n}\n\n/**\n * Why a candidate failed the gate, in the fixed order the checks run:\n * availability → tools → input modalities → output modalities → context.\n */\nexport const INCOMPATIBILITY_REASONS = [\n \"provider-unavailable\",\n \"model-unavailable\",\n \"variant-unavailable\",\n \"tool-use-unsupported\",\n \"input-modality-unsupported\",\n \"output-modality-unsupported\",\n \"context-capacity-insufficient\",\n \"context-capacity-unknown\",\n] as const satisfies readonly string[]\n\nexport type IncompatibilityReason = (typeof INCOMPATIBILITY_REASONS)[number]\n\nexport interface Verdict {\n readonly compatible: boolean\n readonly reasons: readonly IncompatibilityReason[]\n}\n","/**\n * Circuit breaker types (ADP-019).\n *\n * The breaker is the quarantine mechanism for transient infrastructure\n * failures (outage, overload, timeout): repeated failures open the resource\n * for a backoff window, after which exactly one probe request is admitted\n * (half-open state). Rate limiting and quota exhaustion are deliberately\n * exempt from breaker counting because they already have their own windowed\n * resource states; counting them here would double-punish a resource that is\n * already known to need a cooldown.\n */\nimport type { FailureCategory } from \"../classifier/types.js\"\n\nexport const BREAKER_STATES = [\"closed\", \"open\", \"half_open\"] as const satisfies readonly string[]\n\nexport type BreakerState = (typeof BREAKER_STATES)[number]\n\nexport interface BreakerConfig {\n /** Consecutive countable failures in the closed state that trip the breaker. */\n readonly failureThreshold: number\n /** Backoff for the first opening; doubles on each reopening, capped below. */\n readonly baseOpenMs: number\n /** Upper bound for the backoff window. */\n readonly maxBackoffMs: number\n /**\n * How long a half-open probe may stay unreported before assessment treats\n * it as lost. Generous by design: a probe episode is a real work unit and\n * may run for minutes; the deadline only exists so a probe whose terminal\n * event never arrives cannot wedge the resource in half_open forever.\n */\n readonly probeTimeoutMs: number\n}\n\nexport const DEFAULT_BREAKER_CONFIG: BreakerConfig = {\n failureThreshold: 5,\n baseOpenMs: 30_000,\n maxBackoffMs: 1_800_000,\n probeTimeoutMs: 600_000,\n}\n\nexport const BREAKER_EXEMPT_CATEGORIES: readonly FailureCategory[] = [\n \"rate_limited\",\n \"quota_exhausted\",\n \"user_cancelled\",\n]\n\n/**\n * Persistent breaker record for one resource. `openCount` drives the doubling\n * backoff and resets only when the breaker closes (a probe or an observed\n * success). Rate limiting, quota exhaustion and user cancellation are\n * deliberately exempt from breaker counting: the first two own their own\n * windowed resource states (counting them would double-punish a resource\n * already known to need a cooldown), and a user-interrupted probe says\n * nothing about resource health, so an interrupted probe re-arms the same\n * window rather than doubling it. `probeId` identifies the single admitted\n * probe while half-open so stale or forged probe reports can be rejected;\n * `probeAt` records when it was admitted so a probe whose outcome report is\n * lost can expire instead of wedging the resource half-open forever.\n */\nexport interface BreakerRecord {\n readonly state: BreakerState\n readonly failures: number\n readonly openCount: number\n readonly reopenAt?: number | undefined\n readonly probeId?: string | undefined\n readonly probeAt?: number | undefined\n}\n","/**\n * Resource health types (ADP-007, ADP-012, ADP-021).\n *\n * A resource is identified at the narrowest scope the evidence supports:\n * provider → account → model → variant. Health states are a closed set and\n * every transition between them is defined by the pure transition layer; the\n * registry never invents states. The circuit breaker (ADP-019) is an\n * orthogonal axis stored per resource record.\n */\nimport {\n DEFAULT_BREAKER_CONFIG,\n type BreakerConfig,\n type BreakerRecord,\n} from \"../circuit-breaker/types.js\"\nimport type { FailureCategory } from \"../classifier/types.js\"\n\nexport const RESOURCE_SCOPES = [\n \"provider\",\n \"account\",\n \"model\",\n \"variant\",\n] as const satisfies readonly string[]\n\nexport type ResourceScope = (typeof RESOURCE_SCOPES)[number]\n\n/**\n * Hierarchical resource identity. The scope is derived from the most specific\n * field present, so callers attribute evidence at exactly the level they can\n * prove (e.g. a provider-wide outage without a model id stays at provider\n * scope; a per-variant failure quarantines only that variant).\n */\nexport interface ResourceKey {\n readonly providerID: string\n readonly accountID?: string | undefined\n readonly modelID?: string | undefined\n readonly variantID?: string | undefined\n}\n\nexport const HEALTH_STATES = [\n \"healthy\",\n \"draining\",\n \"degraded\",\n \"rate_limited\",\n \"quota_exhausted\",\n \"unavailable\",\n] as const satisfies readonly string[]\n\nexport type HealthState = (typeof HEALTH_STATES)[number]\n\n/**\n * A time-bounded window during which the current state is known to hold\n * (e.g. until a Retry-After delay or a quota reset elapses). Absent when no\n * reset time is known — recovery then relies on probes, observed successes,\n * or explicit resets.\n */\nexport interface ResourceWindow {\n readonly kind: \"rate-limit\" | \"quota\"\n readonly until: number\n}\n\nexport interface ResourceRecord {\n readonly key: ResourceKey\n readonly health: HealthState\n readonly breaker: BreakerRecord\n readonly window?: ResourceWindow | undefined\n readonly updatedAt: number\n}\n\n/**\n * Health evidence events. `failure` carries an already-classified category\n * (from the error classifier, ADP-009) plus the classification's\n * definitiveness and parsed retry delay. `capacity` carries a CapacitySensor\n * reading (ADP-020) — `exhausted: false` is positive evidence of capacity.\n * `reset` is the manual Control-mode recovery op.\n */\nexport type HealthEvent =\n | {\n readonly kind: \"failure\"\n readonly key: ResourceKey\n readonly category: FailureCategory\n readonly definitive: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"success\"; readonly key: ResourceKey }\n | { readonly kind: \"drain\"; readonly key: ResourceKey }\n | {\n readonly kind: \"capacity\"\n readonly key: ResourceKey\n readonly exhausted: boolean\n readonly retryAfterMs?: number | undefined\n }\n | { readonly kind: \"reset\"; readonly key: ResourceKey }\n\nexport interface ResourceHealthConfig {\n readonly breaker: BreakerConfig\n /** Window applied to rate-limited evidence that carries no Retry-After. */\n readonly defaultRateLimitWindowMs: number\n /**\n * Window applied to quota exhaustion that carries no reset delay. Without\n * one the state would be permanent (it is persisted and rehydrated), so an\n * unknown reset re-admits the resource after this window and lets fresh\n * evidence re-mark it (ADP-012).\n */\n readonly defaultQuotaWindowMs: number\n}\n\nexport const DEFAULT_HEALTH_CONFIG: ResourceHealthConfig = {\n breaker: DEFAULT_BREAKER_CONFIG,\n defaultRateLimitWindowMs: 30_000,\n defaultQuotaWindowMs: 15 * 60_000,\n}\n\n/** Injected monotonic clock, milliseconds. */\nexport type Clock = () => number\n\n/**\n * Why an assessment blocks new work. Ordered from hardest to softest fact:\n * hard resource states (unavailable, quota, rate limit) are direct evidence;\n * breaker reasons are inferred from failure counts; draining is a policy\n * request, not a health fact.\n */\nexport const BLOCKED_REASONS = [\n \"unavailable\",\n \"quota-exhausted\",\n \"rate-limited\",\n \"breaker-open\",\n \"probe-in-flight\",\n \"draining\",\n] as const satisfies readonly string[]\n\nexport type BlockedReason = (typeof BLOCKED_REASONS)[number]\n\n/** Opaque single-probe admission token; validated on report. */\nexport interface ProbeTicket {\n readonly id: string\n readonly key: ResourceKey\n}\n\nexport type ProbeOutcome =\n { readonly success: true } | { readonly success: false; readonly category: FailureCategory }\n\n/**\n * Result of assessing whether a resource may take new work right now. The\n * `blocked` variant reports the winning blocker's key (which may be a wider\n * scope than the assessed key) and, when known, when the block can lift.\n */\nexport type Assessment =\n | { readonly kind: \"available\" }\n | { readonly kind: \"probe\"; readonly ticket: ProbeTicket }\n | {\n readonly kind: \"blocked\"\n readonly reason: BlockedReason\n readonly key: ResourceKey\n readonly retryAtMs?: number\n }\n","/**\n * Resource key helpers: scope derivation and canonical identity.\n */\nimport type { ResourceKey, ResourceScope } from \"./types.js\"\n\n/** The scope a key is attributed at: the most specific present field. */\nexport function resourceScope(key: ResourceKey): ResourceScope {\n if (key.variantID !== undefined) {\n return \"variant\"\n }\n if (key.modelID !== undefined) {\n return \"model\"\n }\n if (key.accountID !== undefined) {\n return \"account\"\n }\n return \"provider\"\n}\n\n/** Canonical string identity for map keys and receipts. */\nexport function resourceKeyID(key: ResourceKey): string {\n return JSON.stringify([\n key.providerID,\n key.accountID ?? null,\n key.modelID ?? null,\n key.variantID ?? null,\n ])\n}\n\n/**\n * The chain of scopes implied by `key`, ordered widest → narrowest. Each level\n * keeps the narrower fields that are present, so a key without an account\n * (OpenCode model references carry only provider and model) still yields a\n * model-level entry. Health assessment walks this chain because a blocked\n * ancestor blocks every descendant (e.g. a provider-wide rate limit skips all\n * of its models). A variant field without a model field is degenerate and\n * contributes no level of its own.\n */\nexport function resourceChain(key: ResourceKey): ResourceKey[] {\n const chain: ResourceKey[] = [{ providerID: key.providerID }]\n if (key.accountID !== undefined) {\n chain.push({ providerID: key.providerID, accountID: key.accountID })\n }\n if (key.modelID !== undefined) {\n chain.push(\n key.accountID === undefined\n ? { providerID: key.providerID, modelID: key.modelID }\n : { providerID: key.providerID, accountID: key.accountID, modelID: key.modelID },\n )\n }\n if (key.modelID !== undefined && key.variantID !== undefined) {\n chain.push(\n key.accountID === undefined\n ? { providerID: key.providerID, modelID: key.modelID, variantID: key.variantID }\n : {\n providerID: key.providerID,\n accountID: key.accountID,\n modelID: key.modelID,\n variantID: key.variantID,\n },\n )\n }\n return chain\n}\n","/**\n * Scheduler types (ADP-013/015/016/022): the pure decision core's vocabulary.\n *\n * The core is a total function over its inputs — routing outcome, demand,\n * inventory, per-candidate health and capacity views — and never performs\n * effects. Effects (switching, receipts, parking) belong to the execution\n * layer. OBSERVE and CONTROL call the same core; mode handling is a pure\n * wrapper (`forMode`).\n */\nimport type { ModelRef } from \"../work-unit/types.js\"\nimport type { RoutingDecision, TierName } from \"../tier-policy/types.js\"\nimport type { CandidateModel, Demand } from \"../compatibility/types.js\"\nimport type { Assessment } from \"../../health/resource-health/types.js\"\nimport type { CapacitySignals } from \"../../health/capacity/types.js\"\nimport { INCOMPATIBILITY_REASONS } from \"../compatibility/types.js\"\nimport { BLOCKED_REASONS } from \"../../health/resource-health/types.js\"\nimport { resourceKeyID } from \"../../health/resource-health/key.js\"\n\n/** Operating modes (GOAL manual control). The plugin defaults to `observe`. */\nexport const OPERATING_MODES = [\"off\", \"observe\", \"active\"] as const satisfies readonly string[]\n\nexport type OperatingMode = (typeof OPERATING_MODES)[number]\n\n/** Why an `apply` decision chose its model (receipt provenance). */\nexport const APPLY_REASONS = [\n \"pin\",\n \"preferred\",\n \"fallback\",\n \"probe\",\n \"draining\",\n] as const satisfies readonly string[]\n\nexport type ApplyReason = (typeof APPLY_REASONS)[number]\n\n/**\n * Why the core did not apply anything.\n * - `routing-defer` — the tier ladder deferred; OpenCode's choice stands.\n * - `pin-unverifiable` — the pinned model is not in the host inventory, so\n * availability cannot be verified (inventory gate); deferring keeps the\n * user's own model choice, which for a pin is typically the pinned model.\n * - `pin-incompatible` — the pinned model cannot execute the work.\n * - `escalation-*` — escalation evidence was absent, the budget was spent,\n * the tier ladder is at its ceiling, or the next tier has no resources\n * (no cross-tier borrowing).\n * - `adaptive-off` — the plugin is off; only reachable through `forMode`.\n */\nexport const SCHEDULER_DEFER_REASONS = [\n \"routing-defer\",\n \"pin-unverifiable\",\n \"pin-incompatible\",\n \"escalation-not-justified\",\n \"escalation-budget-exhausted\",\n \"escalation-ceiling\",\n \"escalation-no-candidate\",\n \"adaptive-off\",\n] as const satisfies readonly string[]\n\nexport type SchedulerDeferReason = (typeof SCHEDULER_DEFER_REASONS)[number]\n\n/**\n * Why work parks instead of applying: the required tier has no usable\n * resource right now. Parking waits for recovery — it never borrows across\n * tiers (ADP-022).\n */\nexport const PARK_REASONS = [\n \"pin-blocked\",\n \"no-candidates\",\n \"no-compatible-resource\",\n \"all-blocked\",\n] as const satisfies readonly string[]\n\nexport type ParkReason = (typeof PARK_REASONS)[number]\n\n/** Why a tier candidate was not usable. Superset of gate and health reasons. */\nexport const SKIP_REASONS = [\n \"not-in-inventory\",\n \"capacity-exhausted\",\n ...INCOMPATIBILITY_REASONS,\n ...BLOCKED_REASONS,\n] as const satisfies readonly string[]\n\nexport type SkipReason = (typeof SKIP_REASONS)[number]\n\n/** A tier candidate that could not take the work, with the bounded reason. */\nexport interface SkippedCandidate {\n readonly ref: ModelRef\n readonly why: SkipReason\n}\n\n/** Bounded evidence attached to an `apply` decision. */\nexport interface ApplyEvidence {\n /** Candidates considered before the applied one, in order (bounded). */\n readonly skipped: readonly SkippedCandidate[]\n /** Breaker probe id when the applied unit is the half-open probe. */\n readonly probeId?: string | undefined\n}\n\nexport interface ApplyDecision {\n readonly kind: \"apply\"\n readonly model: ModelRef\n /** Required tier; `undefined` for pin routing (a pin is not a tier). */\n readonly tier?: TierName | undefined\n readonly reason: ApplyReason\n readonly evidence: ApplyEvidence\n}\n\nexport interface DeferDecision {\n readonly kind: \"defer\"\n readonly reason: SchedulerDeferReason\n readonly detail?: string | undefined\n}\n\nexport interface ParkDecision {\n readonly kind: \"park\"\n readonly reason: ParkReason\n readonly detail?: string | undefined\n}\n\n/** Structured capability evidence for escalation (ADP-015). Never prose mining. */\nexport const ESCALATION_EVIDENCE_KINDS = [\n \"agent-request\",\n \"reviewer-rejection\",\n \"verification-failure\",\n \"repeated-failure\",\n \"explicit-blocker\",\n] as const satisfies readonly string[]\n\nexport type EscalationEvidenceKind = (typeof ESCALATION_EVIDENCE_KINDS)[number]\n\nexport interface EscalationEvidence {\n readonly kind: EscalationEvidenceKind\n readonly detail?: string | undefined\n}\n\n// Persisted receipt vocabulary. The planner produces only \"tier\" today; the\n// historical \"variant\" step stays parseable so old receipts are not dropped.\nexport const ESCALATION_STEPS = [\"variant\", \"tier\"] as const satisfies readonly string[]\n\nexport type EscalationStep = (typeof ESCALATION_STEPS)[number]\n\n/** Finite per-unit escalation budget (ADP-015). `used >= max` ends escalation. */\nexport interface EscalationBudget {\n readonly used: number\n readonly max: number\n}\n\n/** Bound on evidence carried by an `escalate` decision (latest wins). */\nexport const MAX_ESCALATION_EVIDENCE = 4\n\nexport interface EscalationInput {\n readonly currentModel: ModelRef\n readonly currentTier: TierName\n /** Configured resources of the next tier, user order, already gated. */\n readonly nextTierResources: readonly ModelRef[]\n /** Non-empty structured evidence justifies escalation. */\n readonly evidence: readonly EscalationEvidence[]\n readonly budget: EscalationBudget\n}\n\nexport interface EscalateDecision {\n readonly kind: \"escalate\"\n readonly target: ModelRef\n readonly step: EscalationStep\n /** Tier of the escalated-to resource (the next tier). */\n readonly tier: TierName\n readonly evidence: readonly EscalationEvidence[]\n readonly budgetRemaining: number\n}\n\n/** OBSERVE mode's wrapper: the identical decision, recorded but not applied. */\nexport interface ObserveOnlyDecision {\n readonly kind: \"observe-only\"\n readonly would: Decision\n}\n\nexport type Decision =\n ApplyDecision | DeferDecision | ParkDecision | EscalateDecision | ObserveOnlyDecision\n\n/** What admission can return — escalation never originates from admission. */\nexport type AdmissionDecision = ApplyDecision | DeferDecision | ParkDecision\n\n/**\n * Everything admission looks at. `health` and `capacity` are keyed by\n * `schedulerHealthKey(ref)`; an absent health entry means \"no observed\n * failure\" (the registry's default), an absent capacity entry means \"no\n * estimate\" — unknown is never treated as exhausted.\n */\nexport interface SchedulerInput {\n readonly routing: RoutingDecision\n readonly demand: Demand\n /** Host inventory (adapter-normalized). Candidates absent here are unverifiable. */\n readonly inventory: readonly CandidateModel[]\n /** Configured resources of the required tier, in user order (ADP-005). */\n readonly tierCandidates: readonly ModelRef[]\n readonly health: Readonly<Record<string, Assessment>>\n readonly capacity: Readonly<Record<string, CapacitySignals>>\n}\n\n/** Bound on the `skipped` evidence list of an `apply` decision. */\nexport const MAX_EVIDENCE_SKIPPED = 8\n\n/** Canonical health/capacity map key for a candidate model reference. */\nexport function schedulerHealthKey(ref: ModelRef): string {\n return resourceKeyID(\n ref.variant === undefined\n ? { providerID: ref.providerID, modelID: ref.id }\n : { providerID: ref.providerID, modelID: ref.id, variantID: ref.variant },\n )\n}\n","/**\n * Work-unit model (ADP-001): one unit is exactly one OpenCode execution\n * episode — `session.execution.started` → `succeeded`/`failed`/`interrupted`.\n * Tool/step/text continuations never open, close, or split a unit (only the\n * execution events do); a subagent runs in its own session and therefore gets\n * its own units; a later continuation on the same session (e.g. a new /goal\n * round) is a new episode of that session.\n */\nimport type { InterruptReason } from \"./interruption.js\"\n\n/** OpenCode model reference (`Model.Ref`): provider, model, optional variant. */\nexport interface ModelRef {\n readonly providerID: string\n readonly id: string\n readonly variant?: string | undefined\n}\n\n/** Full-field equality; a variant change is a different reference. */\nexport function sameModelRef(a: ModelRef, b: ModelRef): boolean {\n return a.providerID === b.providerID && a.id === b.id && a.variant === b.variant\n}\n\n/**\n * How the model in effect became known. `selected-*` comes from the\n * `session.model.selected` event (which fires for both manual and\n * plugin-made switches — the tracker resolves which via pending own-switch\n * notes, see `WorkUnitTracker.noteOwnSwitch`); `request` comes from the\n * `context` hook and reports the model actually executing.\n */\nexport const MODEL_SOURCES = [\n \"selected-adaptive\",\n \"selected-external\",\n \"request\",\n] as const satisfies readonly string[]\n\nexport type ModelSource = (typeof MODEL_SOURCES)[number]\n\nexport interface ModelTransition {\n readonly at: number\n readonly model: ModelRef\n readonly source: ModelSource\n}\n\n/**\n * Minimal shape of the wire `Session.StructuredError` carried by\n * `session.execution.failed` (`response.body` is deliberately dropped here —\n * the adapter folds it into bounded `ErrorEvidence` for the classifier).\n */\nexport interface ExecutionError {\n readonly type: string\n readonly message: string\n readonly status?: number | undefined\n readonly retryAfterMs?: number | undefined\n}\n\n/**\n * The episode lifecycle. `kind` doubles as status: `\"active\"` while the\n * execution runs, then the terminal kind it closed with.\n */\ninterface UnitBase {\n /** Stable per-episode identifier: `${sessionID}#${episode}`. */\n readonly id: string\n readonly sessionID: string\n /** 1-based count of episodes started for this session (tracker lifetime). */\n readonly episode: number\n readonly startedAt: number\n /**\n * Model in effect for the unit: seeded from the last known selection when\n * the unit opens, then updated by transitions.\n */\n readonly model?: ModelRef | undefined\n readonly transitions: readonly ModelTransition[]\n}\n\nexport interface ActiveUnit extends UnitBase {\n readonly kind: \"active\"\n}\n\nexport interface SucceededUnit extends UnitBase {\n readonly kind: \"succeeded\"\n readonly closedAt: number\n}\n\nexport interface FailedUnit extends UnitBase {\n readonly kind: \"failed\"\n readonly closedAt: number\n readonly error: ExecutionError\n}\n\nexport interface InterruptedUnit extends UnitBase {\n readonly kind: \"interrupted\"\n readonly closedAt: number\n readonly reason: InterruptReason\n}\n\nexport type ClosedUnit = SucceededUnit | FailedUnit | InterruptedUnit\n\nexport type WorkUnit = ActiveUnit | ClosedUnit\n\n/**\n * Normalized episode events. The OpenCode adapter unwraps host event payloads\n * (`event.data.*`) and forwards them here; `model-request` is fed from the\n * `context` session hook.\n */\nexport type WorkUnitEvent =\n | { readonly kind: \"execution-started\"; readonly sessionID: string; readonly at: number }\n | { readonly kind: \"execution-succeeded\"; readonly sessionID: string; readonly at: number }\n | {\n readonly kind: \"execution-failed\"\n readonly sessionID: string\n readonly at: number\n readonly error: ExecutionError\n }\n | {\n readonly kind: \"execution-interrupted\"\n readonly sessionID: string\n readonly at: number\n readonly reason: InterruptReason\n }\n | {\n readonly kind: \"model-selected\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n | {\n readonly kind: \"model-request\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n\n/**\n * Why an event produced no state change. Only terminal events can be ignored\n * — they arrive without an active unit when the terminal was already handled\n * (duplicate delivery) or never preceded by `execution-started`.\n */\nexport const IGNORED_REASONS = [\"terminal-without-active-unit\"] as const satisfies readonly string[]\n\nexport type IgnoredReason = (typeof IGNORED_REASONS)[number]\n\n/** Result of an execution-started event: the tracker always opens (possibly superseding). */\nexport type OpenedResult = Extract<ApplyResult, { kind: \"opened\" }>\n\n/** Result of a selection event: the tracker always records model knowledge. */\nexport type SelectionResult = Extract<\n ApplyResult,\n { kind: \"model-noted\" } | { kind: \"model-tracked\" }\n>\n\nexport type ApplyResult =\n | {\n readonly kind: \"opened\"\n readonly unit: ActiveUnit\n readonly superseded?: ClosedUnit | undefined\n }\n | { readonly kind: \"closed\"; readonly unit: ClosedUnit }\n | {\n readonly kind: \"model-tracked\"\n readonly unit: ActiveUnit\n readonly transition: ModelTransition\n }\n /** Model knowledge recorded with no active unit; remembered for the next admission. */\n | { readonly kind: \"model-noted\"; readonly transition: ModelTransition }\n | { readonly kind: \"ignored\"; readonly reason: IgnoredReason }\n","/**\n * User-configured tier lists (ADP-005): each tier is an ordered list of\n * resources; list order is user policy and is never reordered by Adaptive.\n * Normalization only removes unusable entries and exact duplicates — it\n * never reorders and never merges look-alike names (ADP-006: similar model\n * names across providers are never equivalent unless the user configures\n * both, and full-reference equality below is deliberately provider-scoped).\n */\nimport { sameModelRef, type ModelRef } from \"../work-unit/types.js\"\n\nexport function normalizeTierList(resources: readonly ModelRef[]): ModelRef[] {\n const kept: ModelRef[] = []\n for (const resource of resources) {\n if (resource.providerID.length === 0 || resource.id.length === 0) {\n continue\n }\n if (kept.some((existing) => sameModelRef(existing, resource))) {\n continue\n }\n kept.push(resource)\n }\n return kept\n}\n","/**\n * Tier-policy types (ADP-002..006). Tier names are an ecosystem proposal —\n * OpenCode has no native capability-tier API — so every tier semantic lives\n * in this module and nowhere else.\n */\nimport type { ModelRef } from \"../work-unit/types.js\"\n\nexport const TIERS = [\"quick\", \"standard\", \"advanced\"] as const satisfies readonly string[]\n\nexport type TierName = (typeof TIERS)[number]\n\n/** Vocabulary guard without a cast: strict member equality. */\nexport function isTierName(tier: string): tier is TierName {\n return TIERS.some((name) => name === tier)\n}\n\n/**\n * Request kinds the OpenCode `context` hook exposes for the executing\n * request. Auxiliary kinds are trivial host-internal requests (title,\n * compaction, generate) that must not consume an unnecessarily expensive\n * tier — this is structured host evidence, not prompt keyword matching\n * (ADP-004).\n */\nexport const AUXILIARY_KINDS = [\n \"compaction\",\n \"title\",\n \"generate\",\n] as const satisfies readonly string[]\n\nexport type AuxiliaryKind = (typeof AUXILIARY_KINDS)[number]\n\nexport type RequestKind = \"primary\" | AuxiliaryKind\n\n/** Auxiliary requests route to `quick`. */\nexport const AUXILIARY_TIER: TierName = \"quick\"\n\n/** Unambiguous fallback tier (ADP-002). */\nexport const DEFAULT_TIER: TierName = \"standard\"\n\n/** How an explicit tier request reached the plugin (provenance for receipts). */\nexport const TIER_REQUEST_VIAS = [\n \"manual-command\",\n \"session-setting\",\n] as const satisfies readonly string[]\n\nexport type TierRequestVia = (typeof TIER_REQUEST_VIAS)[number]\n\nexport interface TierRequest {\n readonly tier: TierName\n readonly via: TierRequestVia\n}\n\n/**\n * Everything the ladder may look at, all optional except the configuration\n * view. Every signal is a structured field supplied by the adapter — never\n * text mined from a prompt.\n */\nexport interface RoutingInput {\n /** Explicit user/model pin (manual control); always wins (ADP-002). */\n readonly pin?: ModelRef | undefined\n /** Explicit tier request (manual command or session setting). */\n readonly tierRequest?: TierRequest | undefined\n /** OpenCode agent name of the executing request, when the host supplies one. */\n readonly agent?: string | undefined\n /** Request kind from the `context` hook, when known. */\n readonly requestKind?: RequestKind | undefined\n /** User-configured agent-name → tier mapping (role hints are user policy). */\n readonly agentTiers?: Readonly<Record<string, TierName>> | undefined\n /**\n * Tiers that currently have at least one configured resource (ADP-005).\n * A tier without resources can never be honored — Adaptive does not\n * invent resources and never borrows across tiers (GOAL tenet 4).\n */\n readonly configuredTiers: readonly TierName[]\n}\n\n/** Why the ladder produced a tier decision (receipt provenance). */\nexport const ROUTING_SOURCES = [\n \"pin\",\n \"tier-request\",\n \"agent-role\",\n \"auxiliary-request\",\n \"ambiguity\",\n \"default\",\n] as const satisfies readonly string[]\n\nexport type RoutingSource = (typeof ROUTING_SOURCES)[number]\n\nexport const DEFER_REASONS = [\"tier-not-configured\"] as const satisfies readonly string[]\n\nexport type DeferReason = (typeof DEFER_REASONS)[number]\n\n/**\n * Routing outcome (ADP-002/003):\n * - `pin` — route to the pinned resource.\n * - `tier` — route within the named tier.\n * - `defer` — Adaptive has no reason to override ordinary OpenCode behavior;\n * the unit keeps OpenCode's model choice. `tier` records which tier the\n * ladder resolved to before the configuration gate blocked it.\n */\nexport type RoutingDecision =\n | { readonly kind: \"pin\"; readonly model: ModelRef }\n | { readonly kind: \"tier\"; readonly tier: TierName; readonly source: RoutingSource }\n | { readonly kind: \"defer\"; readonly tier: TierName; readonly reason: DeferReason }\n\n/** True only for the trivial auxiliary request kinds. */\nexport function isAuxiliary(kind: RequestKind): boolean {\n return kind !== \"primary\"\n}\n\n/**\n * Escalation ladder order (GOAL capability escalation): `quick` → `standard`\n * → `advanced`. `advanced` is the last tier — there is no next.\n */\nexport function nextTier(tier: TierName): TierName | undefined {\n const index = TIERS.indexOf(tier)\n return TIERS[index + 1]\n}\n","/**\n * Bounded shape validation and migration-on-read (ADP-036). Every parser is\n * total: it accepts `unknown` and either returns a typed value or `undefined`\n * — the read path always falls back to a default rather than throwing, so a\n * corrupted record can never take the plugin (or the host) down (ADP-031).\n *\n * Plain objects are never indexed with untrusted strings beyond own-property\n * checks (`Object.hasOwn`) — prototype-chain keys like \"toString\" must not be\n * mistaken for data (project-wide audit rule).\n */\nimport { OPERATING_MODES } from \"../../routing/scheduler/types.js\"\nimport type { OperatingMode } from \"../../routing/scheduler/types.js\"\nimport { normalizeTierList } from \"../../routing/tier-policy/tier-list.js\"\nimport { TIERS } from \"../../routing/tier-policy/types.js\"\nimport type { TierName } from \"../../routing/tier-policy/types.js\"\nimport type { ModelRef } from \"../../routing/work-unit/types.js\"\nimport { MAX_AGENT_TIERS, MAX_TIER_RESOURCES, SETTINGS_VERSION } from \"./types.js\"\nimport type { SettingsV1 } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/** One field's patch-path parse outcome: a validated value or a field error. */\ntype FieldParse<T> = { ok: true; value: T } | { ok: false; error: string }\n\n/**\n * Quoted, bounded rendering of an untrusted patch value inside an error\n * message (errors travel to surfaces over RPC; JSON.stringify is only ever\n * called on strings here, so a cyclic object cannot make applyPatch throw).\n */\nfunction describePatchValue(value: unknown): string {\n if (typeof value === \"string\") {\n const quoted = JSON.stringify(value)\n return quoted.length > 64 ? `${quoted.slice(0, 64)}…` : quoted\n }\n if (value === null) return \"null\"\n if (typeof value === \"object\") return \"object\"\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value)\n return typeof value\n}\n\nexport function parseMode(raw: unknown): OperatingMode | undefined {\n if (typeof raw !== \"string\") return undefined\n return OPERATING_MODES.find((mode) => mode === raw)\n}\n\n/**\n * Legacy persisted value: v1 settings written before the `control → active`\n * rename store `mode: \"control\"`. Migration-on-read maps it; patches stay\n * strict (wire input must use the current vocabulary).\n */\nfunction parseLegacyMode(raw: unknown): OperatingMode | undefined {\n return raw === \"control\" ? \"active\" : parseMode(raw)\n}\n\nexport function parseTierLists(\n raw: unknown,\n): Readonly<Record<TierName, readonly ModelRef[]>> | undefined {\n if (!isRecord(raw)) return undefined\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n tiers[tier] = normalizeTierListValue(raw[tier])\n }\n return tiers\n}\n\n/** Shared per-tier normalization (drop invalid, dedupe, cap) for both paths. */\nfunction normalizeTierListValue(list: unknown): readonly ModelRef[] {\n return Array.isArray(list)\n ? normalizeTierList(\n list.map(parseModelRef).filter((ref): ref is ModelRef => ref !== undefined),\n ).slice(0, MAX_TIER_RESOURCES)\n : []\n}\n\nexport function parseModelRef(raw: unknown): ModelRef | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = raw[\"providerID\"]\n const id = raw[\"id\"]\n const variant = raw[\"variant\"]\n if (typeof providerID !== \"string\" || providerID === \"\") return undefined\n if (typeof id !== \"string\" || id === \"\") return undefined\n return {\n providerID,\n id,\n ...(typeof variant === \"string\" && variant !== \"\" ? { variant } : {}),\n }\n}\n\nexport function parsePin(raw: unknown): ModelRef | null | undefined {\n if (raw === null) return null\n return parseModelRef(raw)\n}\n\nexport function parseAgentTiers(raw: unknown): Readonly<Record<string, TierName>> | undefined {\n if (!isRecord(raw)) return undefined\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (agent === \"\") continue\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) continue\n entries.push([agent, parsed])\n if (entries.length === MAX_AGENT_TIERS) break\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return Object.fromEntries(entries)\n}\n\nfunction parseModelessTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\n/**\n * Patch-path tier-list validation. Unlike the read path (which fills missing\n * or unusable tiers with `[]`), a patch that names `tiers` REPLACES the whole\n * map — silently filling an omitted key with `[]` would wipe that tier's\n * configured resources, so every key must be present and array-typed. List\n * contents still go through the shared normalization (drop invalid, dedupe,\n * cap), which is repair of user-typed entries rather than data loss.\n */\nfunction parseTierListsPatch(\n raw: unknown,\n): FieldParse<Readonly<Record<TierName, readonly ModelRef[]>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid tiers\" }\n const missing = TIERS.filter((tier) => raw[tier] === undefined)\n if (missing.length > 0) {\n const named = missing.map((tier) => JSON.stringify(tier)).join(\", \")\n return { ok: false, error: `invalid tiers: missing ${named}` }\n }\n const tiers = {} as Record<TierName, readonly ModelRef[]>\n for (const tier of TIERS) {\n const list = raw[tier]\n if (!Array.isArray(list)) {\n return { ok: false, error: `invalid tiers: ${JSON.stringify(tier)} must be an array` }\n }\n tiers[tier] = normalizeTierListValue(list)\n }\n return { ok: true, value: tiers }\n}\n\n/**\n * Patch-path agent-tier validation. Unlike the read path (which drops invalid\n * entries as migration-on-read repair), a patch REPLACES the whole map —\n * silently dropping entries would let a single typo wipe the persisted hints,\n * so any invalid entry (and an over-cap patch) is rejected with an error that\n * names the offending field and value.\n */\nfunction parseAgentTiersPatch(raw: unknown): FieldParse<Readonly<Record<string, TierName>>> {\n if (!isRecord(raw)) return { ok: false, error: \"invalid agentTiers\" }\n const entries: [string, TierName][] = []\n for (const [agent, tier] of Object.entries(raw)) {\n if (entries.length === MAX_AGENT_TIERS) {\n return {\n ok: false,\n error: `invalid agentTiers: more than ${String(MAX_AGENT_TIERS)} entries`,\n }\n }\n if (agent === \"\") return { ok: false, error: \"invalid agentTiers: empty agent name\" }\n const parsed = parseModelessTier(tier)\n if (parsed === undefined) {\n return {\n ok: false,\n error: `invalid agentTiers entry ${describePatchValue(agent)}: ${describePatchValue(tier)}`,\n }\n }\n entries.push([agent, parsed])\n }\n // `Object.fromEntries` creates own data properties, so even a \"__proto__\"\n // key from JSON input cannot pollute the prototype here.\n return { ok: true, value: Object.fromEntries(entries) }\n}\n\n/** Settings with nothing configured: OBSERVE, empty tiers, no pin (ADP-029/032). */\nexport function defaultSettings(): SettingsV1 {\n return {\n version: SETTINGS_VERSION,\n mode: \"observe\",\n tiers: { quick: [], standard: [], advanced: [] },\n pin: null,\n agentTiers: {},\n inviteDismissed: false,\n }\n}\n\n/**\n * Migration-on-read. `undefined`/absent record → defaults (first install);\n * versionless (v0 draft) and v1 records are validated field-wise with\n * defaults for unusable fields; a record written by a NEWER version is\n * returned as defaults rather than guessed at (and is only re-persisted once\n * the user changes something, which stamps the current version).\n */\nexport function migrateSettings(raw: unknown): SettingsV1 {\n if (!isRecord(raw)) return defaultSettings()\n const version = raw[\"version\"]\n if (version !== SETTINGS_VERSION && version !== 0 && version !== undefined) {\n return defaultSettings()\n }\n return fieldsFrom(raw)\n}\n\nfunction fieldsFrom(raw: Record<string, unknown>): SettingsV1 {\n const mode = parseLegacyMode(raw[\"mode\"]) ?? \"observe\"\n const tiers = parseTierLists(raw[\"tiers\"]) ?? defaultSettings().tiers\n const pin = parsePin(raw[\"pin\"]) ?? null\n const agentTiers = parseAgentTiers(raw[\"agentTiers\"]) ?? {}\n const inviteDismissed = raw[\"inviteDismissed\"] === true\n return { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed }\n}\n\n/**\n * Validate a patch against current settings. The patch is WIRE input (unknown\n * by contract — surfaces send untrusted JSON over RPC; the SettingsPatch type\n * documents the expected shape, the field parsers enforce it). Invalid fields\n * collect error strings (at most one per field, five fields); a valid patch\n * produces a NEW settings object (inputs are never mutated).\n */\nexport function applyPatch(\n current: SettingsV1,\n patch: unknown,\n): { ok: true; settings: SettingsV1 } | { ok: false; errors: string[] } {\n if (!isRecord(patch)) return { ok: false, errors: [\"invalid patch\"] }\n const request = patch as {\n mode?: unknown\n tiers?: unknown\n pin?: unknown\n agentTiers?: unknown\n inviteDismissed?: unknown\n }\n const errors: string[] = []\n let mode = current.mode\n let tiers = current.tiers\n let pin = current.pin\n let agentTiers = current.agentTiers\n let inviteDismissed = current.inviteDismissed\n\n if (request.mode !== undefined) {\n const parsed = parseMode(request.mode)\n if (parsed === undefined) errors.push(\"invalid mode\")\n else mode = parsed\n }\n if (request.tiers !== undefined) {\n const parsed = parseTierListsPatch(request.tiers)\n if (parsed.ok) tiers = parsed.value\n else errors.push(parsed.error)\n }\n // `pin === null` is a meaningful clear and must not read as absence.\n if (request.pin !== undefined) {\n const parsed = parsePin(request.pin)\n if (parsed === undefined) errors.push(\"invalid pin\")\n else pin = parsed\n }\n if (request.agentTiers !== undefined) {\n const parsed = parseAgentTiersPatch(request.agentTiers)\n if (parsed.ok) agentTiers = parsed.value\n else errors.push(parsed.error)\n }\n if (request.inviteDismissed !== undefined) {\n if (typeof request.inviteDismissed !== \"boolean\") errors.push(\"invalid inviteDismissed\")\n else inviteDismissed = request.inviteDismissed\n }\n\n if (errors.length > 0) return { ok: false, errors }\n return {\n ok: true,\n settings: { version: SETTINGS_VERSION, mode, tiers, pin, agentTiers, inviteDismissed },\n }\n}\n","/**\n * Continuation prompt for owned recovery and parked-work resume (ADP-023).\n * Continues from session state; never replays the original instruction once\n * tool side effects may exist. The executor sends exactly this prompt — the\n * never-replay invariant is structural, not a caller responsibility.\n */\nexport const CONTINUATION_PROMPT =\n \"Continue the interrupted work from the current session state. Do not repeat completed work; resume from what the session already produced.\"\n","/**\n * The Adaptive-owned escalation request surface (T-18, ADP-015..017). The\n * schema requires a reason and evidence — it is deliberately the smallest\n * typed mechanism for an agent to request stronger capability, and it is not\n * a planning or task-management API. The request is recorded against the\n * current work unit and applies at the next safe boundary within the finite\n * per-unit budget; a completing unit discards it (routing re-runs fresh).\n */\nimport type { FailureCategory } from \"../../health/classifier/types.js\"\n\n/** The tool name as registered with the host. */\nexport const ESCALATION_TOOL_NAME = \"adaptive_escalate\"\n\n/** Each field is bounded — the request never carries unbounded prose. */\nexport const MAX_ESCALATION_FIELD_LENGTH = 256\n\nexport interface EscalationRequest {\n readonly reason: string\n readonly evidence: string\n}\n\n/**\n * Truncates to `max` UTF-16 code units without splitting a surrogate pair:\n * a trailing high surrogate whose low half was cut is dropped, so the\n * persisted evidence never carries a lone surrogate.\n */\nexport function truncateBounded(text: string, max: number): string {\n if (text.length <= max) return text\n const cut = text.slice(0, max)\n const last = cut.charCodeAt(cut.length - 1)\n return last >= 0xd800 && last <= 0xdbff ? cut.slice(0, -1) : cut\n}\n\n/**\n * Total parser for the tool input (the host forwards model-produced JSON, so\n * the runtime shape is untrusted even though the standard schema describes\n * it). Both fields are required, non-empty, and bounded.\n */\nexport function parseEscalationRequest(input: unknown): EscalationRequest | undefined {\n if (typeof input !== \"object\" || input === null) return undefined\n const record = input as Record<string, unknown>\n const reason = record[\"reason\"]\n const evidence = record[\"evidence\"]\n if (typeof reason !== \"string\" || reason.length === 0) return undefined\n if (typeof evidence !== \"string\" || evidence.length === 0) return undefined\n return {\n reason: truncateBounded(reason, MAX_ESCALATION_FIELD_LENGTH),\n evidence: truncateBounded(evidence, MAX_ESCALATION_FIELD_LENGTH),\n }\n}\n\n/** One-line summary recorded as escalation evidence (bounded). */\nexport function escalationDetail(request: EscalationRequest): string {\n return truncateBounded(`${request.reason}: ${request.evidence}`, MAX_ESCALATION_FIELD_LENGTH)\n}\n\n/**\n * Failure categories that count as structured capability evidence (ADP-015).\n * The remaining evidence kinds (agent request, reviewer rejection) have no\n * structured host source and are never inferred from free text.\n */\nexport const CAPABILITY_FAILURE_CATEGORIES: readonly FailureCategory[] = [\n \"context_overflow\",\n \"content_policy\",\n]\n\n/** Finite per-task escalation budget (ADP-017). */\nexport const MAX_ESCALATIONS_PER_TASK = 2\n","/**\n * Fail-open logging (ADP-031). The supervisor never throws from its public\n * entry points; unexpected failures are logged with a bounded scope line and\n * swallowed. Logging is the degradation path, not a channel for secrets —\n * only the error's string form, bounded, is emitted.\n */\n\n/** Bound for the logged error text (bounded diagnostics, ADP-030 spirit). */\nexport const LOG_ERROR_LENGTH = 200\n\n/** Log one swallowed internal failure under the plugin's namespace. */\nexport function logFailOpen(scope: string, error: unknown): void {\n const detail = String(error).slice(0, LOG_ERROR_LENGTH)\n console.error(`[coool.adaptive] ${scope}: ${detail}`)\n}\n","import { defaultSettings, migrateSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport {\n MAX_AGENT_TIERS,\n MAX_TIER_RESOURCES,\n type SettingsV1,\n type PatchResult,\n} from \"@coool/adaptive-core/state/settings/types\"\nimport { isTierName, TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport function object(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction invalid(field: string): never {\n throw new Error(`Adaptive settings: invalid ${field}`)\n}\n\nfunction reference(value: unknown, field: string): void {\n if (\n !object(value) ||\n Object.keys(value).some((key) => ![\"providerID\", \"id\", \"variant\"].includes(key))\n )\n invalid(field)\n for (const key of [\"providerID\", \"id\"]) {\n const id = value[key]\n if (typeof id !== \"string\" || id.trim() === \"\" || id.length > 128) invalid(field)\n }\n const variant = value[\"variant\"]\n if (\n variant !== undefined &&\n (typeof variant !== \"string\" || variant.trim() === \"\" || variant.length > 128)\n )\n invalid(field)\n}\n\n/** Validate before using core's forgiving migration/normalization on durable data. */\nfunction validate(raw: Record<string, unknown>, reading: boolean): void {\n if (\n Object.keys(raw).some(\n (key) => ![\"version\", \"mode\", \"tiers\", \"pin\", \"agentTiers\", \"inviteDismissed\"].includes(key),\n )\n )\n invalid(\"field\")\n const version = raw[\"version\"]\n if (version !== undefined && version !== 1 && !(reading && version === 0)) invalid(\"version\")\n const mode = raw[\"mode\"]\n if (\n mode !== undefined &&\n !(typeof mode === \"string\" && [\"off\", \"observe\", \"active\"].includes(mode)) &&\n !(reading && mode === \"control\")\n )\n invalid(\"mode\")\n if (raw[\"pin\"] !== undefined && raw[\"pin\"] !== null) reference(raw[\"pin\"], \"pin\")\n if (raw[\"inviteDismissed\"] !== undefined && typeof raw[\"inviteDismissed\"] !== \"boolean\")\n invalid(\"inviteDismissed\")\n const tiers = raw[\"tiers\"]\n if (tiers !== undefined) {\n if (!object(tiers) || Object.keys(tiers).some((key) => !isTierName(key))) invalid(\"tiers\")\n for (const tier of TIERS) {\n const list: unknown = tiers[tier]\n if (!Array.isArray(list) || list.length > MAX_TIER_RESOURCES) invalid(`tiers.${tier}`)\n const seen = new Set<string>()\n for (const entry of list) {\n reference(entry, `tiers.${tier}`)\n const key = JSON.stringify(entry, [\"providerID\", \"id\", \"variant\"])\n if (seen.has(key)) invalid(`tiers.${tier}`)\n seen.add(key)\n }\n }\n }\n const agents = raw[\"agentTiers\"]\n if (agents !== undefined) {\n if (!object(agents) || Object.keys(agents).length > MAX_AGENT_TIERS) invalid(\"agentTiers\")\n for (const [agent, tier] of Object.entries(agents))\n if (agent.trim() === \"\" || typeof tier !== \"string\" || !isTierName(tier))\n invalid(\"agentTiers\")\n }\n}\n\nexport function parseSettings(raw: unknown): SettingsV1 {\n if (raw === undefined) return defaultSettings()\n if (!object(raw)) invalid(\"record\")\n validate(raw, true)\n return migrateSettings(raw)\n}\n\nexport async function readSettings(file: Pick<JsonFile, \"read\">): Promise<SettingsV1> {\n return parseSettings(await file.read())\n}\n\nexport function updateSettings(file: JsonFile, patch: unknown): Promise<PatchResult> {\n return file.update<PatchResult>((raw) => {\n const current = parseSettings(raw)\n try {\n if (!object(patch)) invalid(\"patch\")\n validate(patch, false)\n } catch (error) {\n return {\n next: undefined,\n result: { ok: false, errors: [String(error).replace(\"Error: Adaptive settings: \", \"\")] },\n }\n }\n const settings = migrateSettings({ ...current, ...patch, version: 1 })\n return { next: settings, result: { ok: true, settings } }\n })\n}\n","import type { JsonFile } from \"./store.js\"\nimport { object } from \"./settings.js\"\n\nexport const NOTE_VERBOSITIES = [\"quiet\", \"changes\", \"all\"] as const\nexport type NoteVerbosity = (typeof NOTE_VERBOSITIES)[number]\nexport interface PiPreferences {\n readonly version: 1\n readonly verbosity: NoteVerbosity\n readonly escalateFromPinned: boolean\n}\n\nfunction fields(raw: unknown): Partial<PiPreferences> {\n if (!object(raw)) throw new Error(\"Adaptive preferences: expected an object\")\n if (Object.keys(raw).some((key) => ![\"version\", \"verbosity\", \"escalateFromPinned\"].includes(key)))\n throw new Error(\"Adaptive preferences: unknown field\")\n if (raw[\"version\"] !== undefined && raw[\"version\"] !== 1)\n throw new Error(\"Adaptive preferences.version: expected 1\")\n const verbosity = NOTE_VERBOSITIES.find((value) => value === raw[\"verbosity\"])\n if (raw[\"verbosity\"] !== undefined && verbosity === undefined)\n throw new Error(\"Adaptive preferences.verbosity: expected quiet, changes, or all\")\n const escalate = raw[\"escalateFromPinned\"]\n if (escalate !== undefined && typeof escalate !== \"boolean\")\n throw new Error(\"Adaptive preferences.escalateFromPinned: expected a boolean\")\n return {\n ...(verbosity === undefined ? {} : { verbosity }),\n ...(typeof escalate === \"boolean\" ? { escalateFromPinned: escalate } : {}),\n }\n}\n\nexport function parsePreferences(raw: unknown): PiPreferences {\n return {\n version: 1,\n verbosity: \"changes\",\n escalateFromPinned: false,\n ...(raw === undefined ? {} : fields(raw)),\n }\n}\n\nexport async function readPreferences(file: Pick<JsonFile, \"read\">): Promise<PiPreferences> {\n return parsePreferences(await file.read())\n}\n\nexport function updatePreferences(file: JsonFile, patch: unknown): Promise<PiPreferences> {\n return file.update((raw) => {\n const next = { ...parsePreferences(raw), ...fields(patch) }\n return { next, result: next }\n })\n}\n","/**\n * Bounding for receipts (ADP-030). Receipts are built from typed scheduler\n * decisions, but every string they can carry is truncated to\n * `MAX_RECEIPT_TEXT` before persisting — including identifiers. Boundedness\n * is what makes the no-secrets invariant checkable: no field accepts\n * unbounded text, so nothing unbounded can be persisted.\n */\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n ObserveOnlyDecision,\n ParkDecision,\n} from \"../../routing/scheduler/types.js\"\nimport type { ModelRef } from \"../../routing/work-unit/types.js\"\nimport { truncateBounded } from \"../../execution/escalation/types.js\"\nimport { MAX_RECEIPT_TEXT } from \"./types.js\"\n\n/**\n * Agent-written evidence can carry emoji; cutting between the halves of a\n * surrogate pair would persist a lone surrogate that renders as garbage and\n * throws in URI encoders, so the cut backs off to the pair boundary.\n */\nexport function boundText(raw: string): string {\n return truncateBounded(raw, MAX_RECEIPT_TEXT)\n}\n\nfunction boundRef(ref: ModelRef): ModelRef {\n return {\n providerID: boundText(ref.providerID),\n id: boundText(ref.id),\n ...(ref.variant !== undefined ? { variant: boundText(ref.variant) } : {}),\n }\n}\n\nfunction boundApply(decision: ApplyDecision): ApplyDecision {\n return {\n kind: \"apply\",\n model: boundRef(decision.model),\n ...(decision.tier !== undefined ? { tier: decision.tier } : {}),\n reason: decision.reason,\n evidence: {\n skipped: decision.evidence.skipped.map((skip) => ({\n ref: boundRef(skip.ref),\n why: skip.why,\n })),\n ...(decision.evidence.probeId !== undefined\n ? { probeId: boundText(decision.evidence.probeId) }\n : {}),\n },\n }\n}\n\nfunction boundDefer(decision: DeferDecision): DeferDecision {\n return {\n kind: \"defer\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundPark(decision: ParkDecision): ParkDecision {\n return {\n kind: \"park\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundEscalate(decision: EscalateDecision): EscalateDecision {\n return {\n kind: \"escalate\",\n target: boundRef(decision.target),\n step: decision.step,\n tier: decision.tier,\n evidence: decision.evidence.map((item) => ({\n kind: item.kind,\n ...(item.detail !== undefined ? { detail: boundText(item.detail) } : {}),\n })),\n budgetRemaining: decision.budgetRemaining,\n }\n}\n\nfunction boundObserveOnly(decision: ObserveOnlyDecision, depth: number): ObserveOnlyDecision {\n return { kind: \"observe-only\", would: boundDecision(decision.would, depth + 1) }\n}\n\n/**\n * Structural copy of a decision with every string bounded. `depth` guards\n * the `observe-only` recursion (max one nesting level is ever produced).\n */\nexport function boundDecision(decision: Decision, depth = 0): Decision {\n switch (decision.kind) {\n case \"apply\":\n return boundApply(decision)\n case \"defer\":\n return boundDefer(decision)\n case \"park\":\n return boundPark(decision)\n case \"escalate\":\n return boundEscalate(decision)\n case \"observe-only\":\n return depth < 2 ? boundObserveOnly(decision, depth) : decision\n }\n}\n","/**\n * Why an OpenCode execution was interrupted. Values mirror the verified\n * `session.execution.interrupted` event payload (`reason`), which OpenCode\n * guarantees to be one of these four.\n */\nexport const INTERRUPT_REASONS = [\n \"user\",\n \"shutdown\",\n \"superseded\",\n \"inactivity\",\n] as const satisfies readonly string[]\n\nexport type InterruptReason = (typeof INTERRUPT_REASONS)[number]\n","/**\n * Failure classification types (ADP-008, ADP-009).\n *\n * The classifier consumes a layered evidence record assembled by the OpenCode\n * adapter. Evidence layers exist so classification can honor the ADP-008\n * precedence chain: structured metadata beats HTTP status beats standard\n * headers beats documented provider-specific metadata beats bounded text.\n */\nimport type { InterruptReason } from \"../../routing/work-unit/interruption.js\"\n\nexport const FAILURE_CATEGORIES = [\n \"rate_limited\",\n \"quota_exhausted\",\n \"outage\",\n \"overload\",\n \"timeout\",\n \"auth_failure\",\n \"invalid_model\",\n \"context_overflow\",\n \"content_policy\",\n \"user_cancelled\",\n \"unknown\",\n] as const satisfies readonly string[]\n\nexport type FailureCategory = (typeof FAILURE_CATEGORIES)[number]\n\n/**\n * Where the winning classification came from. Exposed so receipts can show\n * why a decision was made and so tests can pin the precedence chain.\n */\nexport const EVIDENCE_LAYERS = [\n \"interruption\",\n \"structured\",\n \"status\",\n \"headers\",\n \"provider-metadata\",\n \"textual\",\n \"none\",\n] as const satisfies readonly string[]\n\nexport type EvidenceLayer = (typeof EVIDENCE_LAYERS)[number]\n\n/**\n * Structured OpenCode evidence (`Session.StructuredError`): a server-assigned\n * error tag plus, when the provider sent it, a retry delay OpenCode already\n * parsed from `Retry-After`. `type` is a free-form string on the wire, so the\n * classifier only interprets types from the documented @opencode/protocol\n * vocabulary and falls through to lower layers for anything unmapped instead\n * of guessing.\n */\nexport interface StructuredSignal {\n readonly type: string\n readonly retryAfterMs?: number | undefined\n}\n\n/**\n * Documented provider-specific metadata, already normalized by our own\n * adapters (e.g. the Codex capacity sensor validates `x-codex-*` headers\n * before producing these). The classifier never reads raw provider headers\n * itself.\n */\nexport interface ProviderMetadata {\n readonly quotaExhausted?: boolean | undefined\n readonly overloaded?: boolean | undefined\n}\n\n/**\n * Layered failure evidence. `status` is the merged HTTP status (the adapter\n * prefers the wire status seen by `http.response` over any status echoed in\n * structured metadata). `text` is the bounded concatenation of error message\n * and response body, bounded again defensively inside the classifier.\n */\nexport interface ErrorEvidence {\n readonly interrupted?: InterruptReason | undefined\n readonly structured?: StructuredSignal | undefined\n readonly status?: number | undefined\n readonly headers?: Readonly<Record<string, string>> | undefined\n readonly providerMetadata?: ProviderMetadata | undefined\n readonly text?: string | undefined\n}\n\n/** Advisory retry semantics; the retry policy (T-12) makes final decisions. */\nexport interface RetryAdvice {\n readonly retryable: boolean\n readonly retryAfterMs?: number\n}\n\nexport interface FailureClassification {\n readonly category: FailureCategory\n readonly layer: EvidenceLayer\n /** Explicit shared subscription/balance evidence; absent means keep the model scope. */\n readonly quotaScope?: \"provider\"\n /**\n * True when the evidence conclusively identifies the failure. Textual\n * classifications are always non-definitive; scheduling treats\n * non-definitive evidence more conservatively (ADP-012).\n */\n readonly definitive: boolean\n readonly retry: RetryAdvice\n /** Horizontal recovery (switch resource within the tier) is allowed. */\n readonly failoverEligible: boolean\n}\n","/**\n * Read-side parsing for persisted receipts. Every parser is total: it accepts\n * `unknown` and returns typed records, dropping anything invalid — a\n * corrupted receipts file can never take the plugin down (ADP-031). Reason\n * vocabularies are membership-checked (the write path is typed); free-text\n * fields are re-bounded. An older plugin reading newer receipts may drop\n * unknown-vocabulary entries — receipts are bounded diagnostics, eviction is\n * expected behavior, and the payload version guards the schema itself.\n */\nimport {\n APPLY_REASONS,\n ESCALATION_EVIDENCE_KINDS,\n ESCALATION_STEPS,\n PARK_REASONS,\n SKIP_REASONS,\n SCHEDULER_DEFER_REASONS,\n} from \"../../routing/scheduler/types.js\"\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n EscalationEvidence,\n ObserveOnlyDecision,\n ParkDecision,\n SkippedCandidate,\n} from \"../../routing/scheduler/types.js\"\nimport { TIERS } from \"../../routing/tier-policy/types.js\"\nimport type { TierName } from \"../../routing/tier-policy/types.js\"\nimport { INTERRUPT_REASONS } from \"../../routing/work-unit/interruption.js\"\nimport { FAILURE_CATEGORIES } from \"../../health/classifier/types.js\"\nimport { parseModelRef } from \"../settings/parse.js\"\nimport { boundText } from \"./bound.js\"\nimport { MAX_RECEIPTS, RECEIPTS_VERSION } from \"./types.js\"\nimport type { Receipt, ReceiptOutcome } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction boundString(raw: unknown): string | undefined {\n return typeof raw === \"string\" ? boundText(raw) : undefined\n}\n\nfunction isFiniteNonNegative(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\nfunction parseTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\nfunction parseOptionalBounded(raw: unknown): string | undefined {\n const value = boundString(raw)\n return value === \"\" ? undefined : value\n}\n\n/** Free-text detail keeps empty strings (round-trips through the store). */\nfunction parseDetailBounded(raw: unknown): string | undefined {\n return boundString(raw) ?? undefined\n}\n\nfunction parseApplyEvidence(raw: unknown): ApplyDecision[\"evidence\"] | undefined {\n if (!isRecord(raw)) return undefined\n const skippedRaw = raw[\"skipped\"]\n if (!Array.isArray(skippedRaw)) return undefined\n const skipped: SkippedCandidate[] = []\n for (const entry of skippedRaw.slice(0, 8)) {\n if (!isRecord(entry)) continue\n const ref = parseModelRef(entry[\"ref\"])\n const why = parseVocab(entry[\"why\"], SKIP_REASONS)\n if (ref === undefined || why === undefined) continue\n skipped.push({ ref, why })\n }\n const probeId = parseDetailBounded(raw[\"probeId\"])\n return { skipped, ...(probeId !== undefined ? { probeId } : {}) }\n}\n\nfunction parseApply(raw: Record<string, unknown>): ApplyDecision | undefined {\n const model = parseModelRef(raw[\"model\"])\n const reason = parseVocab(raw[\"reason\"], APPLY_REASONS)\n const evidence = parseApplyEvidence(raw[\"evidence\"])\n if (model === undefined || reason === undefined || evidence === undefined) {\n return undefined\n }\n const tier = parseTier(raw[\"tier\"])\n return {\n kind: \"apply\",\n model,\n ...(tier !== undefined ? { tier } : {}),\n reason,\n evidence,\n }\n}\n\nfunction parseDefer(raw: Record<string, unknown>): DeferDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], SCHEDULER_DEFER_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"defer\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parsePark(raw: Record<string, unknown>): ParkDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], PARK_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"park\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parseEscalate(raw: Record<string, unknown>): EscalateDecision | undefined {\n const target = parseModelRef(raw[\"target\"])\n const step = parseVocab(raw[\"step\"], ESCALATION_STEPS)\n const tier = parseTier(raw[\"tier\"])\n const budgetRemainingRaw = raw[\"budgetRemaining\"]\n if (\n target === undefined ||\n step === undefined ||\n tier === undefined ||\n !isFiniteNonNegative(budgetRemainingRaw)\n ) {\n return undefined\n }\n const evidenceRaw = raw[\"evidence\"]\n if (!Array.isArray(evidenceRaw)) return undefined\n const evidence: EscalationEvidence[] = []\n for (const entry of evidenceRaw.slice(0, 4)) {\n if (!isRecord(entry)) continue\n const kind = parseVocab(entry[\"kind\"], ESCALATION_EVIDENCE_KINDS)\n if (kind === undefined) continue\n const detail = parseDetailBounded(entry[\"detail\"])\n evidence.push({ kind, ...(detail !== undefined ? { detail } : {}) })\n }\n return {\n kind: \"escalate\",\n target,\n step,\n tier,\n evidence,\n budgetRemaining: budgetRemainingRaw,\n }\n}\n\n/** Max `observe-only` nesting accepted on read (the scheduler produces ≤ 1). */\nconst MAX_PARSE_DEPTH = 2\n\nfunction parseObserveOnly(\n raw: Record<string, unknown>,\n depth: number,\n): ObserveOnlyDecision | undefined {\n if (depth >= MAX_PARSE_DEPTH) return undefined\n const would = parseDecision(raw[\"would\"], depth + 1)\n return would === undefined ? undefined : { kind: \"observe-only\", would }\n}\n\nfunction parseDecision(raw: unknown, depth = 0): Decision | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"kind\"]) {\n case \"apply\":\n return parseApply(raw)\n case \"defer\":\n return parseDefer(raw)\n case \"park\":\n return parsePark(raw)\n case \"escalate\":\n return parseEscalate(raw)\n case \"observe-only\":\n return parseObserveOnly(raw, depth)\n default:\n return undefined\n }\n}\n\nfunction parseOutcome(raw: unknown): ReceiptOutcome | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"status\"]) {\n case \"succeeded\":\n return { status: \"succeeded\" }\n case \"failed\": {\n const category = parseVocab(raw[\"category\"], FAILURE_CATEGORIES)\n return category === undefined ? undefined : { status: \"failed\", category }\n }\n case \"interrupted\": {\n const reason = parseVocab(raw[\"reason\"], INTERRUPT_REASONS)\n return reason === undefined ? undefined : { status: \"interrupted\", reason }\n }\n default:\n return undefined\n }\n}\n\nfunction parseReceipt(raw: unknown): Receipt | undefined {\n if (!isRecord(raw)) return undefined\n const id = raw[\"id\"]\n const at = raw[\"at\"]\n const sessionID = parseOptionalBounded(raw[\"sessionID\"])\n const decision = parseDecision(raw[\"decision\"])\n if (\n !(isFiniteNonNegative(id) && Number.isInteger(id) && isFiniteNonNegative(at)) ||\n sessionID === undefined ||\n decision === undefined\n ) {\n return undefined\n }\n const unitID = parseOptionalBounded(raw[\"unitID\"])\n const tier = parseTier(raw[\"tier\"])\n // A present-but-invalid outcome invalidates the whole record: stripping\n // just the outcome would break first-outcome-wins across a restart (the\n // receipt would accept a later, different outcome as its first).\n let outcome: ReceiptOutcome | undefined\n if (raw[\"outcome\"] !== undefined) {\n outcome = parseOutcome(raw[\"outcome\"])\n if (outcome === undefined) return undefined\n }\n return {\n id,\n at,\n sessionID,\n ...(unitID !== undefined ? { unitID } : {}),\n ...(tier !== undefined ? { tier } : {}),\n decision,\n ...(outcome !== undefined ? { outcome } : {}),\n }\n}\n\n/**\n * Parse a persisted receipts payload. Accepts the versioned shape and a\n * versionless draft array; anything else yields no receipts.\n */\nexport function parseReceiptsPayload(raw: unknown): Receipt[] {\n let list: unknown\n if (isRecord(raw)) {\n const version = raw[\"version\"]\n if (version !== RECEIPTS_VERSION && version !== undefined) return []\n list = raw[\"receipts\"]\n } else if (Array.isArray(raw)) {\n list = raw\n }\n if (!Array.isArray(list)) return []\n const parsed = list\n .map(parseReceipt)\n .filter((receipt): receipt is Receipt => receipt !== undefined)\n return parsed.length > MAX_RECEIPTS ? parsed.slice(-MAX_RECEIPTS) : parsed\n}\n","/**\n * Bounded receipt store (ADP-030). Receipts live in a ring capped at\n * `MAX_RECEIPTS` (newest kept, oldest evicted) and persist through the\n * storage seam on every mutation. Ids are monotonic across restarts (they\n * continue from the persisted maximum) so a receipt can always be told apart\n * from its neighbors. Write failures propagate to the caller — the wiring\n * layer's fail-open wrapper decides how to degrade (ADP-031) — and the\n * in-memory ring is only advanced after a successful write, so memory and\n * disk never diverge.\n */\nimport { boundDecision, boundText } from \"./bound.js\"\nimport { parseReceiptsPayload } from \"./parse.js\"\nimport { MAX_RECEIPTS, RECEIPTS_VERSION } from \"./types.js\"\nimport type {\n Receipt,\n ReceiptInput,\n ReceiptOutcome,\n ReceiptsPayload,\n ReceiptsStorage,\n} from \"./types.js\"\n\nexport interface ReceiptRef {\n readonly sessionID: string\n /** When given, only receipts of that unit are updated; otherwise only receipts without a unit. */\n readonly unitID?: string | undefined\n}\n\nexport class ReceiptStore {\n #receipts: Receipt[] = []\n #counter = 0\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: ReceiptsStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#receipts = []\n return\n }\n const parsed = parseReceiptsPayload(raw)\n this.#receipts = parsed\n this.#counter = parsed.reduce((max, receipt) => Math.max(max, receipt.id), 0)\n }\n\n /** All retained receipts, oldest → newest. */\n snapshot(): readonly Receipt[] {\n return this.#receipts\n }\n\n record(input: ReceiptInput): Promise<Receipt> {\n return this.#serialize(() => this.#record(input))\n }\n\n async #record(input: ReceiptInput): Promise<Receipt> {\n // A receipt with no session can never be attributed to anything, and the\n // read path drops empty identifiers — persisting one would make it vanish\n // across a restart. Throw instead; the wiring layer fail-open-catches.\n if (input.sessionID.trim() === \"\") {\n throw new Error(\"invalid receipt: sessionID must be a non-empty string\")\n }\n const id = this.#counter + 1\n const receipt: Receipt = {\n id,\n at: input.at,\n // Identifiers are bounded with the same bound the read path applies, so\n // what is persisted is exactly what comes back (types.ts invariant).\n sessionID: boundText(input.sessionID),\n ...(input.unitID !== undefined ? { unitID: boundText(input.unitID) } : {}),\n ...(input.tier !== undefined ? { tier: input.tier } : {}),\n decision: boundDecision(input.decision),\n }\n const next =\n this.#receipts.length >= MAX_RECEIPTS\n ? [...this.#receipts.slice(1 - MAX_RECEIPTS), receipt]\n : [...this.#receipts, receipt]\n // Persist BEFORE committing memory: a write failure must leave memory and\n // disk consistent (the caller decides how to fail open).\n await this.#persist(next)\n this.#receipts = next\n this.#counter = id\n return receipt\n }\n\n /**\n * Attach a unit outcome to matching receipts that do not have one yet\n * (first outcome wins). Returns how many receipts were updated; zero\n * updates do not touch storage.\n */\n attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n return this.#serialize(() => this.#attachOutcome(ref, outcome))\n }\n\n async #attachOutcome(ref: ReceiptRef, outcome: ReceiptOutcome): Promise<number> {\n let updated = 0\n const next = this.#receipts.map((receipt) => {\n if (receipt.outcome !== undefined) return receipt\n if (receipt.sessionID !== ref.sessionID) return receipt\n const matches =\n ref.unitID !== undefined ? receipt.unitID === ref.unitID : receipt.unitID === undefined\n if (!matches) return receipt\n updated++\n return { ...receipt, outcome }\n })\n if (updated === 0) return 0\n await this.#persist(next)\n this.#receipts = next\n return updated\n }\n\n /**\n * Stamps the unit that just opened onto the session's pending unit-less\n * admission receipts (recorded in the awaited prompt hook, before the unit\n * existed). After adoption the receipt carries the unitID, so outcomes\n * attach to it like any unit-scoped receipt.\n *\n * One opened unit adopts ONE admission — the newest pending receipt. With\n * several pending receipts (a prompt admitted but superseded before its\n * unit ever opened), stamping all of them would attach this unit's outcome\n * to foreign admission decisions; the older receipts stay pending instead.\n */\n adoptUnit(sessionID: string, unitID: string): Promise<number> {\n return this.#serialize(() => this.#adoptUnit(sessionID, unitID))\n }\n\n async #adoptUnit(sessionID: string, unitID: string): Promise<number> {\n let target: number | undefined\n this.#receipts.forEach((receipt, index) => {\n if (receipt.unitID !== undefined || receipt.outcome !== undefined) return\n if (receipt.sessionID !== sessionID) return\n target = index\n })\n if (target === undefined) return 0\n const at = target\n const next = this.#receipts.map((receipt, index) =>\n index === at ? { ...receipt, unitID } : receipt,\n )\n await this.#persist(next)\n this.#receipts = next\n return 1\n }\n\n // Include reads in the chain so a reload cannot overwrite a newer commit.\n // A failed write rejects its caller without blocking subsequent operations.\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n\n /** Writes the given next state; the caller commits memory only on success. */\n async #persist(receipts: readonly Receipt[]): Promise<void> {\n const payload: ReceiptsPayload = {\n version: RECEIPTS_VERSION,\n receipts,\n }\n await this.storage.write(payload)\n }\n}\n","// covers: [\"ADP-030\", \"ADP-051\", \"ADP-059\"]\nimport { isDeepStrictEqual } from \"node:util\"\nimport { ReceiptStore, type ReceiptRef } from \"@coool/adaptive-core/state/receipts/store\"\nimport { parseReceiptsPayload } from \"@coool/adaptive-core/state/receipts/parse\"\nimport type {\n Receipt,\n ReceiptInput,\n ReceiptOutcome,\n} from \"@coool/adaptive-core/state/receipts/types\"\nimport type { JsonTransactionFile } from \"./store.js\"\n\nfunction parse(raw: unknown): readonly Receipt[] {\n if (raw === undefined) return []\n const receipts = parseReceiptsPayload(raw)\n if (!isDeepStrictEqual(raw, { version: 1, receipts }))\n throw new Error(\"Adaptive receipts: invalid receipts.json payload\")\n return receipts\n}\n\nasync function transaction<R>(\n file: JsonTransactionFile,\n change: (store: ReceiptStore) => Promise<R>,\n): Promise<R> {\n return file.transaction(async (current) => {\n const receipts = parse(current)\n let next: unknown\n const store = new ReceiptStore({\n read: () => Promise.resolve({ version: 1, receipts }),\n write: (payload) => {\n next = payload\n return Promise.resolve()\n },\n })\n await store.load()\n return { result: await change(store), next }\n })\n}\n\nexport function recordReceipt(file: JsonTransactionFile, input: ReceiptInput): Promise<Receipt> {\n return transaction(file, (store) => store.record(input))\n}\n\nexport function attachReceiptOutcome(\n file: JsonTransactionFile,\n ref: ReceiptRef,\n outcome: ReceiptOutcome,\n): Promise<number> {\n return transaction(file, (store) => store.attachOutcome(ref, outcome))\n}\n\n/** Shared flow expects newest first; the durable ring remains oldest first. */\nexport async function readReceipts(file: Pick<JsonTransactionFile, \"read\">): Promise<Receipt[]> {\n return [...parse(await file.read())].reverse()\n}\n","import type { CandidateModel, Demand, IncompatibilityReason, Verdict } from \"./types.js\"\n\n/** A finite, non-negative token count is assessable; anything else is unknown demand. */\nfunction assessableTokens(value: number | undefined): value is number {\n return value !== undefined && Number.isFinite(value) && value >= 0\n}\n\nfunction supportsModalities(\n supported: readonly string[] | undefined,\n demanded: readonly string[],\n): boolean {\n if (supported === undefined) {\n return false\n }\n return demanded.every((modality) => supported.includes(modality))\n}\n\n/**\n * Run every check and accumulate reasons in fixed order. A candidate is\n * compatible only when no reason applies; unknown candidate metadata never\n * satisfies a stated requirement.\n */\nexport function checkCompatibility(candidate: CandidateModel, demand: Demand): Verdict {\n const reasons: IncompatibilityReason[] = []\n\n if (candidate.providerEnabled !== true) {\n reasons.push(\"provider-unavailable\")\n }\n if (candidate.enabled !== true) {\n reasons.push(\"model-unavailable\")\n }\n if (candidate.variant !== undefined && candidate.variantAvailable !== true) {\n reasons.push(\"variant-unavailable\")\n }\n\n if (demand.tools === true && candidate.capabilities?.tools !== true) {\n reasons.push(\"tool-use-unsupported\")\n }\n if (\n demand.input !== undefined &&\n demand.input.length > 0 &&\n !supportsModalities(candidate.capabilities?.input, demand.input)\n ) {\n reasons.push(\"input-modality-unsupported\")\n }\n if (\n demand.output !== undefined &&\n demand.output.length > 0 &&\n !supportsModalities(candidate.capabilities?.output, demand.output)\n ) {\n reasons.push(\"output-modality-unsupported\")\n }\n\n if (assessableTokens(demand.contextTokens)) {\n const contextLimit = candidate.limit?.context\n if (!assessableTokens(contextLimit)) {\n reasons.push(\"context-capacity-unknown\")\n } else if (contextLimit < demand.contextTokens) {\n reasons.push(\"context-capacity-insufficient\")\n }\n }\n\n return { compatible: reasons.length === 0, reasons }\n}\n","/**\n * Admission routing (ADP-013/016/022): pick the model for a fresh work unit,\n * or decide to defer (OpenCode's choice stands) or park (wait for recovery).\n *\n * Selection, after the compatibility gate (ADP-017) filters candidates: the\n * first candidate in user order that is ready or due for its half-open probe\n * wins; draining only when none is. Rationale: a due probe at a preferred\n * position is how that resource returns (ADP-018/019) — passing it over for a\n * later ready sibling would keep it out forever; a draining resource is being\n * retired, so depending on it is the last resort. Breaker single-flight is\n * enforced by the resource-health registry, not here.\n */\nimport { checkCompatibility } from \"../compatibility/gate.js\"\nimport type { CandidateModel } from \"../compatibility/types.js\"\nimport type { RoutingDecision, TierName } from \"../tier-policy/types.js\"\nimport { sameModelRef, type ModelRef } from \"../work-unit/types.js\"\nimport type { Assessment } from \"../../health/resource-health/types.js\"\nimport type { CapacitySignals } from \"../../health/capacity/types.js\"\nimport type {\n AdmissionDecision,\n ApplyDecision,\n ApplyReason,\n SchedulerInput,\n SkippedCandidate,\n SkipReason,\n} from \"./types.js\"\nimport { MAX_EVIDENCE_SKIPPED, schedulerHealthKey } from \"./types.js\"\n\n/** The health/capacity view of one candidate, resolved to an admission bucket. */\ntype Bucket =\n | { readonly kind: \"ready\" }\n | { readonly kind: \"probe\"; readonly probeId: string }\n | { readonly kind: \"draining\" }\n | { readonly kind: \"skip\"; readonly why: SkipReason }\n\nfunction refOfCandidate(candidate: CandidateModel): ModelRef {\n return {\n providerID: candidate.providerID,\n id: candidate.modelID,\n variant: candidate.variant,\n }\n}\n\nfunction lookup(inventory: readonly CandidateModel[], ref: ModelRef): CandidateModel | undefined {\n return inventory.find((candidate) => sameModelRef(refOfCandidate(candidate), ref))\n}\n\nfunction classify(\n assessment: Assessment | undefined,\n signals: CapacitySignals | undefined,\n): Bucket {\n if (signals?.exhausted === true) {\n return { kind: \"skip\", why: \"capacity-exhausted\" }\n }\n if (assessment === undefined) {\n return signals?.draining === true ? { kind: \"draining\" } : { kind: \"ready\" }\n }\n if (assessment.kind === \"probe\") {\n return { kind: \"probe\", probeId: assessment.ticket.id }\n }\n if (assessment.kind === \"available\") {\n return signals?.draining === true ? { kind: \"draining\" } : { kind: \"ready\" }\n }\n return assessment.reason === \"draining\"\n ? { kind: \"draining\" }\n : { kind: \"skip\", why: assessment.reason }\n}\n\nfunction apply(\n model: ModelRef,\n tier: TierName | undefined,\n reason: ApplyReason,\n skipped: readonly SkippedCandidate[],\n probeId: string | undefined,\n): ApplyDecision {\n return {\n kind: \"apply\",\n model,\n ...(tier === undefined ? {} : { tier }),\n reason,\n evidence: {\n skipped: skipped.slice(0, MAX_EVIDENCE_SKIPPED),\n ...(probeId === undefined ? {} : { probeId }),\n },\n }\n}\n\nfunction admitPin(input: SchedulerInput, pin: ModelRef): AdmissionDecision {\n const entry = lookup(input.inventory, pin)\n if (entry === undefined) {\n return { kind: \"defer\", reason: \"pin-unverifiable\" }\n }\n const verdict = checkCompatibility(entry, input.demand)\n if (!verdict.compatible) {\n return { kind: \"defer\", reason: \"pin-incompatible\", detail: verdict.reasons.join(\",\") }\n }\n const key = schedulerHealthKey(pin)\n const bucket = classify(input.health[key], input.capacity[key])\n if (bucket.kind === \"skip\") {\n return { kind: \"park\", reason: \"pin-blocked\", detail: bucket.why }\n }\n // Manual intent wins (GOAL): a pinned model is applied even while draining;\n // a probe admission is recorded for observability but never overrides intent.\n return apply(pin, undefined, \"pin\", [], bucket.kind === \"probe\" ? bucket.probeId : undefined)\n}\n\nfunction admitTier(input: SchedulerInput, tier: TierName): AdmissionDecision {\n if (input.tierCandidates.length === 0) {\n // The tier was reported configured but has an empty list — a configuration\n // discrepancy; park rather than invent resources (ADP-005).\n return { kind: \"park\", reason: \"no-candidates\" }\n }\n // Candidates passed over before the winner (or all of them, when none won).\n const seen: { ref: ModelRef; bucket: Extract<Bucket, { kind: \"draining\" | \"skip\" }> }[] = []\n let gateSkipped = 0\n const skipWhys: string[] = []\n let chosen: { ref: ModelRef; bucket: Extract<Bucket, { kind: \"ready\" | \"probe\" }> } | undefined\n for (const ref of input.tierCandidates) {\n const entry = lookup(input.inventory, ref)\n if (entry === undefined) {\n seen.push({ ref, bucket: { kind: \"skip\", why: \"not-in-inventory\" } })\n skipWhys.push(\"not-in-inventory\")\n gateSkipped += 1\n continue\n }\n const verdict = checkCompatibility(entry, input.demand)\n if (!verdict.compatible) {\n // The gate reports incompatible only when at least one reason exists; the\n // non-null assertion is the only way to express that invariant locally.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const why = verdict.reasons[0]!\n seen.push({ ref, bucket: { kind: \"skip\", why } })\n skipWhys.push(why)\n gateSkipped += 1\n continue\n }\n const key = schedulerHealthKey(ref)\n const bucket = classify(input.health[key], input.capacity[key])\n if (bucket.kind === \"ready\" || bucket.kind === \"probe\") {\n // The first ready or probe candidate wins; later candidates are\n // irrelevant, so the scan stops and the evidence stays an honest prefix\n // of the user order.\n chosen = { ref, bucket }\n break\n }\n seen.push({ ref, bucket })\n if (bucket.kind === \"skip\") {\n skipWhys.push(bucket.why)\n }\n }\n const first = input.tierCandidates[0]\n const evidenceBefore = (until: number): SkippedCandidate[] =>\n seen.slice(0, until).map((e): SkippedCandidate => ({\n ref: e.ref,\n why: e.bucket.kind === \"skip\" ? e.bucket.why : \"draining\",\n }))\n if (chosen?.bucket.kind === \"probe\") {\n return apply(chosen.ref, tier, \"probe\", evidenceBefore(seen.length), chosen.bucket.probeId)\n }\n if (chosen !== undefined) {\n return apply(\n chosen.ref,\n tier,\n first !== undefined && sameModelRef(chosen.ref, first) ? \"preferred\" : \"fallback\",\n evidenceBefore(seen.length),\n undefined,\n )\n }\n const drainIndex = seen.findIndex((e) => e.bucket.kind === \"draining\")\n const drainEntry = drainIndex >= 0 ? seen[drainIndex] : undefined\n if (drainEntry !== undefined) {\n return apply(drainEntry.ref, tier, \"draining\", evidenceBefore(drainIndex), undefined)\n }\n const summary = skipWhys.slice(0, 3).join(\",\")\n return {\n kind: \"park\",\n reason: gateSkipped === skipWhys.length ? \"no-compatible-resource\" : \"all-blocked\",\n detail: summary,\n }\n}\n\n/**\n * Decide the model for a fresh work unit. Total and deterministic: the same\n * input always yields the same decision, and the function has no effects.\n */\nexport function admit(input: SchedulerInput): AdmissionDecision {\n const routing: RoutingDecision = input.routing\n if (routing.kind === \"defer\") {\n return { kind: \"defer\", reason: \"routing-defer\", detail: routing.reason }\n }\n if (routing.kind === \"pin\") {\n return admitPin(input, routing.model)\n }\n return admitTier(input, routing.tier)\n}\n","// covers: [\"ADP-002\", \"ADP-005\", \"ADP-009\", \"ADP-013\", \"ADP-017\", \"ADP-022\", \"ADP-057\"]\nimport { admit } from \"@coool/adaptive-core/routing/scheduler/admit\"\nimport type {\n SchedulerInput,\n AdmissionDecision,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\n\nexport const VIRTUAL_IDS = [\"auto\", \"quick\", \"standard\", \"advanced\"] as const\nexport type VirtualID = (typeof VIRTUAL_IDS)[number]\n\nexport interface RouteInput {\n readonly tier: TierName\n /** In-unit request: keep the previous physical model when there is one. */\n readonly sticky: boolean\n readonly settings: SettingsV1\n readonly previous: ModelRef | undefined\n readonly inventory: SchedulerInput[\"inventory\"]\n readonly demand: SchedulerInput[\"demand\"]\n readonly health: SchedulerInput[\"health\"]\n readonly capacity: SchedulerInput[\"capacity\"]\n /** Models this unit already failed over from (same-tier recovery). */\n readonly exclude: readonly ModelRef[]\n}\n\n/** The models a non-sticky admission may dispatch, before exclusions. */\nexport function admissionCandidates(settings: SettingsV1, tier: TierName): readonly ModelRef[] {\n return settings.pin === null ? settings.tiers[tier] : [settings.pin]\n}\n\nfunction excluded(exclude: readonly ModelRef[], ref: ModelRef): boolean {\n return exclude.some((tried) => tried.providerID === ref.providerID && tried.id === ref.id)\n}\n\n/**\n * Admit within the tier, never across it. Recovery first avoids the models\n * this unit already failed on; when nothing else in the tier can take the\n * work, the failed model stays eligible so Pi's own backoff retry proceeds\n * unless health blocks it. A user pin always wins and is never excluded.\n */\nexport function routeAdmission(input: RouteInput): AdmissionDecision {\n // Ordinary tool continuations must never be repriced or re-tiered mid-unit.\n const pin = input.sticky ? input.previous : input.settings.pin\n const decide = (exclude: readonly ModelRef[]) =>\n admit({\n routing:\n pin === undefined || pin === null\n ? { kind: \"tier\", tier: input.tier, source: \"default\" }\n : { kind: \"pin\", model: pin },\n inventory: input.inventory,\n demand: input.demand,\n tierCandidates: input.settings.tiers[input.tier].filter((ref) => !excluded(exclude, ref)),\n health: input.health,\n capacity: input.capacity,\n })\n const decision = decide(input.exclude)\n return decision.kind === \"apply\" || input.exclude.length === 0 ? decision : decide([])\n}\n","import type { ErrorEvidence, FailureCategory, FailureClassification, RetryAdvice } from \"./types.js\"\n\n/**\n * Text fed to the textual last-resort layer is truncated to this bound before\n * matching, so adversarial or enormous error bodies cannot dominate\n * classification cost or smuggle patterns in late bytes (ADP-008).\n */\nconst TEXT_BOUND = 512\n\n// These messages describe the subscription's shared allowance or balance,\n// unlike a generic quota error or a named model-family limit (ADP-007).\nconst SHARED_QUOTA_PATTERN =\n /\\byou['’]ve hit your (?:session|usage|weekly) limit(?=\\s*(?:$|[·.,;(:]|resets?\\b))|\\b(?:out of credits|insufficient credits|credit balance)\\b/i\n\n// A 429 whose message says the quota itself is spent (\"You exceeded your\n// current quota, please check your plan and billing details\") is quota\n// exhaustion: a burst-sized window would re-admit it every half minute. The\n// status stays the definitive evidence; text only picks the window. Messages\n// that also speak of rate limits keep the short window — Gemini words its\n// per-minute 429s as \"exceeded your current quota\" and links its rate-limit\n// docs.\nconst RATE_LIMIT_TEXT = /rate[ _-]?limit|per min/i\n\n/**\n * Retry/failover policy per category (ADP-010, ADP-011).\n *\n * - Infrastructure failures (rate limiting, quota, outage, overload, timeout)\n * are failover-eligible: horizontal recovery within the tier is exactly\n * their remedy.\n * - Permanent configuration failures (auth, invalid model, content policy)\n * and context overflow never retry and never failover: retrying the same\n * request cannot help and switching resources would reproduce the failure.\n * - User cancellation is final: no retry, no failover (ADP-010).\n * - Unknown failures defer to OpenCode's native handling.\n */\nconst CATEGORY_POLICY: Readonly<\n Record<FailureCategory, { retryable: boolean; failoverEligible: boolean }>\n> = {\n rate_limited: { retryable: true, failoverEligible: true },\n quota_exhausted: { retryable: false, failoverEligible: true },\n outage: { retryable: true, failoverEligible: true },\n overload: { retryable: true, failoverEligible: true },\n timeout: { retryable: true, failoverEligible: true },\n auth_failure: { retryable: false, failoverEligible: false },\n invalid_model: { retryable: false, failoverEligible: false },\n context_overflow: { retryable: false, failoverEligible: false },\n content_policy: { retryable: false, failoverEligible: false },\n user_cancelled: { retryable: false, failoverEligible: false },\n unknown: { retryable: false, failoverEligible: false },\n}\n\n/**\n * Error tags from the documented @opencode/protocol vocabulary that map\n * directly to a failure category. Tags absent here (`ProviderRequestError`,\n * `UnknownError`, anything unrecognized) are structured but not\n * category-specific: they never guess, and classification falls through to\n * the refining layers.\n */\nconst STRUCTURED_TYPES = new Map<string, FailureCategory>([\n [\"UnauthorizedError\", \"auth_failure\"],\n [\"ForbiddenError\", \"auth_failure\"],\n [\"ModelNotFoundError\", \"invalid_model\"],\n [\"UnsupportedModelError\", \"invalid_model\"],\n [\"ServiceUnavailableError\", \"outage\"],\n])\n\n/**\n * Bounded textual patterns, last resort only (ADP-008). Ordered most\n * specific first; the first match wins. These encode provider error-message\n * conventions documented by the research phase, not a general-purpose\n * keyword classifier.\n */\nconst TEXTUAL_PATTERNS: readonly {\n readonly category: FailureCategory\n readonly pattern: RegExp\n}[] = [\n {\n category: \"context_overflow\",\n pattern:\n /context (length|window)|maximum context|input length exceeds|prompt is too long|too many (input )?tokens|exceeds the maximum/i,\n },\n {\n // Subscription limits (\"You've hit your session/usage limit\") are quota\n // exhaustion with a provider-side reset window; the reset time in the\n // text is not parsed (the classifier has no clock) — the health layer's\n // default quota window bounds the quarantine instead.\n // Sibling fallback plugins' issue trackers document the real-world\n // phrasings that missed curated whitelists (oh-my-openagent #2393/#5815,\n // lichter's 429 lesson): snake-cased limits, \"usage exceeded\" without\n // \"limit\", credit exhaustion without \"balance\". Qualifiers stay required\n // so \"token limit reached\" (context overflow) never matches quota.\n category: \"quota_exhausted\",\n pattern:\n /\\bquota\\b|credit balance|(?:session|usage|free usage|message|plan|monthly|weekly|daily)[ _-]?limit|usage exceeded|out of credits|insufficient credits/i,\n },\n { category: \"rate_limited\", pattern: /rate ?limit/i },\n { category: \"timeout\", pattern: /\\btimeout\\b|timed? ?out|deadline exceeded|etimedout/i },\n {\n category: \"auth_failure\",\n pattern:\n /unauthorized|invalid (api|access) key|api key (expired|invalid)|authentication|permission denied/i,\n },\n {\n category: \"invalid_model\",\n pattern: /model.{0,30}(does not exist|not found)|invalid model|unknown model|no such model/i,\n },\n {\n // OpenAI-compatible finish reasons arrive snake-cased (\"Provider\n // finish_reason: content_filter\" in pi-ai).\n category: \"content_policy\",\n pattern:\n /content[ _](management[ _])?(policy|filter)|safety system|violates?.{0,32}policy|flagged as/i,\n },\n { category: \"overload\", pattern: /overloaded|over capacity|high demand/i },\n { category: \"user_cancelled\", pattern: /cancel+(l)?ed|aborted by (the )?user|user abort/i },\n]\n\nfunction isHttpStatus(status: number | undefined): status is number {\n return typeof status === \"number\" && Number.isInteger(status) && status >= 100 && status <= 599\n}\n\n/**\n * Upper bound on a provider-claimed retry delay. `Retry-After` and structured\n * retry metadata are untrusted provider data: a hostile or misconfigured\n * value (\"999999999\" seconds) must not convert one response into a\n * near-permanent resource blacklist. The host's own retry scheduling waits\n * out the raw header verbatim — this bound only concerns the health window\n * the supervisor derives from the classification (ADP-011 boundedness).\n */\nconst MAX_RETRY_AFTER_MS = 24 * 60 * 60 * 1000\n\nfunction boundedRetryAfterMs(retryAfterMs: number | undefined): number | undefined {\n if (retryAfterMs === undefined) {\n return undefined\n }\n return Math.min(retryAfterMs, MAX_RETRY_AFTER_MS)\n}\n\nfunction isNonNegativeInteger(value: number | undefined): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 0\n}\n\nfunction lowercasedHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n): ReadonlyMap<string, string> {\n const lowered = new Map<string, string>()\n if (headers === undefined) {\n return lowered\n }\n for (const [name, value] of Object.entries(headers)) {\n lowered.set(name.toLowerCase(), value)\n }\n return lowered\n}\n\n/**\n * Parses a `Retry-After` header into milliseconds. Only the integer-seconds\n * form is accepted: the HTTP-date form requires a clock, which the classifier\n * deliberately does not have (reset-time handling belongs to the capacity\n * boundary, T-05/T-15).\n */\nfunction retryAfterHeaderMs(headers: ReadonlyMap<string, string>): number | undefined {\n const raw = headers.get(\"retry-after\")\n if (raw === undefined || !/^\\d+$/.test(raw)) {\n return undefined\n }\n return Number(raw) * 1000\n}\n\n/**\n * Standard rate-limit headers (case-insensitive `x-ratelimit-remaining*`).\n * All-zero remaining capacity indicates a fixed-window quota exhaustion\n * rather than a short burst limit.\n */\nfunction fixedWindowExhausted(headers: ReadonlyMap<string, string>): boolean {\n let sawRemaining = false\n for (const [name, value] of headers) {\n if (name.startsWith(\"x-ratelimit-remaining\")) {\n sawRemaining = true\n if (value !== \"0\") {\n return false\n }\n }\n }\n return sawRemaining\n}\n\nfunction retryAdvice(category: FailureCategory, retryAfterMs: number | undefined): RetryAdvice {\n const policy = CATEGORY_POLICY[category]\n const bounded = boundedRetryAfterMs(retryAfterMs)\n if (bounded === undefined) {\n return { retryable: policy.retryable }\n }\n return { retryable: policy.retryable, retryAfterMs: bounded }\n}\n\nfunction classification(\n category: FailureCategory,\n layer: FailureClassification[\"layer\"],\n definitive: boolean,\n retryAfterMs: number | undefined,\n quotaScope?: \"provider\",\n): FailureClassification {\n const policy = CATEGORY_POLICY[category]\n return {\n category,\n layer,\n definitive,\n retry: retryAdvice(category, retryAfterMs),\n failoverEligible: policy.failoverEligible,\n ...(quotaScope !== undefined ? { quotaScope } : {}),\n }\n}\n\n/**\n * Classifies an HTTP status. 429 consults the standard rate-limit headers in\n * the same step: status plus documented standard headers are one HTTP\n * semantics layer, and the quota refinement is more specific evidence than a\n * bare 429, so it cannot weaken the ADP-008 precedence.\n */\nfunction classifyStatus(\n status: number,\n headers: ReadonlyMap<string, string>,\n): FailureCategory | undefined {\n if (status === 429) {\n return fixedWindowExhausted(headers) ? \"quota_exhausted\" : \"rate_limited\"\n }\n if (status === 401 || status === 403) {\n return \"auth_failure\"\n }\n if (status === 402) {\n return \"quota_exhausted\"\n }\n if (status === 408) {\n return \"timeout\"\n }\n if (status === 413) {\n return \"context_overflow\"\n }\n if (status === 502 || status === 503 || status === 504) {\n return \"outage\"\n }\n return undefined\n}\n\nfunction classifyText(text: string): FailureCategory | undefined {\n const bounded = text.length > TEXT_BOUND ? text.slice(0, TEXT_BOUND) : text\n for (const { category, pattern } of TEXTUAL_PATTERNS) {\n if (pattern.test(bounded)) {\n return category\n }\n }\n return undefined\n}\n\n/**\n * Total classification of layered failure evidence. Never throws and always\n * returns a category: any evidence shape outside the documented vocabularies\n * classifies as `unknown` via the `none` layer, deferring to OpenCode's\n * native failure handling (ADP-009, ADP-012).\n */\nexport function classifyFailure(evidence: ErrorEvidence): FailureClassification {\n // Layer 0: interruption evidence. Interruptions are host decisions, not\n // provider failures; a user cancellation is final (ADP-010).\n if (evidence.interrupted === \"user\") {\n return classification(\"user_cancelled\", \"interruption\", true, undefined)\n }\n if (evidence.interrupted !== undefined) {\n return classification(\"unknown\", \"interruption\", true, undefined)\n }\n\n // Layer 1: structured OpenCode metadata.\n const structured = evidence.structured\n const structuredRetryAfterMs = isNonNegativeInteger(structured?.retryAfterMs)\n ? structured.retryAfterMs\n : undefined\n if (structured !== undefined) {\n const mapped = STRUCTURED_TYPES.get(structured.type)\n if (mapped !== undefined) {\n return classification(mapped, \"structured\", true, structuredRetryAfterMs)\n }\n // Unmapped tag: fall through so HTTP semantics can refine the category.\n }\n\n // Layer 2: HTTP status (+ standard headers for the 429 refinement).\n const headers = lowercasedHeaders(evidence.headers)\n if (isHttpStatus(evidence.status)) {\n const category = classifyStatus(evidence.status, headers)\n if (category !== undefined) {\n const retryAfterMs = structuredRetryAfterMs ?? retryAfterHeaderMs(headers)\n // Payment Required is the account's balance, not one model's limit:\n // every model behind the provider ID (a gateway such as OpenRouter or\n // Ofox) bills the same account, so a sibling model cannot help.\n if (evidence.status === 402) {\n return classification(category, \"status\", true, retryAfterMs, \"provider\")\n }\n if (category === \"rate_limited\" && evidence.text !== undefined) {\n const bounded = evidence.text.slice(0, TEXT_BOUND)\n if (classifyText(bounded) === \"quota_exhausted\" && !RATE_LIMIT_TEXT.test(bounded)) {\n const quotaScope = SHARED_QUOTA_PATTERN.test(bounded) ? \"provider\" : undefined\n return classification(\"quota_exhausted\", \"status\", true, retryAfterMs, quotaScope)\n }\n }\n return classification(category, \"status\", true, retryAfterMs)\n }\n }\n\n // Layer 3: standard headers alone (Retry-After without a decisive status).\n const headerRetryAfterMs = retryAfterHeaderMs(headers)\n if (headerRetryAfterMs !== undefined) {\n return classification(\"rate_limited\", \"headers\", false, headerRetryAfterMs)\n }\n\n // Layer 4: documented provider-specific metadata, normalized by our own\n // adapters after validation (T-15).\n if (evidence.providerMetadata?.quotaExhausted === true) {\n return classification(\"quota_exhausted\", \"provider-metadata\", true, undefined)\n }\n if (evidence.providerMetadata?.overloaded === true) {\n return classification(\"overload\", \"provider-metadata\", true, structuredRetryAfterMs)\n }\n\n // Layer 5: bounded textual classification, always non-definitive.\n const text = evidence.text\n if (text !== undefined) {\n const category = classifyText(text)\n if (category !== undefined) {\n const quotaScope =\n category === \"quota_exhausted\" && SHARED_QUOTA_PATTERN.test(text.slice(0, TEXT_BOUND))\n ? \"provider\"\n : undefined\n return classification(category, \"textual\", false, structuredRetryAfterMs, quotaScope)\n }\n }\n\n return classification(\"unknown\", \"none\", false, undefined)\n}\n","/**\n * Capability escalation planner (ADP-015).\n *\n * Escalation is justified only by non-empty structured evidence, follows the\n * ladder next tier, and is bounded by the caller's finite budget. The\n * same-model stronger-variant rung is not implemented: it would need an\n * ordered variant ladder the host does not expose, and strength is never\n * guessed from variant names. Every output moves strictly up the ladder or\n * refuses. Termination rests on the budget, which the caller must carry\n * across every unit of one task (each escalation continues on a new unit).\n */\nimport { nextTier } from \"../tier-policy/types.js\"\nimport type { ModelRef } from \"../work-unit/types.js\"\nimport type { DeferDecision, EscalateDecision, EscalationInput } from \"./types.js\"\nimport { MAX_ESCALATION_EVIDENCE } from \"./types.js\"\n\n/**\n * Only a well-formed whole-number budget can bound the loop: NaN, infinite,\n * fractional, or negative counters would make `used >= max` unreachable or\n * leave a negative remainder, so they read as exhausted (finite is the\n * invariant, not the caller's good behavior).\n */\nfunction hasBudgetLeft({ used, max }: EscalationInput[\"budget\"]): boolean {\n return Number.isSafeInteger(used) && Number.isSafeInteger(max) && used >= 0 && used < max\n}\n\nfunction escalate(\n input: EscalationInput,\n target: ModelRef,\n step: EscalateDecision[\"step\"],\n tier: EscalateDecision[\"tier\"],\n): EscalateDecision {\n return {\n kind: \"escalate\",\n target,\n step,\n tier,\n evidence: input.evidence.slice(-MAX_ESCALATION_EVIDENCE),\n budgetRemaining: input.budget.max - input.budget.used - 1,\n }\n}\n\n/**\n * Plan the next escalation step, or defer with the reason escalation cannot\n * proceed. Total and deterministic.\n */\nexport function planEscalation(input: EscalationInput): EscalateDecision | DeferDecision {\n if (input.evidence.length === 0) {\n return { kind: \"defer\", reason: \"escalation-not-justified\" }\n }\n if (!hasBudgetLeft(input.budget)) {\n return { kind: \"defer\", reason: \"escalation-budget-exhausted\" }\n }\n const next = nextTier(input.currentTier)\n if (next === undefined) {\n return { kind: \"defer\", reason: \"escalation-ceiling\" }\n }\n const target = input.nextTierResources[0]\n if (target === undefined) {\n return { kind: \"defer\", reason: \"escalation-no-candidate\" }\n }\n return escalate(input, target, \"tier\", next)\n}\n","// covers: [\"ADP-008\", \"ADP-065\"]\n/**\n * Failure evidence from a Pi assistant message. Pi reports provider failures\n * only as free-text `errorMessage`; there is no structured status field. The\n * pi-ai adapters do place the HTTP status deterministically at the start of\n * that text — SDK errors read \"429 You exceeded…\" or \"503 status code (no\n * body)\", and pi-ai's `formatProviderError` writes \"429: <body>\" or\n * \"<Provider> API error (429): …\" — so the status is recovered from those\n * prefixes only. A status mentioned later in a body is not trusted, and\n * everything else stays textual, non-definitive evidence (ADP-008).\n */\nimport type { ErrorEvidence } from \"@coool/adaptive-core/health/classifier/types\"\n\n/** The structural subset of Pi's `AssistantMessage` this module reads. */\nexport interface FailedMessage {\n readonly stopReason: string\n readonly errorMessage?: string | undefined\n}\n\nconst STATUS_PREFIXES: readonly RegExp[] = [\n /^(\\d{3})(?=[\\s:]|$)/,\n /^[\\w .-]+ API error \\((\\d{3})\\):/,\n]\n\n// pi-ai's Bedrock adapter replaces the SDK exception name with a fixed\n// human-readable prefix and drops the status. AWS documents these exceptions\n// as HTTP 429 and 503; without this, \"Throttling error: Too many tokens…\"\n// would read as context overflow.\nconst BEDROCK_STATUS: readonly (readonly [string, number])[] = [\n [\"Throttling error: \", 429],\n [\"Service unavailable: \", 503],\n]\n\nfunction statusOf(text: string): number | undefined {\n for (const pattern of STATUS_PREFIXES) {\n const digits = pattern.exec(text)?.[1]\n if (digits !== undefined) {\n return Number(digits)\n }\n }\n return BEDROCK_STATUS.find(([prefix]) => text.startsWith(prefix))?.[1]\n}\n\nexport function failureEvidence(message: FailedMessage): ErrorEvidence {\n // Pi marks a user abort (Esc, or the abort signal during retry backoff) as\n // its own stop reason; it is never a provider failure (ADP-010).\n if (message.stopReason === \"aborted\") {\n return { interrupted: \"user\" }\n }\n const text = message.errorMessage?.trim() ?? \"\"\n if (text === \"\") {\n return {}\n }\n const status = statusOf(text)\n return status === undefined ? { text } : { status, text }\n}\n","// covers: [\"ADP-009\", \"ADP-013\", \"ADP-015\", \"ADP-016\", \"ADP-017\", \"ADP-055\", \"ADP-061\"]\n/**\n * Branch-aware task state for the Pi virtual models. Everything is derived\n * from the session branch Pi hands us — router state, tool results, and the\n * hidden continuation message — so forking or rewinding a session also\n * rewinds tier requests and escalation budgets. Pure: no Pi imports.\n */\nimport { classifyFailure } from \"@coool/adaptive-core/health/classifier/classify\"\nimport type { FailureClassification } from \"@coool/adaptive-core/health/classifier/types\"\nimport {\n CAPABILITY_FAILURE_CATEGORIES,\n escalationDetail,\n MAX_ESCALATIONS_PER_TASK,\n parseEscalationRequest,\n} from \"@coool/adaptive-core/execution/escalation/index\"\nimport { planEscalation } from \"@coool/adaptive-core/routing/scheduler/escalate\"\nimport type { EscalationEvidence } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { isTierName, nextTier } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { failureEvidence, type FailedMessage } from \"./evidence.js\"\nimport type { VirtualID } from \"./router.js\"\n\nexport const TIER_TOOL = \"adaptive_tier\"\nexport const CONTINUATION_TYPE = \"adaptive.continuation\"\n// Pi's own custom entry for router state (`VIRTUAL_MODEL_STATE_ENTRY`); the\n// constant is not exported from the package root.\nconst ROUTER_STATE_ENTRY = \"pi.virtual-model-state\"\n/** Infra restarts after a run ended on a provider failure, per task (ADP-061). */\nexport const MAX_RESTARTS_PER_TASK = 2\n\n/** The structural subset of Pi's `SessionEntry` this module reads. */\nexport interface BranchEntry {\n readonly type: string\n readonly customType?: string\n readonly data?: unknown\n readonly details?: unknown\n readonly message?: BranchMessage\n}\n\ninterface BranchMessage {\n readonly role: string\n readonly toolName?: string\n readonly details?: unknown\n readonly provider?: string\n readonly model?: string\n readonly stopReason?: string\n readonly errorMessage?: string\n}\n\n/** Router state stored by Pi on the branch for one virtual model. */\nexport interface TaskState {\n readonly version: 1\n readonly task: string\n readonly unit: string\n readonly tier: TierName\n readonly escalations: number\n readonly restarts: number\n readonly hops?: number\n /** Failed wake deliveries of this task (the give-up budget, ADP-024). */\n readonly wakes?: number\n /** Token of the park this task was resumed from, when it was. */\n readonly wakeToken?: string\n /** Models this unit failed over from; new admissions in the unit avoid them. */\n readonly tried: readonly ModelRef[]\n /** Token of the last owned continuation already turned into a unit. */\n readonly consumed?: string\n}\n\n/** Details of the hidden continuation message that continues a task. */\nexport interface Recovery {\n readonly task: string\n readonly token: string\n readonly tier: TierName\n readonly escalations: number\n readonly restarts: number\n readonly wakes?: number\n /** Set when this continuation resumes parked work (its park's token). */\n readonly wakeToken?: string\n /** Models the new unit starts out avoiding (the one that just failed). */\n readonly tried: readonly ModelRef[]\n}\n\nexport interface RoutePlan {\n readonly tier: TierName\n /** Keep the previous physical model (in-unit continuation or retry). */\n readonly sticky: boolean\n /** Models a non-sticky admission avoids while the tier has alternatives. */\n readonly exclude: readonly ModelRef[]\n readonly state: TaskState | undefined\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\nfunction text(value: unknown, key: string, label: string): string {\n const found = field(value, key)\n if (typeof found !== \"string\" || found.length === 0)\n throw new Error(`${label}: ${key} must be a non-empty string`)\n return found\n}\n\nfunction tier(value: unknown, label: string): TierName {\n const found = field(value, \"tier\")\n if (typeof found !== \"string\" || !isTierName(found))\n throw new Error(`${label}: tier must be quick, standard, or advanced`)\n return found\n}\n\nfunction count(value: unknown, key: string, label: string): number {\n const found = field(value, key)\n if (typeof found !== \"number\" || !Number.isSafeInteger(found) || found < 0)\n throw new Error(`${label}: ${key} must be a non-negative integer`)\n return found\n}\n\nfunction parkingCounts(\n value: unknown,\n label: string,\n): { readonly wakes?: number; readonly hops?: number; readonly wakeToken?: string } {\n const token = field(value, \"wakeToken\")\n if (token !== undefined && (typeof token !== \"string\" || token.length === 0))\n throw new Error(`${label}: wakeToken must be a non-empty string`)\n return {\n ...(field(value, \"wakes\") === undefined ? {} : { wakes: count(value, \"wakes\", label) }),\n ...(field(value, \"hops\") === undefined ? {} : { hops: count(value, \"hops\", label) }),\n ...(token === undefined ? {} : { wakeToken: token }),\n }\n}\n\nfunction refs(value: unknown, label: string): ModelRef[] {\n const found = field(value, \"tried\")\n if (!Array.isArray(found)) throw new Error(`${label}: tried must be an array`)\n return found.map((entry: unknown, index) => ({\n providerID: text(entry, \"providerID\", `${label}: tried[${String(index)}]`),\n id: text(entry, \"id\", `${label}: tried[${String(index)}]`),\n }))\n}\n\nfunction sameRef(left: ModelRef, right: ModelRef): boolean {\n return left.providerID === right.providerID && left.id === right.id\n}\n\n/** Total parser for persisted router state; `undefined` means none yet. */\nexport function parseTaskState(value: unknown): TaskState | undefined {\n if (value === undefined) return undefined\n const label = \"Adaptive task state\"\n if (field(value, \"version\") !== 1) throw new Error(`${label}: version must be 1`)\n const consumed = field(value, \"consumed\")\n if (consumed !== undefined && (typeof consumed !== \"string\" || consumed.length === 0))\n throw new Error(`${label}: consumed must be a non-empty string`)\n return {\n version: 1,\n task: text(value, \"task\", label),\n unit: text(value, \"unit\", label),\n tier: tier(value, label),\n escalations: count(value, \"escalations\", label),\n restarts: count(value, \"restarts\", label),\n ...parkingCounts(value, label),\n tried: refs(value, label),\n ...(consumed === undefined ? {} : { consumed }),\n }\n}\n\nfunction parseRecovery(value: unknown): Recovery {\n const label = \"Adaptive continuation\"\n return {\n task: text(value, \"task\", label),\n token: text(value, \"token\", label),\n tier: tier(value, label),\n escalations: count(value, \"escalations\", label),\n restarts: count(value, \"restarts\", label),\n ...parkingCounts(value, label),\n tried: refs(value, label),\n }\n}\n\n/** Latest router state Pi stored on this branch for `adaptive/<id>`. */\nexport function branchState(branch: readonly BranchEntry[], id: VirtualID): TaskState | undefined {\n const entry = branch.findLast(\n (candidate) =>\n candidate.type === \"custom\" &&\n candidate.customType === ROUTER_STATE_ENTRY &&\n field(candidate.data, \"provider\") === \"adaptive\" &&\n field(candidate.data, \"modelId\") === id,\n )\n return parseTaskState(field(entry?.data, \"state\"))\n}\n\nfunction toolResults(branch: readonly BranchEntry[], name: string): unknown[] {\n return branch.flatMap((entry) =>\n entry.message?.role === \"toolResult\" && entry.message.toolName === name\n ? [entry.message.details]\n : [],\n )\n}\n\n/** The latest recorded `adaptive_tier` request (sticky for the session branch). */\nexport function tierRequest(branch: readonly BranchEntry[]): TierName | undefined {\n const recorded = toolResults(branch, TIER_TOOL)\n .map((details) => field(details, \"tier\"))\n .findLast((value) => typeof value === \"string\" && isTierName(value))\n return typeof recorded === \"string\" && isTierName(recorded) ? recorded : undefined\n}\n\nfunction isUnitStart(entry: BranchEntry): boolean {\n return (\n entry.message?.role === \"user\" ||\n (entry.type === \"custom_message\" && entry.customType === CONTINUATION_TYPE)\n )\n}\n\n/** Entries of the current unit: everything after the latest unit start. */\nfunction currentUnit(branch: readonly BranchEntry[]): readonly BranchEntry[] {\n return branch.slice(branch.findLastIndex(isUnitStart) + 1)\n}\n\n/**\n * The owned continuation that the next `continuation` route must turn into a\n * new unit. Only our hidden message, as the latest conversation entry, for\n * the branch's current task and not yet consumed — any other extension's\n * message or a user prompt in between invalidates it.\n */\nexport function pendingRecovery(\n branch: readonly BranchEntry[],\n state: TaskState | undefined,\n): Recovery | undefined {\n const latest = branch.findLast(\n (entry) => entry.type === \"message\" || entry.type === \"custom_message\",\n )\n if (\n state === undefined ||\n latest?.type !== \"custom_message\" ||\n latest.customType !== CONTINUATION_TYPE\n )\n return undefined\n const recovery = parseRecovery(latest.details)\n return recovery.task === state.task && recovery.token !== state.consumed ? recovery : undefined\n}\n\n/** The request Pi is retrying: what failed and on which physical model. */\nexport interface FailedRequest {\n readonly model: ModelRef\n readonly message: FailedMessage\n}\n\nexport interface PlanRouteInput {\n readonly id: VirtualID\n readonly reason: \"user\" | \"continuation\" | \"retry\" | \"direct\"\n readonly state: TaskState | undefined\n readonly branch: readonly BranchEntry[]\n /** ADP-055: sticky session-tier requests rank under a user pin, above the default. */\n readonly requestedTier?: TierName | null | undefined\n readonly failed?: FailedRequest | undefined\n readonly newId: () => string\n}\n\nexport function startTask(tier: TierName, newId: () => string): TaskState {\n return { version: 1, task: newId(), unit: newId(), tier, escalations: 0, restarts: 0, tried: [] }\n}\n\n/** Infra failures that another resource of the same tier may absorb. */\nexport function infraFailure(message: FailedMessage): FailureClassification | undefined {\n const classification = classifyFailure(failureEvidence(message))\n return classification.failoverEligible ? classification : undefined\n}\n\n/**\n * Which tier admits this request and how the task state moves. A user prompt\n * starts a new task (escalations and restarts never carry over); an owned\n * continuation starts a new unit of the same task; a native retry after an\n * infra failure re-admits within the tier, avoiding the models that failed\n * (ADP-009/013 — never a capability escalation); everything else stays\n * in-unit on the previous model.\n */\nexport function planRoute(input: PlanRouteInput): RoutePlan {\n const selected: TierName = input.id === \"auto\" ? \"standard\" : input.id\n const { state } = input\n if (input.reason === \"direct\")\n return { tier: \"quick\", sticky: false, exclude: [], state: input.state }\n if (input.reason === \"user\") {\n const base =\n input.id === \"auto\"\n ? (input.requestedTier ?? tierRequest(input.branch) ?? selected)\n : selected\n return {\n tier: base,\n sticky: false,\n exclude: [],\n state: startTask(base, input.newId),\n }\n }\n if (input.reason === \"retry\" && state !== undefined && input.failed !== undefined) {\n const failed = input.failed\n if (infraFailure(failed.message) !== undefined) {\n const tried = state.tried.some((ref) => sameRef(ref, failed.model))\n ? state.tried\n : [...state.tried, failed.model]\n return {\n tier: state.tier,\n sticky: false,\n exclude: tried,\n state: { ...state, tried, hops: (state.hops ?? 0) + 1 },\n }\n }\n }\n const recovery =\n input.reason === \"continuation\" ? pendingRecovery(input.branch, state) : undefined\n if (recovery === undefined)\n return { tier: state?.tier ?? selected, sticky: true, exclude: [], state }\n return {\n tier: recovery.tier,\n sticky: false,\n exclude: recovery.tried,\n state: {\n version: 1,\n task: recovery.task,\n unit: input.newId(),\n tier: recovery.tier,\n escalations: recovery.escalations,\n restarts: recovery.restarts,\n ...(recovery.wakes === undefined ? {} : { wakes: recovery.wakes }),\n ...(recovery.wakeToken === undefined ? {} : { wakeToken: recovery.wakeToken }),\n tried: recovery.tried,\n consumed: recovery.token,\n },\n }\n}\n\n/** Escalation requests recorded by `adaptive_escalate` during the current unit. */\nexport function unitEvidence(branch: readonly BranchEntry[], tool: string): EscalationEvidence[] {\n return toolResults(currentUnit(branch), tool).flatMap((details) => {\n const request = parseEscalationRequest(details)\n return request === undefined\n ? []\n : [{ kind: \"agent-request\", detail: escalationDetail(request) }]\n })\n}\n\nexport interface AfterRunInput {\n readonly id: VirtualID\n readonly escalateFromPinned: boolean\n /** The host resolves virtual selection and branch overrides before settling. */\n readonly settings: SettingsV1\n readonly branch: readonly BranchEntry[]\n /** Physical models Pi can dispatch right now. */\n readonly available: readonly ModelRef[]\n readonly tool: string\n readonly newId: () => string\n}\n\ninterface FailedRun {\n readonly state: TaskState\n readonly model: ModelRef\n readonly classification: FailureClassification\n}\n\n/**\n * The failure the settled run ended on, for an unpinned task in active mode.\n * Without a user pin the routing is Adaptive's; with one it never recovers on\n * the user's behalf.\n */\nfunction failedRun(input: AfterRunInput): FailedRun | undefined {\n if (input.settings.mode !== \"active\" || input.settings.pin !== null) return undefined\n const state = branchState(input.branch, input.id)\n const last = currentUnit(input.branch).findLast((entry) => entry.message?.role === \"assistant\")\n const message = last?.message\n // A run Adaptive's own route ended (Pi records it under the virtual model)\n // carries no provider evidence to recover from.\n if (state === undefined || message?.stopReason !== \"error\" || message.provider === \"adaptive\")\n return undefined\n return {\n state,\n model: { providerID: message.provider ?? \"\", id: message.model ?? \"\" },\n classification: classifyFailure(\n failureEvidence({ stopReason: message.stopReason, errorMessage: message.errorMessage }),\n ),\n }\n}\n\n/**\n * Decide, after a run settles, whether the task continues one tier up\n * (ADP-015..017). Pinned tiers require explicit user opt-in. Only a capability-class\n * failure of the run's last request, only to a configured, dispatchable\n * next-tier model, within the per-task budget. A successful run never\n * escalates, whatever the agent requested.\n */\nexport function escalationAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = input.id === \"auto\" || input.escalateFromPinned ? failedRun(input) : undefined\n if (run === undefined || !CAPABILITY_FAILURE_CATEGORIES.includes(run.classification.category))\n return undefined\n const { state } = run\n const next = nextTier(state.tier)\n const plan = planEscalation({\n currentModel: run.model,\n currentTier: state.tier,\n nextTierResources: (next === undefined ? [] : input.settings.tiers[next]).filter((ref) =>\n input.available.some((model) => sameRef(model, ref)),\n ),\n evidence: [\n ...unitEvidence(input.branch, input.tool),\n { kind: \"repeated-failure\", detail: run.classification.category },\n ],\n budget: { used: state.escalations, max: MAX_ESCALATIONS_PER_TASK },\n })\n if (plan.kind !== \"escalate\") return undefined\n return {\n task: state.task,\n token: input.newId(),\n tier: plan.tier,\n escalations: state.escalations + 1,\n restarts: state.restarts,\n ...(state.wakes === undefined ? {} : { wakes: state.wakes }),\n ...(state.wakeToken === undefined ? {} : { wakeToken: state.wakeToken }),\n tried: [],\n }\n}\n\n/**\n * Decide, after a run settles on an infra failure Pi did not (or could no\n * longer) retry — quota and billing errors are never retried natively —\n * whether the task continues on another model of the SAME tier (ADP-061).\n * Bounded per task; the failed model is avoided while the tier has another.\n */\nexport function restartAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = failedRun(input)\n if (!run?.classification.failoverEligible) return undefined\n const { state } = run\n if (state.restarts >= MAX_RESTARTS_PER_TASK) return undefined\n return {\n task: state.task,\n token: input.newId(),\n tier: state.tier,\n escalations: state.escalations,\n restarts: state.restarts + 1,\n ...(state.wakes === undefined ? {} : { wakes: state.wakes }),\n ...(state.wakeToken === undefined ? {} : { wakeToken: state.wakeToken }),\n // A failure without provider metadata names no model to avoid; an empty\n // reference would make the continuation unparseable.\n tried: [run.model].filter((ref) => ref.providerID !== \"\" && ref.id !== \"\"),\n }\n}\n\n/**\n * A spent immediate-restart budget may still wait for an actual tier reset.\n * A task that was resumed from a park (wakeToken) and failed again has\n * consumed one wake of the give-up budget; a task that never woke has not.\n */\nexport function parkingAfterRun(input: AfterRunInput): Recovery | undefined {\n const run = failedRun(input)\n if (!run?.classification.failoverEligible || run.state.restarts < MAX_RESTARTS_PER_TASK)\n return undefined\n const { wakes, wakeToken } = run.state\n return {\n task: run.state.task,\n token: input.newId(),\n tier: run.state.tier,\n escalations: run.state.escalations,\n restarts: run.state.restarts,\n wakes: (wakes ?? 0) + (wakeToken === undefined ? 0 : 1),\n ...(wakeToken === undefined ? {} : { wakeToken }),\n tried: [],\n }\n}\n\n/**\n * The task whose wake lineage a successful settle concludes. A provider success\n * is the only outcome that closes a park: the record it parked stands for work\n * that just finished, and keeping it would promise work that no longer exists.\n * A failed settle never serves — the recovery chain owns the lineage then.\n */\nexport function servedTask(input: AfterRunInput): string | undefined {\n const last = currentUnit(input.branch).findLast((entry) => entry.message?.role === \"assistant\")\n if (last?.message?.stopReason !== \"stop\") return undefined\n return branchState(input.branch, input.id)?.task\n}\n","import type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { isTierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { object } from \"./settings.js\"\nimport { VIRTUAL_IDS } from \"./router.js\"\nimport { TIER_TOOL, type BranchEntry } from \"./task.js\"\n\nexport const SESSION_ENTRY = \"adaptive.session\"\nexport interface SessionPatch {\n readonly version: 1\n readonly mode?: OperatingMode | null\n readonly tier?: TierName | null\n}\n\nfunction parse(raw: unknown): SessionPatch {\n if (!object(raw) || raw[\"version\"] !== 1) throw new Error(\"Adaptive session.version: expected 1\")\n const mode = raw[\"mode\"]\n const tier = raw[\"tier\"]\n if (\n mode !== undefined &&\n mode !== null &&\n mode !== \"off\" &&\n mode !== \"observe\" &&\n mode !== \"active\"\n )\n throw new Error(\"Adaptive session.mode: expected off, observe, active, or null\")\n if (tier !== undefined && tier !== null && (typeof tier !== \"string\" || !isTierName(tier)))\n throw new Error(\"Adaptive session.tier: expected quick, standard, advanced, or null\")\n return {\n version: 1,\n ...(mode === undefined ? {} : { mode }),\n ...(tier === undefined ? {} : { tier }),\n }\n}\n\nexport function sessionModeOverride(branch: readonly BranchEntry[]): OperatingMode | null {\n let mode: OperatingMode | null = null\n for (const entry of branch) {\n if (entry.type !== \"custom\" || entry.customType !== SESSION_ENTRY) continue\n const patch = parse(entry.data)\n if (patch.mode !== undefined) mode = patch.mode\n }\n return mode\n}\n\n/** A physical selection is always manual, even if the global mode says active. */\nexport function effectiveMode(\n model: { readonly provider: string; readonly id: string } | undefined,\n global: OperatingMode,\n branch: readonly BranchEntry[],\n): OperatingMode {\n if (model?.provider === \"adaptive\" && VIRTUAL_IDS.some((id) => id === model.id)) return \"active\"\n const override = sessionModeOverride(branch)\n return (override ?? global) === \"off\" ? \"off\" : \"observe\"\n}\n\n/** User dialogs and tool declarations share one chronological, branch-aware request. */\nexport function requestedTier(branch: readonly BranchEntry[]): TierName | null {\n let tier: TierName | null = null\n for (const entry of branch) {\n if (entry.type === \"custom\" && entry.customType === SESSION_ENTRY) {\n const patch = parse(entry.data)\n if (patch.tier !== undefined) tier = patch.tier\n }\n if (entry.message?.role === \"toolResult\" && entry.message.toolName === TIER_TOOL) {\n const details = entry.message.details\n if (object(details)) {\n const next = details[\"tier\"]\n if (next === null || (typeof next === \"string\" && isTierName(next))) tier = next\n }\n }\n }\n return tier\n}\n","/**\n * Tier-editor view models (ADP-033): resource labels with clear health tags,\n * model search over the host's available models, variant picking, and pure\n * reorder/remove helpers. All functions are total and deterministic.\n */\nimport type { ModelRef } from \"../routing/work-unit/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../status.js\"\nimport type { SettingsV1 } from \"../state/settings/index.js\"\nimport type { SelectOption } from \"./options.js\"\n\n/** `provider/model` with an `@variant` suffix when pinned to one. */\nexport function resourceLabel(ref: ModelRef): string {\n const base = `${ref.providerID}/${ref.id}`\n return ref.variant === undefined ? base : `${base}@${ref.variant}`\n}\n\n/**\n * Unavailable-resource display: empty string when healthy, otherwise a\n * bracketed, comma-separated tag list (health, breaker, window).\n */\nexport function healthTag(status: TierResourceStatus | undefined): string {\n if (status === undefined) return \"\"\n const parts: string[] = []\n if (status.health !== \"healthy\") parts.push(status.health)\n if (status.breaker === \"open\") parts.push(\"breaker-open\")\n else if (status.breaker === \"half_open\") parts.push(\"half-open\")\n if (status.windowed) parts.push(\"windowed\")\n return parts.length === 0 ? \"\" : ` [${parts.join(\", \")}]`\n}\n\nexport type TierEditorChoice = { kind: \"add\" } | { kind: \"resource\"; index: number; ref: ModelRef }\nexport function tierEditorOptions(\n settings: SettingsV1,\n tier: TierName,\n status: StatusSnapshot | undefined,\n modelSearchPlaceholder: string,\n): SelectOption<TierEditorChoice>[] {\n const options: SelectOption<TierEditorChoice>[] = [\n { title: \"Add model…\", value: { kind: \"add\" }, description: modelSearchPlaceholder },\n ]\n const tierStatus = status?.tiers[tier]\n settings.tiers[tier].forEach((ref, index) => {\n options.push({\n title: `${resourceLabel(ref)}${healthTag(tierStatus?.[index])}`,\n value: { kind: \"resource\", index, ref },\n description: \"Move or remove\",\n })\n })\n // No \"Back\" row: Escape steps back out of the dialog (undefined pick →\n // the editor loop re-shows the tier list).\n return options\n}\n\nexport function tierMenuOptions(status: StatusSnapshot): SelectOption<TierName>[] {\n return TIERS.map((tier) => {\n const resources = status.tiers[tier]\n // The lists are short: showing them inline answers \"what is configured\n // where\" without opening the editor.\n const description =\n resources.length === 0\n ? \"(empty — add models to enable routing)\"\n : resources.map((entry) => resourceLabel(entry.ref)).join(\" · \")\n return { title: `${tier} (${String(resources.length)})`, value: tier, description }\n })\n}\n\n/** Structural summary of one real OpenCode model (built by the entry). */\nexport interface ModelSummary {\n readonly providerID: string\n readonly modelID: string\n readonly name: string\n readonly variants: readonly string[]\n}\n\nexport function modelPickerOptions(models: readonly ModelSummary[]): SelectOption<ModelSummary>[] {\n return models.map((info) => ({\n title: `${info.providerID}/${info.modelID}`,\n description: info.name,\n value: info,\n }))\n}\n\nexport interface VariantChoice {\n variant: string | undefined\n}\n\nexport function variantOptions(variants: readonly string[]): SelectOption<VariantChoice>[] {\n const options: SelectOption<VariantChoice>[] = [\n { title: \"(model default)\", value: { variant: undefined } },\n ]\n for (const variant of variants) {\n options.push({ title: `@${variant}`, value: { variant } })\n }\n return options\n}\n\n/** Move the resource at `index` to the front (make it primary); out-of-bounds is a no-op. */\nexport function moveResourceToTop(resources: readonly ModelRef[], index: number): ModelRef[] {\n return [...resources.filter((_, i) => i === index), ...resources.filter((_, i) => i !== index)]\n}\n\n/** Swap the resource at `index` with its `delta` neighbour; bounds are no-ops. */\nexport function moveResource(\n resources: readonly ModelRef[],\n index: number,\n delta: -1 | 1,\n): ModelRef[] {\n const next = [...resources]\n const target = index + delta\n const item = next[index]\n const other = next[target]\n if (item === undefined || other === undefined) return next\n next[index] = other\n next[target] = item\n return next\n}\n\n/** Drop the resource at `index`; out-of-bounds keeps the list unchanged. */\nexport function removeResource(resources: readonly ModelRef[], index: number): ModelRef[] {\n return resources.filter((_, i) => i !== index)\n}\n","// covers: [\"ADP-057\", \"ADP-058\"]\nimport { sameModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport type { Decision, ParkReason } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { NoteVerbosity } from \"../preferences.js\"\n\nexport interface AdaptiveNote {\n readonly version: 1\n readonly text: string\n readonly receiptID?: number\n}\n\nfunction base(decision: Decision): Decision {\n return decision.kind === \"observe-only\" ? base(decision.would) : decision\n}\n\nexport function shouldWriteNote(\n verbosity: NoteVerbosity,\n decision: Decision,\n previous: Decision | undefined,\n): boolean {\n if (verbosity === \"quiet\") return false\n if (verbosity === \"all\" || previous === undefined) return true\n const current = base(decision)\n const last = base(previous)\n return (\n current.kind !== \"apply\" ||\n last.kind !== \"apply\" ||\n current.reason === \"fallback\" ||\n current.reason === \"probe\" ||\n decision.kind !== previous.kind ||\n !sameModelRef(current.model, last.model)\n )\n}\n\nconst PARKED: Record<ParkReason, string> = {\n \"all-blocked\": \"all models unavailable\",\n \"no-candidates\": \"no models configured\",\n \"no-compatible-resource\": \"no compatible model\",\n \"pin-blocked\": \"pinned model unavailable\",\n}\nconst APPLIED: Partial<Record<Extract<Decision, { kind: \"apply\" }>[\"reason\"], string>> = {\n fallback: \" · fallback\",\n probe: \" · testing recovery\",\n}\n\n/** Written when the user leaves an Adaptive model: routing stops until they come back. */\nexport function pausedNote(model: { readonly provider: string; readonly id: string }): string {\n return `Paused · you picked ${model.provider}/${model.id}`\n}\n\nexport function decisionNote(decision: Decision, tier: TierName, retry = false): string {\n switch (decision.kind) {\n case \"observe-only\":\n return `Observing · would ${decisionNote(decision.would, tier, retry)}`\n case \"apply\":\n return `${tier} → ${resourceLabel(decision.model)}${retry ? \" · retry\" : (APPLIED[decision.reason] ?? \"\")}`\n case \"park\":\n return `${tier} waiting · ${PARKED[decision.reason]}`\n case \"defer\":\n return `Not routing · ${decision.reason.replaceAll(\"-\", \" \")} · /adaptive why`\n case \"escalate\":\n return `Escalated to ${decision.tier} for this task → ${resourceLabel(decision.target)}`\n }\n}\n","/**\n * Pure circuit breaker state machine (ADP-019).\n *\n * All functions are total, synchronous, and clock-free: `now` is always an\n * injected parameter. The single-probe guarantee comes from the admission\n * protocol: `admitProbe` synchronously transitions an open (and due) breaker\n * to half-open, so the second concurrent caller observes `half_open` and is\n * blocked — there is never an await between the state check and the\n * transition. Callers must persist the returned record immediately.\n */\nimport type { FailureCategory } from \"../classifier/types.js\"\nimport { BREAKER_EXEMPT_CATEGORIES, type BreakerConfig, type BreakerRecord } from \"./types.js\"\n\nexport function initialBreaker(): BreakerRecord {\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\n/**\n * Backoff window for the `openCount`-th opening: doubling, capped at\n * `maxBackoffMs` so a persistently failing resource never waits longer than\n * the configured ceiling.\n */\nfunction backoffMs(openCount: number, config: BreakerConfig): number {\n return Math.min(config.baseOpenMs * 2 ** (openCount - 1), config.maxBackoffMs)\n}\n\nfunction openBreaker(\n record: BreakerRecord,\n openCount: number,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n return {\n state: \"open\",\n failures: record.failures,\n openCount,\n reopenAt: now + backoffMs(openCount, config),\n }\n}\n\nexport interface BreakerFailureResult {\n readonly record: BreakerRecord\n /** True exactly when this failure tripped the breaker from closed to open. */\n readonly opened: boolean\n}\n\n/**\n * Records a countable failure. Callers route only infrastructure failures\n * here (the resource-health transitions layer sends outage, overload, and\n * timeout); the breaker additionally exempts rate limiting and quota\n * exhaustion, which own their windowed resource states. Failures observed\n * while the breaker is not closed cannot happen through the admission\n * protocol (non-probe callers are blocked) and are ignored defensively.\n */\nexport function recordBreakerFailure(\n record: BreakerRecord,\n category: FailureCategory,\n now: number,\n config: BreakerConfig,\n): BreakerFailureResult {\n if (BREAKER_EXEMPT_CATEGORIES.includes(category) || record.state !== \"closed\") {\n return { record, opened: false }\n }\n const failures = record.failures + 1\n if (failures < config.failureThreshold) {\n return { record: { ...record, failures }, opened: false }\n }\n return {\n record: openBreaker({ ...record, failures }, record.openCount + 1, now, config),\n opened: true,\n }\n}\n\n/**\n * Observed success closes the breaker and resets the failure/backoff state.\n * Evidence beats inference: a success is proof the resource works, from any\n * prior breaker state.\n */\nexport function recordBreakerSuccess(): BreakerRecord {\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\nexport type ProbeAdmission =\n | { kind: \"closed\"; record: BreakerRecord }\n | { kind: \"waiting\"; record: BreakerRecord; retryAtMs: number }\n | { kind: \"in-flight\"; record: BreakerRecord }\n | { kind: \"admitted\"; record: BreakerRecord }\n\n/**\n * Attempts to admit the single half-open probe. Callers must persist the\n * returned record synchronously; the returned record carries no probeId — the\n * registry stamps its own ticket id on the persisted copy.\n */\n/**\n * Non-mutating wait computation for an open breaker, admission view: the\n * remaining backoff in ms, or `undefined` when the window has elapsed (or the\n * record is not open). Used to decide whether a probe may be admitted.\n */\nexport function breakerWait(record: BreakerRecord, now: number): number | undefined {\n if (record.state !== \"open\") return undefined\n const reopenAt = record.reopenAt\n if (reopenAt !== undefined && now < reopenAt) return reopenAt - now\n return undefined\n}\n\n/**\n * Non-mutating block computation for an open breaker, observer view: an open\n * breaker blocks regardless of elapsed backoff — recovery counts only once a\n * probe proved it — so an elapsed (or, unreachable through the state machine,\n * missing) stamp simply means zero remaining wait.\n */\nexport function breakerBlockWait(record: BreakerRecord, now: number): number | undefined {\n if (record.state !== \"open\") return undefined\n return Math.max(0, (record.reopenAt ?? 0) - now)\n}\n\nexport function admitProbe(record: BreakerRecord, now: number): ProbeAdmission {\n if (record.state === \"closed\") {\n return { kind: \"closed\", record }\n }\n if (record.state === \"half_open\") {\n return { kind: \"in-flight\", record }\n }\n const wait = breakerWait(record, now)\n if (wait !== undefined) {\n return { kind: \"waiting\", record, retryAtMs: wait }\n }\n return {\n kind: \"admitted\",\n record: { state: \"half_open\", failures: record.failures, openCount: record.openCount },\n }\n}\n\n/** Closes the breaker when a probe report confirms recovery. */\nexport function recordProbeSuccess(record: BreakerRecord): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n return { state: \"closed\", failures: 0, openCount: 0 }\n}\n\n/**\n * Expires a probe whose episode never reported an outcome. A lost probe is\n * no health evidence: the breaker re-arms the SAME backoff window (no\n * doubling) so a fresh probe can be admitted after it. Evaluated lazily by\n * the registry's assessment sweep — there are no timers.\n */\nexport function expireProbe(\n record: BreakerRecord,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n if (\n record.state !== \"half_open\" ||\n record.probeAt === undefined ||\n now - record.probeAt < config.probeTimeoutMs\n ) {\n return record\n }\n return openBreaker(record, record.openCount, now, config)\n}\n\n/**\n * Returns an admitted probe that was never dispatched (the admission picked\n * another resource, only observed, or failed to switch). No request ran, so\n * this is no evidence at all: the breaker goes back to open with the window\n * it was admitted under — still due — instead of restarting the backoff,\n * which would push a passed-over resource back on every admission.\n */\nexport function releaseProbe(record: BreakerRecord): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n return {\n state: \"open\",\n failures: record.failures,\n openCount: record.openCount,\n ...(record.probeAt !== undefined ? { reopenAt: record.probeAt } : {}),\n }\n}\n\n/**\n * Records a failed probe. A non-exempt failure reopens the breaker with a\n * doubled backoff. An exempt failure (the probe was rate limited or quota\n * blocked) re-arms the same backoff window without escalation: the resource\n * was rejected for demand reasons, not degraded health, so doubling would\n * overstate the failure.\n */\nexport function recordProbeFailure(\n record: BreakerRecord,\n category: FailureCategory,\n now: number,\n config: BreakerConfig,\n): BreakerRecord {\n if (record.state !== \"half_open\") {\n return record\n }\n if (BREAKER_EXEMPT_CATEGORIES.includes(category)) {\n return openBreaker(record, record.openCount, now, config)\n }\n return openBreaker(record, record.openCount + 1, now, config)\n}\n","/**\n * Capacity sensor boundary (ADP-020).\n *\n * Capacity is observed, never inferred: a sensor reports what its telemetry\n * actually shows (used/remaining ratios, retry-after, reset time) and grades\n * its own confidence. A `null` reading or assessment means \"no trustworthy\n * estimate\" — callers must treat that as unknown, never as healthy. Provider\n * specific sensing (passive Codex headers, optional quota endpoints) lives in\n * adapters; this module owns the boundary type, the deterministic merge of\n * concurrent readings for one resource, and the derivation of the\n * draining/exhausted signals consumed by the health layer (ADP-021).\n */\nimport type { ResourceKey } from \"../resource-health/types.js\"\n\nexport const CONFIDENCE_LEVELS = [\"low\", \"medium\", \"high\"] as const satisfies readonly string[]\n\n/** How much a sensor trusts its own numbers. `high` is required for draining. */\nexport type Confidence = (typeof CONFIDENCE_LEVELS)[number]\n\n/**\n * One observation of a resource's capacity. Ratios are fractions in [0, 1].\n * A reading may carry any subset of the measured fields (e.g. a header that\n * only reports a Retry-After); a reading with none of them carries no\n * information and is discarded. `observedAt` is when the underlying telemetry\n * was seen, not when the sensor was asked.\n */\nexport interface CapacityReading {\n readonly usedRatio?: number | undefined\n readonly remainingRatio?: number | undefined\n readonly retryAfterMs?: number | undefined\n /** Epoch milliseconds at which capacity is expected to reset. */\n readonly resetAt?: number | undefined\n readonly confidence: Confidence\n readonly observedAt: number\n /** Bounded, secret-free label of the data source (e.g. a header name). */\n readonly evidence?: string | undefined\n}\n\n/** A source of capacity observations for exactly one resource. */\nexport interface CapacitySensor {\n readonly id: string\n readonly resource: ResourceKey\n /**\n * Returns the latest reading, or `null` when the sensor has no trustworthy\n * estimate. Expected \"no data\" must be returned as `null`, never thrown;\n * the registry still guards against throws (fail-open: a failing sensor is\n * no estimate, not an error).\n */\n read(): Promise<CapacityReading | null>\n}\n\nexport interface CapacityConfig {\n /** Readings older than this are treated as absent (no estimate). */\n readonly maxAgeMs: number\n /**\n * Near-exhaustion bound at or below which high-confidence evidence marks\n * the resource `draining` (ADP-021). A fixed product constant, deliberately\n * not user-configurable — no threshold sliders.\n */\n readonly drainingRemainingThreshold: number\n}\n\nexport const DEFAULT_CAPACITY_CONFIG: CapacityConfig = {\n maxAgeMs: 60_000,\n drainingRemainingThreshold: 0.1,\n}\n\n/** Drain/exhaust derivation for a merged reading. */\nexport interface CapacitySignals {\n readonly exhausted: boolean\n readonly draining: boolean\n}\n\n/**\n * Scheduler-facing view for one resource. `none` is the explicit \"no\n * estimate\" answer — unknown capacity, not zero capacity.\n */\nexport type CapacityAssessment =\n | { readonly kind: \"none\" }\n | {\n readonly kind: \"estimate\"\n readonly reading: CapacityReading\n readonly signals: CapacitySignals\n }\n","/**\n * Deterministic capacity merge semantics (ADP-020).\n *\n * Several sensors may observe the same resource (e.g. passive headers and an\n * optional quota endpoint). The merge picks one coherent story instead of\n * synthesizing chimera numbers: readings are prioritized by confidence, then\n * by conservativeness (lower remaining ratio first), then by input order, and\n * each measured field is taken from the first reading in priority order that\n * supplies it. Trust is reduced, never amplified:\n *\n * - the merged confidence is the LOWEST confidence among all surviving fresh\n * readings, because any concurrent contradictory observation unsettles the\n * whole picture (a sensor that merely corroborates still shares its doubt);\n * - `observedAt` is the oldest surviving observation, so the merged reading\n * ages honestly;\n * - `evidence` follows the base (highest-priority) reading, which owns the\n * merged story.\n *\n * Exact bounds are facts, not estimates: `remainingRatio === 0` or\n * `usedRatio === 1` signals exhaustion at any confidence, while the softer\n * `draining` signal requires `high` confidence (ADP-021). Anything that is\n * not a well-formed measurement is rejected — untrusted data becomes \"no\n * estimate\", never a guess.\n */\nimport type { HealthEvent, ResourceKey } from \"../resource-health/types.js\"\nimport {\n CONFIDENCE_LEVELS,\n type CapacityConfig,\n type CapacityReading,\n type CapacitySignals,\n DEFAULT_CAPACITY_CONFIG,\n type Confidence,\n} from \"./types.js\"\n\n/** Evidence labels are bounded so unbounded header text cannot be persisted. */\nexport const MAX_EVIDENCE_LENGTH = 128\n\nexport function confidenceRank(confidence: Confidence): number {\n return CONFIDENCE_LEVELS.indexOf(confidence)\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value)\n}\n\nfunction isValidRatio(value: unknown): value is number {\n return isFiniteNumber(value) && value >= 0 && value <= 1\n}\n\n/**\n * Re-validates a reading field by field. A reading with an invalid ratio is\n * rejected entirely (its numbers cannot be partially trusted); invalid\n * `retryAfterMs`/`resetAt` values only drop their own field. A reading with\n * no measured field left is discarded as pure noise.\n */\nexport function normalizeReading(reading: unknown): CapacityReading | null {\n if (typeof reading !== \"object\" || reading === null) {\n return null\n }\n const candidate = reading as CapacityReading\n if (!CONFIDENCE_LEVELS.includes(candidate.confidence)) {\n return null\n }\n if (!isFiniteNumber(candidate.observedAt) || candidate.observedAt < 0) {\n return null\n }\n if (\n (candidate.usedRatio !== undefined && !isValidRatio(candidate.usedRatio)) ||\n (candidate.remainingRatio !== undefined && !isValidRatio(candidate.remainingRatio))\n ) {\n return null\n }\n const retryAfterMs =\n candidate.retryAfterMs !== undefined &&\n isFiniteNumber(candidate.retryAfterMs) &&\n Number.isInteger(candidate.retryAfterMs) &&\n candidate.retryAfterMs >= 0\n ? candidate.retryAfterMs\n : undefined\n const resetAt =\n isFiniteNumber(candidate.resetAt) && candidate.resetAt >= 0 ? candidate.resetAt : undefined\n const evidence =\n typeof candidate.evidence === \"string\"\n ? candidate.evidence.slice(0, MAX_EVIDENCE_LENGTH)\n : undefined\n if (\n candidate.usedRatio === undefined &&\n candidate.remainingRatio === undefined &&\n retryAfterMs === undefined &&\n resetAt === undefined\n ) {\n return null\n }\n return {\n ...(candidate.usedRatio !== undefined ? { usedRatio: candidate.usedRatio } : {}),\n ...(candidate.remainingRatio !== undefined ? { remainingRatio: candidate.remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence: candidate.confidence,\n observedAt: candidate.observedAt,\n ...(evidence !== undefined ? { evidence } : {}),\n }\n}\n\nfunction isFresh(reading: CapacityReading, now: number, config: CapacityConfig): boolean {\n return now - reading.observedAt <= config.maxAgeMs\n}\n\n/**\n * Strict priority between two readings: higher confidence wins; on equal\n * confidence the more conservative remaining ratio wins (a missing remaining\n * ratio cannot prove scarcity, so it counts as the least conservative value).\n * Equal readings keep their relative order.\n */\nfunction strictlyHigherPriority(candidate: CapacityReading, incumbent: CapacityReading): boolean {\n const byConfidence = confidenceRank(candidate.confidence) - confidenceRank(incumbent.confidence)\n if (byConfidence !== 0) {\n return byConfidence > 0\n }\n const candidateRemaining = candidate.remainingRatio ?? 1\n const incumbentRemaining = incumbent.remainingRatio ?? 1\n return candidateRemaining < incumbentRemaining\n}\n\n/**\n * Merges concurrent readings for one resource. Returns `null` when nothing\n * survives normalization and the freshness window — an explicit \"no estimate\".\n *\n * Selection runs over the input order with a strict priority comparator, so\n * ties keep the earliest reading and both comparator outcomes stay reachable.\n */\nexport function mergeReadings(\n readings: readonly CapacityReading[],\n now: number,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacityReading | null {\n const survivors = readings\n .map(normalizeReading)\n .filter((reading): reading is CapacityReading => reading !== null)\n .filter((reading) => isFresh(reading, now, config))\n if (survivors.length === 0) {\n return null\n }\n const base = survivors.reduce((best, reading) =>\n strictlyHigherPriority(reading, best) ? reading : best,\n )\n const bestField = <T>(pick: (reading: CapacityReading) => T | undefined): T | undefined => {\n let best: CapacityReading | undefined\n let bestValue: T | undefined\n for (const reading of survivors) {\n const value = pick(reading)\n if (value === undefined) {\n continue\n }\n if (best === undefined || strictlyHigherPriority(reading, best)) {\n best = reading\n bestValue = value\n }\n }\n return bestValue\n }\n const usedRatio = bestField((reading) => reading.usedRatio)\n const remainingRatio = bestField((reading) => reading.remainingRatio)\n const retryAfterMs = bestField((reading) => reading.retryAfterMs)\n const resetAt = bestField((reading) => reading.resetAt)\n const confidence = survivors.reduce<Confidence>(\n (lowest, reading) =>\n confidenceRank(reading.confidence) < confidenceRank(lowest) ? reading.confidence : lowest,\n base.confidence,\n )\n const observedAt = Math.min(...survivors.map((reading) => reading.observedAt))\n return {\n ...(usedRatio !== undefined ? { usedRatio } : {}),\n ...(remainingRatio !== undefined ? { remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n ...(base.evidence !== undefined ? { evidence: base.evidence } : {}),\n }\n}\n\n/**\n * Drain/exhaust derivation. Exhaustion is signaled by exact bounds at any\n * confidence (a header stating zero remaining is a fact, not a guess);\n * draining additionally requires `high` confidence because it withdraws new\n * work before hard evidence exists (ADP-021).\n */\nexport function capacitySignals(\n reading: CapacityReading,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacitySignals {\n const exhausted = reading.remainingRatio === 0 || reading.usedRatio === 1\n const draining =\n !exhausted &&\n reading.confidence === \"high\" &&\n ((reading.remainingRatio !== undefined &&\n reading.remainingRatio <= config.drainingRemainingThreshold) ||\n (reading.usedRatio !== undefined &&\n reading.usedRatio >= 1 - config.drainingRemainingThreshold))\n return { exhausted, draining }\n}\n\n/**\n * Pure bridge to the health layer: converts a merged reading into the\n * capacity event consumed by resource-health transitions (ADP-021). The\n * scheduler wiring decides when to observe it; this function only shapes it.\n */\nexport function capacityHealthEvent(key: ResourceKey, reading: CapacityReading): HealthEvent {\n return {\n kind: \"capacity\",\n key,\n exhausted: capacitySignals(reading).exhausted,\n ...(reading.retryAfterMs !== undefined ? { retryAfterMs: reading.retryAfterMs } : {}),\n }\n}\n","/**\n * Maps a classified failure onto the resource scope it actually blocks.\n */\nimport type { FailureClassification } from \"../classifier/types.js\"\nimport type { HealthEvent, ResourceKey } from \"./types.js\"\n\n/** Quota survives variantless host resolution; only shared-limit evidence blocks siblings. */\nexport function failureKey(key: ResourceKey, classification: FailureClassification): ResourceKey {\n if (classification.quotaScope === \"provider\") {\n // Host model refs expose the configured provider, not a credential/account id.\n return { providerID: key.providerID }\n }\n if (classification.category === \"quota_exhausted\" && key.variantID !== undefined) {\n return { providerID: key.providerID, modelID: key.modelID }\n }\n return key\n}\n\n/** Health failure event from a classification (bounded structured evidence). */\nexport function failureEvent(key: ResourceKey, classification: FailureClassification): HealthEvent {\n return {\n kind: \"failure\",\n key: failureKey(key, classification),\n category: classification.category,\n definitive: classification.definitive,\n ...(classification.retry.retryAfterMs !== undefined\n ? { retryAfterMs: classification.retry.retryAfterMs }\n : {}),\n }\n}\n","/**\n * Pure resource health transitions (ADP-007, ADP-012, ADP-019, ADP-021).\n *\n * `applyHealthEvent` is the single authority for how evidence changes a\n * resource record: total, synchronous, and clock-free (`now` is injected).\n *\n * Policy notes:\n * - Rate limiting and quota exhaustion set their own windowed states, always\n * bounded (a default window when the evidence names no reset);\n * a windowed state is never downgraded by weaker evidence (a 429 while\n * quota-exhausted does not erase the quota signal).\n * - Outage, overload, and timeout count toward the circuit breaker and mark\n * the resource degraded. They never hard-quarantine on their own: a single\n * definitive outage signal can be a blip, so the breaker owns transient\n * failure quarantine with backoff windows and probe recovery.\n * - Definitive configuration failures (auth, invalid model) hard-quarantine\n * the resource: the evidence proves the resource cannot work. Non-definitive\n * evidence of the same categories (the textual last resort, ADP-008) is\n * transient and breaker-owned instead — one fuzzy substring in an error\n * body must never permanently blacklist a resource with no recovery path\n * (ADP-012).\n * - The `definitive` flag otherwise guides scheduling deference, not health:\n * both definitive and non-definitive infra failures leave the resource\n * degraded.\n * - Ambiguous or request-level failures (context overflow, content policy,\n * user cancellation, unknown) never change health: they say nothing about\n * the resource.\n * - Draining is a policy request (ADP-021), not degraded health: it applies\n * on top of healthy/degraded and never masks a harder state.\n */\nimport {\n recordBreakerFailure,\n recordBreakerSuccess,\n initialBreaker,\n} from \"../circuit-breaker/breaker.js\"\nimport type { BreakerRecord } from \"../circuit-breaker/types.js\"\nimport { resourceScope } from \"./key.js\"\nimport type { HealthEvent, ResourceHealthConfig, ResourceKey, ResourceRecord } from \"./types.js\"\n\nexport function initialRecord(key: ResourceKey, now: number): ResourceRecord {\n return { key, health: \"healthy\", breaker: initialBreaker(), updatedAt: now }\n}\n\n/**\n * Elapses time-bounded windows: once a window's `until` passes, the windowed\n * state (rate limited, quota exhausted) lifts back to healthy. Records\n * without a window, or with one still in the future, pass through unchanged.\n */\nexport function sweepRecord(record: ResourceRecord, now: number): ResourceRecord {\n const window = record.window\n if (window === undefined || now < window.until) {\n return record\n }\n return { key: record.key, health: \"healthy\", breaker: record.breaker, updatedAt: now }\n}\n\nfunction touched(record: ResourceRecord, now: number): ResourceRecord {\n return { ...record, updatedAt: now }\n}\n\n/**\n * Defensive re-validation of a parsed retry delay: the classifier already\n * rejects malformed values, but the health layer never trusts a negative or\n * fractional delay to compute a window.\n */\nfunction validRetryAfterMs(value: number | undefined): number | undefined {\n return value !== undefined && Number.isInteger(value) && value >= 0 ? value : undefined\n}\n\nfunction quotaExhausted(\n record: ResourceRecord,\n retryAfterMs: number | undefined,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n const until = now + (validRetryAfterMs(retryAfterMs) ?? config.defaultQuotaWindowMs)\n return { ...record, health: \"quota_exhausted\", window: { kind: \"quota\", until }, updatedAt: now }\n}\n\nfunction failureEvent(\n record: ResourceRecord,\n event: Extract<HealthEvent, { kind: \"failure\" }>,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n switch (event.category) {\n case \"rate_limited\": {\n if (record.health === \"quota_exhausted\" || record.health === \"unavailable\") {\n return touched(record, now)\n }\n const retryAfterMs = validRetryAfterMs(event.retryAfterMs)\n const until = now + (retryAfterMs ?? config.defaultRateLimitWindowMs)\n return {\n ...record,\n health: \"rate_limited\",\n window: { kind: \"rate-limit\", until },\n updatedAt: now,\n }\n }\n case \"quota_exhausted\": {\n if (record.health === \"unavailable\") {\n return touched(record, now)\n }\n return quotaExhausted(record, event.retryAfterMs, now, config)\n }\n case \"outage\":\n case \"overload\":\n case \"timeout\": {\n const breaker = recordBreakerFailure(record.breaker, event.category, now, config.breaker)\n const health =\n record.health === \"healthy\" || record.health === \"draining\" ? \"degraded\" : record.health\n return { ...record, health, breaker: breaker.record, updatedAt: now }\n }\n case \"auth_failure\":\n case \"invalid_model\": {\n // An invalid model says nothing about the provider or account; only\n // model-scoped and variant-scoped keys may be quarantined by it.\n if (event.category === \"invalid_model\") {\n const scope = resourceScope(record.key)\n if (scope !== \"model\" && scope !== \"variant\") {\n return touched(record, now)\n }\n }\n if (!event.definitive) {\n // Non-definitive evidence (bounded-textual last resort) is not proof\n // the resource cannot work: quarantine through the breaker's bounded\n // failure counting instead of a windowless, unrecoverable state.\n const breaker = recordBreakerFailure(record.breaker, event.category, now, config.breaker)\n const health =\n record.health === \"healthy\" || record.health === \"draining\" ? \"degraded\" : record.health\n return { ...record, health, breaker: breaker.record, updatedAt: now }\n }\n return { ...record, health: \"unavailable\", updatedAt: now }\n }\n default:\n // context_overflow, content_policy, user_cancelled, unknown:\n // request-level evidence, not resource health.\n return touched(record, now)\n }\n}\n\nexport function applyHealthEvent(\n record: ResourceRecord,\n event: HealthEvent,\n now: number,\n config: ResourceHealthConfig,\n): ResourceRecord {\n switch (event.kind) {\n case \"failure\":\n return failureEvent(record, event, now, config)\n case \"success\": {\n const breaker: BreakerRecord = recordBreakerSuccess()\n const health =\n record.health === \"draining\" || record.health === \"quota_exhausted\"\n ? record.health\n : \"healthy\"\n return {\n ...record,\n health,\n breaker,\n window: health === record.health ? record.window : undefined,\n updatedAt: now,\n }\n }\n case \"drain\": {\n const health =\n record.health === \"healthy\" || record.health === \"degraded\" ? \"draining\" : record.health\n return { ...record, health, updatedAt: now }\n }\n case \"capacity\": {\n if (event.exhausted) {\n if (record.health === \"unavailable\") {\n return touched(record, now)\n }\n return quotaExhausted(record, event.retryAfterMs, now, config)\n }\n const health = record.health === \"quota_exhausted\" ? \"healthy\" : record.health\n return {\n ...record,\n health,\n window: health === record.health ? record.window : undefined,\n updatedAt: now,\n }\n }\n case \"reset\":\n return { key: record.key, health: \"healthy\", breaker: initialBreaker(), updatedAt: now }\n }\n}\n","/**\n * Resource health registry (ADP-007, ADP-019, ADP-021).\n *\n * Stateful façade over the pure transition layer: one record per resource\n * key, an injected clock, and assessment that composes the record's chain of\n * ancestor scopes. Time only advances through the injected clock — there are\n * no timers; windows and breaker backoffs are evaluated (swept) lazily on\n * every observation, assessment, and snapshot.\n *\n * The single-probe guarantee (ADP-019) lives here: `assess` synchronously\n * flips a due open breaker to half-open and issues the probe ticket, so\n * concurrent assessors can never observe two admissions.\n */\nimport {\n admitProbe,\n breakerBlockWait,\n expireProbe,\n recordProbeFailure,\n recordProbeSuccess,\n releaseProbe,\n} from \"../circuit-breaker/breaker.js\"\nimport type { BreakerRecord } from \"../circuit-breaker/types.js\"\nimport { resourceChain, resourceKeyID } from \"./key.js\"\nimport { applyHealthEvent, initialRecord, sweepRecord } from \"./transitions.js\"\nimport {\n DEFAULT_HEALTH_CONFIG,\n type Assessment,\n type Clock,\n type HealthEvent,\n type ProbeOutcome,\n type ProbeTicket,\n type ResourceHealthConfig,\n type ResourceKey,\n type ResourceRecord,\n} from \"./types.js\"\n\n/**\n * Severity of the three hard resource states. Used only to choose which\n * blocker a report names when several scopes in a chain are blocked at once;\n * every candidate still blocks regardless of which wins the report.\n */\nconst HARD_BLOCK_SEVERITY = {\n unavailable: 3,\n \"quota-exhausted\": 2,\n \"rate-limited\": 1,\n} as const\n\ntype HardBlockReason = keyof typeof HARD_BLOCK_SEVERITY\n\ninterface HardBlock {\n readonly reason: HardBlockReason\n readonly key: ResourceKey\n readonly retryAtMs: number | undefined\n readonly severity: number\n}\n\nfunction blocked(\n reason: HardBlockReason,\n key: ResourceKey,\n retryAtMs: number | undefined,\n): Assessment\nfunction blocked(reason: \"breaker-open\", key: ResourceKey, retryAtMs: number): Assessment\nfunction blocked(\n reason: \"probe-in-flight\" | \"draining\",\n key: ResourceKey,\n retryAtMs: undefined,\n): Assessment\nfunction blocked(\n reason: HardBlockReason | \"breaker-open\" | \"probe-in-flight\" | \"draining\",\n key: ResourceKey,\n retryAtMs: number | undefined,\n): Assessment {\n if (retryAtMs === undefined) {\n return { kind: \"blocked\", reason, key }\n }\n return { kind: \"blocked\", reason, key, retryAtMs }\n}\n\nfunction hardBlocker(record: ResourceRecord, now: number): HardBlock | undefined {\n const retryAtMs = record.window === undefined ? undefined : record.window.until - now\n switch (record.health) {\n case \"unavailable\":\n return {\n reason: \"unavailable\",\n key: record.key,\n retryAtMs: undefined,\n severity: HARD_BLOCK_SEVERITY.unavailable,\n }\n case \"quota_exhausted\":\n return {\n reason: \"quota-exhausted\",\n key: record.key,\n retryAtMs,\n severity: HARD_BLOCK_SEVERITY[\"quota-exhausted\"],\n }\n case \"rate_limited\":\n return {\n reason: \"rate-limited\",\n key: record.key,\n retryAtMs,\n severity: HARD_BLOCK_SEVERITY[\"rate-limited\"],\n }\n default:\n return undefined\n }\n}\n\n/** Most severe hard block across a chain; narrowest scope wins ties. */\nfunction hardest(\n records: readonly (ResourceRecord | undefined)[],\n now: number,\n): HardBlock | undefined {\n let hard: HardBlock | undefined\n for (const record of records) {\n if (record === undefined) {\n continue\n }\n const candidate = hardBlocker(record, now)\n if (candidate === undefined) {\n continue\n }\n if (hard === undefined || candidate.severity >= hard.severity) {\n hard = candidate\n }\n }\n return hard\n}\n\nexport class ResourceHealthRegistry {\n readonly #records = new Map<string, ResourceRecord>()\n readonly #clock: Clock\n readonly #config: ResourceHealthConfig\n readonly #newProbeId: () => string\n\n /**\n * `newProbeId` must be unique across every instance that shares records\n * (see `restore`); a per-instance counter suffices for a single owner.\n */\n constructor(\n clock: Clock,\n config: ResourceHealthConfig = DEFAULT_HEALTH_CONFIG,\n newProbeId?: () => string,\n ) {\n this.#clock = clock\n this.#config = config\n let counter = 0\n this.#newProbeId =\n newProbeId ??\n (() => {\n counter += 1\n return String(counter)\n })\n }\n\n /**\n * Replaces the registry's view with records another live instance shares\n * (one process per host session, all reading one locked file). Unlike\n * `hydrate`, an in-flight probe is kept: its owner is alive and will report\n * the outcome, and a lost owner is still bounded by the probe timeout.\n */\n restore(records: readonly ResourceRecord[]): void {\n const now = this.#clock()\n this.#records.clear()\n for (const record of records) {\n this.#records.set(resourceKeyID(record.key), sweepRecord(record, now))\n }\n }\n\n /**\n * Seeds the registry from persisted records (restart / cross-instance\n * reload). Records are swept against the current clock and inserted\n * without persisting — hydration must not write back what it just read.\n * A hydrated half_open record cannot keep its probe (the ticket lived in\n * the previous instance's memory), so it re-opens due immediately — its\n * backoff window had already elapsed when it went half-open, and the next\n * assessment admits exactly one probe as usual.\n */\n hydrate(records: readonly ResourceRecord[]): void {\n const now = this.#clock()\n for (const record of records) {\n const swept = sweepRecord(record, now)\n const breaker =\n swept.breaker.state === \"half_open\"\n ? {\n state: \"open\" as const,\n failures: swept.breaker.failures,\n openCount: swept.breaker.openCount,\n reopenAt: now,\n }\n : swept.breaker\n this.#records.set(resourceKeyID(swept.key), { ...swept, breaker, updatedAt: now })\n }\n }\n\n observe(event: HealthEvent): ResourceRecord {\n const now = this.#clock()\n const id = resourceKeyID(event.key)\n const existing = this.#records.get(id)\n const swept =\n existing === undefined ? initialRecord(event.key, now) : sweepRecord(existing, now)\n const updated = applyHealthEvent(swept, event, now, this.#config)\n this.#records.set(id, updated)\n return updated\n }\n\n #sweptRecord(key: ResourceKey, now: number): ResourceRecord | undefined {\n const id = resourceKeyID(key)\n const record = this.#records.get(id)\n if (record === undefined) {\n return undefined\n }\n const swept = sweepRecord(record, now)\n if (swept !== record) {\n this.#records.set(id, swept)\n }\n return swept\n }\n\n /**\n * Assesses whether the resource may take new work right now, composing the\n * full ancestor chain. Precedence: the most severe hard resource state\n * wins (narrowest scope on ties), then the breaker scan (widest scope\n * first — a due wide breaker is probed before a narrow one), then draining,\n * then available.\n */\n assess(key: ResourceKey): Assessment {\n const now = this.#clock()\n const records = resourceChain(key).map((chainKey) => this.#sweptRecord(chainKey, now))\n\n const hard = hardest(records, now)\n if (hard !== undefined) {\n return blocked(hard.reason, hard.key, hard.retryAtMs)\n }\n\n // Two passes over the chain: the request would reach every scope, so a\n // backing-off or probing breaker at ANY scope blocks it. Only when none\n // blocks may the widest due breaker take the single probe — otherwise a\n // due provider breaker would send the probe to a model whose own breaker\n // is still backing off, or double up on that model's in-flight probe.\n const due: { record: ResourceRecord; breaker: BreakerRecord }[] = []\n for (const record of records) {\n if (record === undefined) {\n continue\n }\n // A probe whose outcome report never arrived must not wedge the\n // resource in half_open: expire it (same backoff window, no doubling)\n // before attempting admission.\n const expired = expireProbe(record.breaker, now, this.#config.breaker)\n const current =\n expired === record.breaker ? record : { ...record, breaker: expired, updatedAt: now }\n if (current !== record) {\n this.#records.set(resourceKeyID(record.key), current)\n }\n const admission = admitProbe(current.breaker, now)\n if (admission.kind === \"waiting\") {\n return blocked(\"breaker-open\", record.key, admission.retryAtMs)\n }\n if (admission.kind === \"in-flight\") {\n return blocked(\"probe-in-flight\", record.key, undefined)\n }\n if (admission.kind === \"admitted\") {\n due.push({ record, breaker: admission.record })\n }\n }\n const first = due[0]\n if (first !== undefined) {\n const probeId = this.#newProbeId()\n this.#records.set(resourceKeyID(first.record.key), {\n ...first.record,\n breaker: { ...first.breaker, probeId, probeAt: now },\n updatedAt: now,\n })\n return { kind: \"probe\", ticket: { id: probeId, key: first.record.key } }\n }\n\n // Draining is the softest blocker; report the narrowest draining scope.\n let draining: ResourceRecord | undefined\n for (const record of records) {\n if (record?.health === \"draining\") {\n draining = record\n }\n }\n if (draining !== undefined) {\n return blocked(\"draining\", draining.key, undefined)\n }\n\n return { kind: \"available\" }\n }\n\n /**\n * Non-mutating assessment for decisions that must not admit a probe\n * (escalation-target gating): identical hard-state and draining walk, but\n * an open or half-open breaker blocks without being flipped or ticketed.\n */\n evaluate(key: ResourceKey): Assessment {\n const now = this.#clock()\n const records = resourceChain(key).map((chainKey) => this.#sweptRecord(chainKey, now))\n const hard = hardest(records, now)\n if (hard !== undefined) {\n return blocked(hard.reason, hard.key, hard.retryAtMs)\n }\n for (const record of records) {\n if (record === undefined) continue\n // Observer view (non-mutating): an open breaker blocks even when its\n // backoff elapsed — assess is what flips it to half_open and issues\n // the probe ticket.\n const wait = breakerBlockWait(record.breaker, now)\n if (wait !== undefined) {\n return blocked(\"breaker-open\", record.key, wait)\n }\n if (record.breaker.state === \"half_open\") {\n return blocked(\"probe-in-flight\", record.key, undefined)\n }\n }\n let draining: ResourceRecord | undefined\n for (const record of records) {\n if (record?.health === \"draining\") {\n draining = record\n }\n }\n if (draining !== undefined) {\n return blocked(\"draining\", draining.key, undefined)\n }\n return { kind: \"available\" }\n }\n\n /**\n * Reports the outcome of an admitted probe. Only the ticket issued for the\n * current half-open record is honored; stale tickets (probe already\n * resolved, record reset, or unknown key) are rejected.\n */\n reportProbe(ticket: ProbeTicket, outcome: ProbeOutcome): boolean {\n const now = this.#clock()\n const id = resourceKeyID(ticket.key)\n const record = this.#records.get(id)\n if (record === undefined) {\n return false\n }\n const breaker = record.breaker\n if (breaker.state !== \"half_open\" || breaker.probeId !== ticket.id) {\n return false\n }\n const next = outcome.success\n ? recordProbeSuccess(breaker)\n : recordProbeFailure(breaker, outcome.category, now, this.#config.breaker)\n this.#records.set(id, { ...record, breaker: next, updatedAt: now })\n return true\n }\n\n /**\n * Returns an admitted-but-never-dispatched probe ticket: the breaker\n * reopens still due, so the next admission can issue a fresh probe. Same\n * stale-ticket rule as `reportProbe`.\n */\n releaseProbe(ticket: ProbeTicket): boolean {\n const id = resourceKeyID(ticket.key)\n const record = this.#records.get(id)\n if (record?.breaker.state !== \"half_open\" || record.breaker.probeId !== ticket.id) {\n return false\n }\n this.#records.set(id, {\n ...record,\n breaker: releaseProbe(record.breaker),\n updatedAt: this.#clock(),\n })\n return true\n }\n\n /** Current (swept) record for one key, if the registry tracks it. */\n recordFor(key: ResourceKey): ResourceRecord | undefined {\n return this.#sweptRecord(key, this.#clock())\n }\n\n /** All tracked records, swept against the clock. */\n snapshot(): ResourceRecord[] {\n const now = this.#clock()\n return [...this.#records.values()].map((record) => sweepRecord(record, now))\n }\n}\n","/**\n * Read-side parsing for persisted health records. Every parser is total: it\n * accepts `unknown` and returns typed records, dropping anything invalid — a\n * corrupted health file can never take the plugin down (ADP-031). State and\n * breaker vocabularies are membership-checked; timestamps must be finite\n * numbers. An older plugin reading newer records may drop unknown-vocabulary\n * entries — health records are bounded mirrors of an in-memory registry, and\n * the payload version guards the schema itself.\n */\nimport { BREAKER_STATES } from \"../../health/circuit-breaker/types.js\"\nimport type { BreakerRecord } from \"../../health/circuit-breaker/types.js\"\nimport { HEALTH_STATES } from \"../../health/resource-health/types.js\"\nimport type {\n ResourceKey,\n ResourceRecord,\n ResourceWindow,\n} from \"../../health/resource-health/types.js\"\nimport { HEALTH_VERSION } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\nfunction isNonNegativeInt(raw: unknown): raw is number {\n return isFiniteNumber(raw) && Number.isInteger(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\n/**\n * A non-empty bounded identifier string (provider/model/variant/account ids).\n * Over-long values are rejected, not truncated: the writer stores keys as-is,\n * so a truncated key would name a different resource.\n */\nfunction parseIdentifier(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || raw === \"\" || raw.length > 128) return undefined\n return raw\n}\n\nfunction parseKey(raw: unknown): ResourceKey | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = parseIdentifier(raw[\"providerID\"])\n if (providerID === undefined) return undefined\n const accountID = parseIdentifier(raw[\"accountID\"])\n const modelID = parseIdentifier(raw[\"modelID\"])\n const variantID = parseIdentifier(raw[\"variantID\"])\n // A present-but-unusable scope field would silently widen the key.\n if (raw[\"accountID\"] !== undefined && accountID === undefined) return undefined\n if (raw[\"modelID\"] !== undefined && modelID === undefined) return undefined\n if (raw[\"variantID\"] !== undefined && variantID === undefined) return undefined\n // Scope fields must form a valid prefix: a variant without a model, or a\n // model without its variant's provider context, is not a real resource.\n if (variantID !== undefined && modelID === undefined) return undefined\n return {\n providerID,\n ...(accountID !== undefined ? { accountID } : {}),\n ...(modelID !== undefined ? { modelID } : {}),\n ...(variantID !== undefined ? { variantID } : {}),\n }\n}\n\nfunction parseBreaker(raw: unknown): BreakerRecord | undefined {\n if (!isRecord(raw)) return undefined\n const state = parseVocab(raw[\"state\"], BREAKER_STATES)\n const failures = raw[\"failures\"]\n const openCount = raw[\"openCount\"]\n if (state === undefined) return undefined\n if (!(isNonNegativeInt(failures) && isNonNegativeInt(openCount))) return undefined\n const reopenAt = raw[\"reopenAt\"]\n const probeId = parseIdentifier(raw[\"probeId\"])\n const probeAt = raw[\"probeAt\"]\n return {\n state,\n failures,\n openCount,\n ...(isFiniteNumber(reopenAt) ? { reopenAt } : {}),\n ...(probeId !== undefined ? { probeId } : {}),\n ...(isFiniteNumber(probeAt) ? { probeAt } : {}),\n }\n}\n\nfunction parseWindow(raw: unknown): ResourceWindow | undefined {\n if (!isRecord(raw)) return undefined\n const kind = parseVocab(raw[\"kind\"], [\"rate-limit\", \"quota\"] as const)\n const until = raw[\"until\"]\n if (kind === undefined || !isFiniteNumber(until)) return undefined\n return { kind, until }\n}\n\nfunction parseRecord(raw: unknown): ResourceRecord | undefined {\n if (!isRecord(raw)) return undefined\n const key = parseKey(raw[\"key\"])\n const health = parseVocab(raw[\"health\"], HEALTH_STATES)\n const breaker = parseBreaker(raw[\"breaker\"])\n const updatedAt = raw[\"updatedAt\"]\n if (key === undefined || health === undefined || breaker === undefined) return undefined\n if (!isFiniteNumber(updatedAt)) return undefined\n const window = parseWindow(raw[\"window\"])\n // Windowed states lift only when their window elapses: without a valid\n // window the record would block the resource permanently, so it is dropped\n // (the resource reads as healthy until fresh evidence arrives).\n if ((health === \"rate_limited\" || health === \"quota_exhausted\") && window === undefined) {\n return undefined\n }\n return {\n key,\n health,\n breaker,\n ...(window !== undefined ? { window } : {}),\n updatedAt,\n }\n}\n\nexport function parseHealthPayload(raw: unknown): ResourceRecord[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== HEALTH_VERSION) return []\n const list = raw[\"records\"]\n if (!Array.isArray(list)) return []\n const parsed: ResourceRecord[] = []\n for (const entry of list.slice(0, 512)) {\n const record = parseRecord(entry)\n if (record !== undefined) parsed.push(record)\n }\n return parsed\n}\n","/**\n * Bounded health-record store: a persistence mirror of the in-memory\n * resource-health registry. The store keeps the newest-updated records\n * (bounded, least-recently-updated evicted) and persists on every replace.\n * As everywhere else in `state/`, memory is only advanced after a successful\n * write, so memory and disk never diverge; write failures propagate to the\n * caller — the wiring layer's fail-open wrapper decides how to degrade\n * (ADP-031).\n */\nimport { parseHealthPayload } from \"./parse.js\"\nimport { MAX_HEALTH_RECORDS, HEALTH_VERSION } from \"./types.js\"\nimport type { HealthPayload, HealthStorage } from \"./types.js\"\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\n/**\n * The bounded record set worth persisting: the most recently updated\n * records — stale scopes matter less than the resources that are actually\n * failing right now.\n */\nexport function retainedHealthRecords(records: readonly ResourceRecord[]): ResourceRecord[] {\n return records.length > MAX_HEALTH_RECORDS\n ? [...records]\n .sort((left, right) => right.updatedAt - left.updatedAt)\n .slice(0, MAX_HEALTH_RECORDS)\n : [...records]\n}\n\nexport class HealthRecordStore {\n #records: ResourceRecord[] = []\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: HealthStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseHealthPayload(raw)\n }\n\n /** All retained records. */\n snapshot(): readonly ResourceRecord[] {\n return this.#records\n }\n\n /** Replace the whole record set with a fresh registry snapshot (bounded). */\n replace(records: readonly ResourceRecord[]): Promise<void> {\n return this.#serialize(() => this.#replace(records))\n }\n\n async #replace(records: readonly ResourceRecord[]): Promise<void> {\n const next = retainedHealthRecords(records)\n // Persist BEFORE committing memory: a write failure must leave memory\n // and disk consistent (the caller decides how to fail open).\n const payload: HealthPayload = {\n version: HEALTH_VERSION,\n records: next,\n }\n await this.storage.write(payload)\n this.#records = next\n }\n\n // Reloads and writes share one queue; otherwise a slow persistence call\n // can restore older state after a newer call has already committed.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n","// covers: [\"ADP-009\", \"ADP-010\", \"ADP-011\", \"ADP-059\"]\n/**\n * Resource health shared by every Pi process on this machine. Each\n * transaction restores the registry from the health file under its lock,\n * lets the caller assess or observe, and writes the swept snapshot back — so\n * one process's 429 steers the next admission in another, and a half-open\n * breaker admits one probe across all of them (ADP-059). No Pi imports.\n */\nimport { classifyFailure } from \"@coool/adaptive-core/health/classifier/classify\"\nimport type { FailureClassification } from \"@coool/adaptive-core/health/classifier/types\"\nimport {\n DEFAULT_HEALTH_CONFIG,\n failureEvent,\n ResourceHealthRegistry,\n} from \"@coool/adaptive-core/health/index\"\nimport type {\n Assessment,\n ProbeTicket,\n ResourceKey,\n} from \"@coool/adaptive-core/health/resource-health/types\"\nimport { schedulerHealthKey } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { retainedHealthRecords } from \"@coool/adaptive-core/state/health/store\"\nimport { HEALTH_VERSION } from \"@coool/adaptive-core/state/health/types\"\nimport { failureEvidence, type FailedMessage } from \"./evidence.js\"\nimport type { JsonFile } from \"./store.js\"\n\nexport interface SharedHealth {\n readonly file: JsonFile\n readonly clock: () => number\n /** Probe ids must be unique across every process sharing the file. */\n readonly newId: () => string\n}\n\n/** Run `change` against the shared registry and persist what it leaves behind. */\nexport function withHealth<R>(\n shared: SharedHealth,\n change: (registry: ResourceHealthRegistry) => R,\n): Promise<R> {\n return shared.file.update((current) => {\n const registry = new ResourceHealthRegistry(shared.clock, DEFAULT_HEALTH_CONFIG, shared.newId)\n registry.restore(parseHealthPayload(current))\n const result = change(registry)\n return {\n next: { version: HEALTH_VERSION, records: retainedHealthRecords(registry.snapshot()) },\n result,\n }\n })\n}\n\nfunction keyOf(ref: ModelRef): ResourceKey {\n return { providerID: ref.providerID, modelID: ref.id }\n}\n\n/**\n * Assess the candidates of one admission. Assessing a due open breaker issues\n * a probe ticket; every ticket the admission does not dispatch must be\n * handed back with `releaseUnselected`, or the probe stays in flight until it\n * times out.\n */\nexport function assessCandidates(\n registry: ResourceHealthRegistry,\n candidates: readonly ModelRef[],\n): { readonly health: Record<string, Assessment>; readonly tickets: readonly ProbeTicket[] } {\n const health: Record<string, Assessment> = {}\n const tickets: ProbeTicket[] = []\n for (const ref of candidates) {\n const assessment = registry.assess(keyOf(ref))\n health[schedulerHealthKey(ref)] = assessment\n if (assessment.kind === \"probe\") tickets.push(assessment.ticket)\n }\n return { health, tickets }\n}\n\nexport function releaseUnselected(\n registry: ResourceHealthRegistry,\n tickets: readonly ProbeTicket[],\n selected: ModelRef | undefined,\n): void {\n for (const ticket of tickets)\n if (ticket.key.providerID !== selected?.providerID || ticket.key.modelID !== selected.id)\n registry.releaseProbe(ticket)\n}\n\n/**\n * Record how one dispatched request ended. User cancellations are not\n * provider evidence. Only the dispatching process sees the outcome of a\n * half-open record, so a failure there is that probe's outcome; a success\n * closes the breaker from any state. Returns the failure classification of\n * an errored dispatch, for the receipt outcome.\n */\nexport function observeOutcome(\n registry: ResourceHealthRegistry,\n ref: ModelRef,\n message: FailedMessage,\n): FailureClassification | undefined {\n const key = keyOf(ref)\n if (message.stopReason === \"aborted\") return undefined\n if (message.stopReason !== \"error\") {\n registry.observe({ kind: \"success\", key })\n return undefined\n }\n const classification = classifyFailure(failureEvidence(message))\n const breaker = registry.recordFor(key)?.breaker\n if (breaker?.state === \"half_open\" && breaker.probeId !== undefined)\n registry.reportProbe(\n { id: breaker.probeId, key },\n { success: false, category: classification.category },\n )\n registry.observe(failureEvent(key, classification))\n return classification\n}\n","/**\n * Passive Codex/ChatGPT capacity telemetry (ADP-020).\n *\n * The only consumed evidence is the `x-codex-*` response-header family\n * (including LiteLLM's `llm_provider-x-codex-*` relay form), captured from the\n * `http.response` hook by the wiring-supplied allowlist. Verified wire facts:\n * `x-codex-primary-used-percent` (5h window), `x-codex-secondary-used-percent`\n * (weekly window), `x-codex-{primary,secondary}-window-minutes`,\n * `x-codex-{primary,secondary}-reset-after-seconds`, and\n * `x-codex-{primary,secondary}-reset-at` — where `reset-at` is documented to\n * sometimes arrive as an EMPTY STRING while `reset-after-seconds` is present.\n * Everything is validated; unparseable telemetry produces no estimate rather\n * than a guess.\n */\n\nexport const CODEX_SENSOR_ID = \"codex-headers\"\n\n/** The telemetry windows Codex headers report. Primary is the 5h window. */\nexport const CODEX_WINDOW_KINDS = [\"primary\", \"secondary\"] as const satisfies readonly string[]\n\nexport type CodexWindowKind = (typeof CODEX_WINDOW_KINDS)[number]\n\nexport interface CodexWindow {\n /** Usage percentage in [0, 100] — the window exists only if this is valid. */\n readonly usedPercent: number\n /** Validated finite non-negative seconds until reset, when reported. */\n readonly resetAfterSeconds?: number | undefined\n /** Validated finite non-negative epoch-seconds reset timestamp, when reported. */\n readonly resetAtSeconds?: number | undefined\n}\n\n/** One validated header observation. `null` windows are simply absent. */\nexport interface CodexUsage {\n readonly primary?: CodexWindow | undefined\n readonly secondary?: CodexWindow | undefined\n}\n","/**\n * Untrusted-header validation. Header values arrive from provider responses\n * (or relays); every field is parsed defensively and a window is admitted only\n * when its usage percentage is trustworthy. A usage above 100% voids the\n * snapshot rather than leaving the other window to speak for it. Reset fields that fail validation\n * are dropped field-wise — they cannot invalidate a valid percentage.\n */\nimport type { CodexUsage, CodexWindow, CodexWindowKind } from \"./types.js\"\nimport { CODEX_WINDOW_KINDS } from \"./types.js\"\n\n/**\n * LiteLLM relays Codex headers under a provider prefix, e.g.\n * `llm_provider-x-codex-primary-used-percent`. Matching on the substring keeps\n * the parser independent of which relay prefix is used.\n */\nexport const CODEX_HEADER_MARK = \"x-codex-\"\n\n/**\n * Allowlist predicate for the `http.response` capture option: matches plain\n * and LiteLLM-prefixed Codex telemetry header names (case already lowered by\n * the caller). Only quota telemetry passes — no other response header is ever\n * captured.\n */\nexport function isCodexHeaderName(lowercaseName: string): boolean {\n return lowercaseName.includes(CODEX_HEADER_MARK)\n}\n\ninterface WindowAccumulator {\n usedPercent?: number | undefined\n /** A usage above 100% was reported: the window is exhausted, not absent. */\n overshoot?: boolean | undefined\n resetAfterSeconds?: number | undefined\n resetAtSeconds?: number | undefined\n}\n\nfunction finiteAtLeast(value: string, min: number): number | undefined {\n // An empty (or whitespace-only) value must not fall through Number(\"\") === 0.\n const trimmed = value.trim()\n if (trimmed === \"\") {\n return undefined\n }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed) || parsed < min) {\n return undefined\n }\n return parsed\n}\n\nfunction emptyAccumulator(): WindowAccumulator {\n return {\n usedPercent: undefined,\n overshoot: undefined,\n resetAfterSeconds: undefined,\n resetAtSeconds: undefined,\n }\n}\n\nfunction takenValue(accumulator: WindowAccumulator, suffix: string): number | undefined {\n switch (suffix) {\n case \"used-percent\":\n return accumulator.usedPercent\n case \"reset-after-seconds\":\n return accumulator.resetAfterSeconds\n case \"reset-at\":\n return accumulator.resetAtSeconds\n default:\n return undefined\n }\n}\n\nfunction applyField(accumulator: WindowAccumulator, suffix: string, value: string): void {\n // First valid value per field wins; invalid or duplicate values are ignored.\n if (takenValue(accumulator, suffix) !== undefined) {\n return\n }\n switch (suffix) {\n case \"used-percent\": {\n // The percentage is the window's existence test: out of range or\n // unparseable values never admit a window.\n const usedPercent = finiteAtLeast(value, 0)\n if (usedPercent === undefined) {\n return\n }\n if (usedPercent > 100) {\n accumulator.overshoot = true\n return\n }\n accumulator.usedPercent = usedPercent\n return\n }\n case \"reset-after-seconds\": {\n const resetAfterSeconds = finiteAtLeast(value, 0)\n if (resetAfterSeconds !== undefined) {\n accumulator.resetAfterSeconds = resetAfterSeconds\n }\n return\n }\n case \"reset-at\": {\n // Documented wire quirk: reset-at can be an empty string while\n // reset-after-seconds carries the real value. Empty and unparseable\n // values are dropped, never guessed at.\n const resetAtSeconds = finiteAtLeast(value, 0)\n if (resetAtSeconds !== undefined) {\n accumulator.resetAtSeconds = resetAtSeconds\n }\n return\n }\n default:\n // window-minutes and unknown suffixes carry no reading information.\n return\n }\n}\n\nfunction windowOf(accumulator: WindowAccumulator): CodexWindow | undefined {\n const usedPercent = accumulator.usedPercent\n if (usedPercent === undefined) {\n return undefined\n }\n const { resetAfterSeconds, resetAtSeconds } = accumulator\n return {\n usedPercent,\n ...(resetAfterSeconds !== undefined ? { resetAfterSeconds } : {}),\n ...(resetAtSeconds !== undefined ? { resetAtSeconds } : {}),\n }\n}\n\n/**\n * Parse captured response headers into a validated usage snapshot. Header\n * lookup is case-insensitive and accepts LiteLLM-prefixed names; fields\n * accumulate per window in any order. Returns `null` when no window carries a\n * trustworthy usage percentage.\n */\nexport function parseCodexUsage(captured: Readonly<Record<string, string>>): CodexUsage | null {\n const accumulators: Record<CodexWindowKind, WindowAccumulator | undefined> = {\n primary: undefined,\n secondary: undefined,\n }\n for (const [rawName, value] of Object.entries(captured)) {\n const mark = rawName.toLowerCase().indexOf(CODEX_HEADER_MARK)\n if (mark < 0) {\n continue\n }\n const rest = rawName.slice(mark + CODEX_HEADER_MARK.length).toLowerCase()\n const separator = rest.indexOf(\"-\")\n const kind = rest.slice(0, separator)\n if (!(CODEX_WINDOW_KINDS as readonly string[]).includes(kind)) {\n continue\n }\n const key = kind as CodexWindowKind\n const accumulator = accumulators[key] ?? emptyAccumulator()\n applyField(accumulator, rest.slice(separator + 1), value)\n accumulators[key] = accumulator\n }\n // An overshooting window is exhausted, yet its percentage is not\n // trustworthy: dropping just that window would let the other one present\n // the subscription as usable, so the whole snapshot is void.\n if (accumulators.primary?.overshoot === true || accumulators.secondary?.overshoot === true) {\n return null\n }\n const primary = windowOf(accumulators.primary ?? emptyAccumulator())\n const secondary = windowOf(accumulators.secondary ?? emptyAccumulator())\n if (primary === undefined && secondary === undefined) {\n return null\n }\n return {\n ...(primary !== undefined ? { primary } : {}),\n ...(secondary !== undefined ? { secondary } : {}),\n }\n}\n","/**\n * Codex usage → `CapacityReading` conversion. The binding constraint is the\n * most-consumed window (ties read the primary window, deterministic). Ratios\n * are exact percent/100 fractions; the reset timestamp is anchored to when the\n * headers were observed, preferring the relative `reset-after-seconds` over\n * the absolute `reset-at` epoch-seconds field.\n *\n * Confidence grades telemetry completeness: a binding window with BOTH a\n * usage percentage and a validated reset field is `high` (self-consistent,\n * provider-generated, actionable for draining); a percentage alone is\n * `medium`. An usage snapshot with no window at all yields a no-measurement\n * reading that the capacity merge layer discards as pure noise.\n */\nimport type { Confidence } from \"../../health/capacity/types.js\"\nimport type { CapacityReading } from \"../../health/capacity/types.js\"\nimport type { CodexUsage, CodexWindow } from \"./types.js\"\n\nexport const CODEX_EVIDENCE = \"x-codex headers\"\n\nfunction hasReset(window: CodexWindow): boolean {\n return window.resetAfterSeconds !== undefined || window.resetAtSeconds !== undefined\n}\n\n/**\n * The window whose exhaustion binds first: higher usage wins, ties → primary.\n * Returns `undefined` only for a snapshot with no window at all.\n */\nexport function bindingWindow(usage: CodexUsage): CodexWindow | undefined {\n const primary = usage.primary\n const secondary = usage.secondary\n if (primary === undefined) {\n return secondary\n }\n if (secondary === undefined) {\n return primary\n }\n return secondary.usedPercent > primary.usedPercent ? secondary : primary\n}\n\nexport function readingFromUsage(usage: CodexUsage, observedAt: number): CapacityReading {\n const window = bindingWindow(usage)\n if (window === undefined) {\n // No measured field — the capacity merge layer rejects this as noise.\n return { confidence: \"low\", observedAt, evidence: CODEX_EVIDENCE }\n }\n const usedRatio = window.usedPercent / 100\n const remainingRatio = 1 - usedRatio\n let resetAt: number | undefined\n if (window.resetAfterSeconds !== undefined) {\n resetAt = observedAt + window.resetAfterSeconds * 1000\n } else if (window.resetAtSeconds !== undefined) {\n resetAt = window.resetAtSeconds * 1000\n }\n const confidence: Confidence = hasReset(window) ? \"high\" : \"medium\"\n return {\n usedRatio,\n remainingRatio,\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n evidence: CODEX_EVIDENCE,\n }\n}\n","/**\n * The passive-header `CapacitySensor` (ADP-020). Holds the latest validated\n * header observation; `read()` converts it to a reading. No polling, no\n * endpoint calls, no credential handling — WebSocket-backed providers bypass\n * the HTTP hook entirely (verified limitation), so this sensor reports\n * `null` (no estimate) whenever no trustworthy headers have been observed.\n * An unparseable observation CLEARS the stored usage: present-but-invalid\n * telemetry is distrust, and a stale quota estimate must never linger.\n */\nimport type { ResourceKey } from \"../../health/resource-health/types.js\"\nimport type { CapacityReading, CapacitySensor } from \"../../health/capacity/types.js\"\nimport { parseCodexUsage } from \"./parse.js\"\nimport { readingFromUsage } from \"./reading.js\"\nimport type { CodexUsage } from \"./types.js\"\nimport { CODEX_SENSOR_ID } from \"./types.js\"\n\nexport class CodexCapacitySensor implements CapacitySensor {\n readonly id = CODEX_SENSOR_ID\n readonly resource: ResourceKey\n #usage: CodexUsage | null = null\n #observedAt = 0\n\n constructor(resource: ResourceKey) {\n this.resource = resource\n }\n\n /**\n * Record one captured-header observation. Unparseable telemetry clears the\n * previous estimate instead of keeping it (present-but-invalid = distrust).\n */\n observe(captured: Readonly<Record<string, string>>, observedAt: number): void {\n this.#usage = parseCodexUsage(captured)\n if (this.#usage !== null) {\n this.#observedAt = observedAt\n }\n }\n\n read(): Promise<CapacityReading | null> {\n const usage = this.#usage\n if (usage === null) {\n return Promise.resolve(null)\n }\n return Promise.resolve(readingFromUsage(usage, this.#observedAt))\n }\n}\n","import { CONFIDENCE_LEVELS } from \"../../health/capacity/types.js\"\nimport type { CapacityReading } from \"../../health/capacity/types.js\"\nimport type { ResourceKey } from \"../../health/resource-health/types.js\"\nimport { CAPACITY_VERSION, MAX_CAPACITY_READINGS, type PersistedCapacityReading } from \"./types.js\"\n\n// Defensive readers: persisted data is untrusted. Every parser is total —\n// accepts unknown, returns typed records, and drops anything invalid — so a\n// corrupted file can never take the plugin down (ADP-031). An older plugin\n// reading a newer payload drops unknown-vocabulary entries; the version field\n// guards the schema itself.\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\n/**\n * A non-empty bounded identifier. Over-long values are rejected, not\n * truncated: the writer stores keys as-is, so a truncated key would name a\n * different resource.\n */\nfunction parseIdentifier(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || raw === \"\" || raw.length > 128) return undefined\n return raw\n}\n\nfunction parseKey(raw: unknown): ResourceKey | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = parseIdentifier(raw[\"providerID\"])\n if (providerID === undefined) return undefined\n const accountID = parseIdentifier(raw[\"accountID\"])\n const modelID = parseIdentifier(raw[\"modelID\"])\n const variantID = parseIdentifier(raw[\"variantID\"])\n // A present-but-unusable scope field would silently widen the key.\n if (raw[\"accountID\"] !== undefined && accountID === undefined) return undefined\n if (raw[\"modelID\"] !== undefined && modelID === undefined) return undefined\n if (raw[\"variantID\"] !== undefined && variantID === undefined) return undefined\n // Scope fields must form a valid prefix: a variant without a model is not\n // addressable against a model inventory and is not a real resource.\n if (variantID !== undefined && modelID === undefined) return undefined\n return {\n providerID,\n ...(accountID !== undefined ? { accountID } : {}),\n ...(modelID !== undefined ? { modelID } : {}),\n ...(variantID !== undefined ? { variantID } : {}),\n }\n}\n\nfunction parseRatio(raw: unknown): number | undefined {\n return isFiniteNumber(raw) && raw >= 0 && raw <= 1 ? raw : undefined\n}\n\nfunction parseReading(raw: unknown): CapacityReading | undefined {\n if (!isRecord(raw)) return undefined\n const confidence = CONFIDENCE_LEVELS.find((level) => level === raw[\"confidence\"])\n if (confidence === undefined) return undefined\n const observedAt = raw[\"observedAt\"]\n if (!isFiniteNumber(observedAt) || observedAt < 0) return undefined\n const usedRatio = parseRatio(raw[\"usedRatio\"])\n const remainingRatio = parseRatio(raw[\"remainingRatio\"])\n const retryAfterMs =\n isFiniteNumber(raw[\"retryAfterMs\"]) && raw[\"retryAfterMs\"] >= 0\n ? raw[\"retryAfterMs\"]\n : undefined\n const resetAt = isFiniteNumber(raw[\"resetAt\"]) && raw[\"resetAt\"] >= 0 ? raw[\"resetAt\"] : undefined\n // A reading with none of the measured fields carries no information and is\n // discarded (mirrors the domain rule in health/capacity/types.ts).\n if (\n usedRatio === undefined &&\n remainingRatio === undefined &&\n retryAfterMs === undefined &&\n resetAt === undefined\n ) {\n return undefined\n }\n const evidence = raw[\"evidence\"]\n return {\n ...(usedRatio !== undefined ? { usedRatio } : {}),\n ...(remainingRatio !== undefined ? { remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n ...(typeof evidence === \"string\" && evidence.length > 0\n ? { evidence: evidence.slice(0, 128) }\n : {}),\n }\n}\n\nfunction parseEntry(raw: unknown): PersistedCapacityReading | undefined {\n if (!isRecord(raw)) return undefined\n const key = parseKey(raw[\"key\"])\n if (key === undefined) return undefined\n const reading = parseReading(raw[\"reading\"])\n if (reading === undefined) return undefined\n return { key, reading }\n}\n\n// Every parser is total: accepts unknown, returns typed records, and drops\n// anything invalid — a corrupted file can never take the plugin down\n// (ADP-031). An older plugin reading newer records may drop\n// unknown-vocabulary entries — records are bounded mirrors of an in-memory\n// registry, and the payload version guards the schema itself.\nexport function parseCapacityPayload(raw: unknown): PersistedCapacityReading[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== CAPACITY_VERSION) return []\n if (!Array.isArray(raw[\"readings\"])) return []\n const list = raw[\"readings\"]\n const readings: PersistedCapacityReading[] = []\n for (const entry of list.slice(0, MAX_CAPACITY_READINGS)) {\n const parsed = parseEntry(entry)\n if (parsed !== undefined) readings.push(parsed)\n }\n return readings\n}\n","// covers: [\"ADP-020\", \"ADP-021\", \"ADP-031\", \"ADP-051\", \"ADP-056\", \"ADP-059\"]\nimport { isDeepStrictEqual } from \"node:util\"\nimport {\n capacitySignals,\n mergeReadings,\n normalizeReading,\n} from \"@coool/adaptive-core/health/capacity/merge\"\nimport type { CapacityReading } from \"@coool/adaptive-core/health/capacity/types\"\nimport { resourceChain, resourceKeyID } from \"@coool/adaptive-core/health/resource-health/key\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport {\n schedulerHealthKey,\n type SchedulerInput,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport {\n CodexCapacitySensor,\n isCodexHeaderName,\n} from \"@coool/adaptive-core/sensors/codex-capacity/index\"\nimport { parseCapacityPayload } from \"@coool/adaptive-core/state/capacity/parse\"\nimport {\n CAPACITY_VERSION,\n MAX_CAPACITY_READINGS,\n type PersistedCapacityReading,\n} from \"@coool/adaptive-core/state/capacity/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport interface SharedCapacity {\n readonly file: JsonFile\n readonly clock: () => number\n}\n\nexport interface CapacityView {\n readonly capacity: SchedulerInput[\"capacity\"]\n /** Fresh readings for status and reset-aware parking; null means unknown. */\n readonly readings: Readonly<Record<string, CapacityReading | null>>\n}\n\nfunction parse(raw: unknown): PersistedCapacityReading[] {\n if (raw === undefined) return []\n const readings = parseCapacityPayload(raw)\n // The core mirror reader is intentionally tolerant. A shared file must not\n // be rewritten after that reader dropped malformed fields or newer schema.\n if (!isDeepStrictEqual(raw, { version: CAPACITY_VERSION, readings }))\n throw new Error(\"Adaptive capacity: invalid capacity.json payload\")\n return readings\n}\n\nfunction capturedHeaders(raw: unknown): Record<string, string> {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw))\n throw new Error(\"Adaptive capacity: headers must be an object\")\n const headers: Record<string, string> = {}\n for (const [name, value] of Object.entries(raw)) {\n if (!isCodexHeaderName(name.toLowerCase())) continue\n if (typeof value !== \"string\")\n throw new Error(\"Adaptive capacity: Codex header values must be strings\")\n headers[name] = value\n }\n return headers\n}\n\n/**\n * Observe only a known dispatched provider, never the selected virtual model.\n * Codex limits are provider-wide. Raw headers, account ids and credentials are\n * never persisted: the core sensor emits numbers and a fixed source label.\n * Missing/invalid telemetry adds nothing; previous observations age out using\n * the same freshness rule as the core mirror.\n */\nexport async function observeCodexHeaders(\n shared: SharedCapacity,\n providerID: unknown,\n headers: unknown,\n): Promise<void> {\n try {\n if (typeof providerID !== \"string\" || providerID === \"\" || providerID.length > 128)\n throw new Error(\"Adaptive capacity: providerID must be a bounded nonempty string\")\n const sensor = new CodexCapacitySensor({ providerID })\n sensor.observe(capturedHeaders(headers), shared.clock())\n const reading = normalizeReading(await sensor.read())\n if (reading === null) return\n const entry = { key: sensor.resource, reading }\n await shared.file.update((current) => {\n // Merge inside the cross-process lock so a peer's newer observation\n // cannot be overwritten by a snapshot read before acquiring it.\n const byKey = new Map(parse(current).map((item) => [resourceKeyID(item.key), item]))\n const id = resourceKeyID(entry.key)\n const previous = byKey.get(id)\n if (previous === undefined || reading.observedAt > previous.reading.observedAt)\n byKey.set(id, entry)\n const readings = [...byKey.values()]\n .sort((a, b) => b.reading.observedAt - a.reading.observedAt)\n .slice(0, MAX_CAPACITY_READINGS)\n return { next: { version: CAPACITY_VERSION, readings }, result: undefined }\n })\n } catch {\n // Neither a header getter nor a storage adapter's exception is safe to log.\n logFailOpen(\"capacity.observe\", \"Capacity observation unavailable\")\n }\n}\n\n/** Read the shared mirror afresh; the core owns scope, freshness and draining. */\nexport async function readCapacity(\n shared: SharedCapacity,\n candidates: readonly ModelRef[],\n): Promise<CapacityView> {\n const capacity: Record<string, ReturnType<typeof capacitySignals>> = {}\n const readings: Record<string, CapacityReading | null> = {}\n for (const ref of candidates) readings[schedulerHealthKey(ref)] = null\n try {\n const entries = await shared.file.update((current) => ({\n next: undefined,\n result: parse(current),\n }))\n const now = shared.clock()\n for (const ref of candidates) {\n const chain = new Set(\n resourceChain({ providerID: ref.providerID, modelID: ref.id, variantID: ref.variant }).map(\n resourceKeyID,\n ),\n )\n const reading = mergeReadings(\n entries\n .filter((entry) => chain.has(resourceKeyID(entry.key)))\n .map((entry) => entry.reading),\n now,\n )\n const id = schedulerHealthKey(ref)\n readings[id] = reading\n if (reading !== null) capacity[id] = capacitySignals(reading)\n }\n } catch {\n logFailOpen(\"capacity.read\", \"Shared capacity unavailable\")\n }\n return { capacity, readings }\n}\n","import { observeCodexHeaders, type SharedCapacity } from \"../capacity.js\"\n\n/** Pi strips model metadata from response hooks. Overlap is not attributable. */\nexport function dispatchCapacity(shared: SharedCapacity) {\n let provider: string | undefined\n let ambiguous = false\n return {\n selected(selected: string) {\n if (provider !== undefined) ambiguous = true\n provider = selected\n },\n clear() {\n provider = undefined\n ambiguous = false\n },\n async response(headers: unknown) {\n if (!ambiguous && provider !== undefined) await observeCodexHeaders(shared, provider, headers)\n },\n }\n}\n","import { replaceControlCharacters, truncateToWidth } from \"@earendil-works/pi-tui\"\nimport { object } from \"../settings.js\"\nimport type { AdaptiveNote } from \"../ui/notes.js\"\n\nexport const NOTE_ENTRY = \"adaptive.note\"\n\ninterface NoteComponent {\n render(width: number): string[]\n invalidate(): void\n}\ninterface EntryHost {\n registerEntryRenderer(\n type: string,\n renderer: (\n entry: { readonly data?: unknown },\n options: { readonly expanded: boolean },\n theme: { fg(color: \"dim\", text: string): string },\n ) => NoteComponent | undefined,\n ): void\n}\n\n/** Sanitizes persisted/user-controlled identifiers before they reach the terminal. */\nexport function fitLine(text: string, width: number): string {\n return truncateToWidth(replaceControlCharacters(text), Math.max(0, width), \"…\")\n}\n\nexport function registerEntries(pi: EntryHost): void {\n pi.registerEntryRenderer(NOTE_ENTRY, (entry, options, theme) => {\n const data: unknown = entry.data\n if (!object(data) || data[\"version\"] !== 1 || typeof data[\"text\"] !== \"string\") return undefined\n const text = data[\"text\"]\n const id = data[\"receiptID\"]\n const detail =\n options.expanded && typeof id === \"number\" ? ` · receipt #${String(id)} · /adaptive why` : \"\"\n return {\n render: (width) => [theme.fg(\"dim\", fitLine(`Adaptive · ${text}${detail}`, width))],\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n })\n}\n\nexport function appendNote(\n pi: { appendEntry(type: string, data: AdaptiveNote): void },\n note: AdaptiveNote,\n): void {\n pi.appendEntry(NOTE_ENTRY, note)\n}\n","/**\n * Operating-mode wrapper (GOAL operating modes). OBSERVE and CONTROL run the\n * identical core; OBSERVE wraps the result without applying it. OFF never\n * reaches the scheduler, but the total wrapper maps it to an explicit defer\n * so the union stays closed.\n */\nimport type { Decision, OperatingMode } from \"./types.js\"\n\nexport function forMode(decision: Decision, mode: OperatingMode): Decision {\n if (mode === \"observe\") {\n return { kind: \"observe-only\", would: decision }\n }\n if (mode === \"active\") {\n return decision\n }\n return { kind: \"defer\", reason: \"adaptive-off\" }\n}\n","import { capacitySignals } from \"../../health/capacity/merge.js\"\nimport { DEFAULT_CAPACITY_CONFIG, type CapacityReading } from \"../../health/capacity/types.js\"\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\n/**\n * Parked-work wake planning (ADP-024): when every resource of a parked\n * unit's tier is blocked, nothing else is guaranteed to reach a safe\n * boundary again (`experimental.idle` only follows successful work), so the\n * supervisor arms one timer for the earliest moment a candidate resource\n * becomes usable. All times are epoch ms; `undefined` means \"unknown\" (no\n * stated reset — e.g. an auth quarantine or an in-flight probe).\n */\n\n/** Wake slightly after the window ends so the resource is past its reset. */\nexport const WAKE_GRACE_MS = 1_000\n/** Shortest wake delay: a due target never spins the timer. */\nexport const MIN_WAKE_MS = 1_000\n/** Re-check cadence when no candidate states when it recovers. */\nexport const UNKNOWN_WAKE_MS = 5 * 60_000\n/**\n * Longest single timer. Longer waits (weekly limits) re-arm in steps, which\n * also keeps the delay far below the 2^31 ms setTimeout overflow and\n * re-anchors the schedule after laptop sleep or wall-clock jumps.\n */\nexport const MAX_WAKE_MS = 30 * 60_000\n/** First backoff step after a wake that resumed nothing; doubles per miss. */\nexport const FRUITLESS_BASE_MS = 5_000\n\n/**\n * When one health record stops blocking admission: windowed states lift at\n * their window end, an open breaker at its reopen time. Unavailable (no\n * window, permanent until reset) and half-open (a probe decides) are unknown.\n */\nfunction recordUsableAt(record: ResourceRecord, now: number): number | undefined {\n if (record.health === \"unavailable\" || record.breaker.state === \"half_open\") {\n return undefined\n }\n let at = now\n if (record.health === \"quota_exhausted\" || record.health === \"rate_limited\") {\n if (record.window === undefined) return undefined\n at = Math.max(at, record.window.until)\n }\n if (record.breaker.state === \"open\") {\n at = Math.max(at, record.breaker.reopenAt ?? now)\n }\n return at\n}\n\n/**\n * When a resource becomes usable: the latest of its health chain (a blocked\n * ancestor blocks every descendant) and its capacity estimate. An exhausted\n * estimate clears at its stated reset or when the reading goes stale,\n * whichever comes first — stale readings stop blocking admission.\n */\nexport function resourceUsableAt(\n chain: readonly (ResourceRecord | undefined)[],\n reading: CapacityReading | null,\n now: number,\n): number | undefined {\n let at = now\n for (const record of chain) {\n if (record === undefined) continue\n const usable = recordUsableAt(record, now)\n if (usable === undefined) return undefined\n at = Math.max(at, usable)\n }\n if (reading !== null && capacitySignals(reading).exhausted) {\n const stale = reading.observedAt + DEFAULT_CAPACITY_CONFIG.maxAgeMs\n const reset = reading.resetAt ?? stale\n at = Math.max(at, Math.min(reset, stale))\n }\n return at\n}\n\n/** Earliest known time among candidates; unknown when none is known. */\nexport function earliestUsable(times: readonly (number | undefined)[]): number | undefined {\n let earliest: number | undefined\n for (const time of times) {\n if (time !== undefined && (earliest === undefined || time < earliest)) earliest = time\n }\n return earliest\n}\n\nexport interface WakePlan {\n /** When the parked work is due for a resume sweep. */\n readonly dueAt: number\n /** Timer delay; shorter than `dueAt - now` when capped by MAX_WAKE_MS. */\n readonly delayMs: number\n /**\n * Whether the timer fires before `dueAt` by design (capped delay). An\n * uncapped fire is due even when the clock reads a little early: timers\n * and wall clocks drift, and a clock stepped back must not skip the sweep.\n */\n readonly capped: boolean\n}\n\n/**\n * Plans the next wake for the parked units' resume times. `fruitless` counts\n * consecutive wake sweeps that resumed nothing: each one doubles the minimum\n * delay (capped), so a resource that looks usable but keeps refusing work\n * cannot spin the timer. No targets → no wake.\n */\nexport function planWake(\n targets: readonly (number | undefined)[],\n now: number,\n fruitless: number,\n): WakePlan | undefined {\n if (targets.length === 0) return undefined\n const known = earliestUsable(targets)\n let dueAt = known === undefined ? Number.POSITIVE_INFINITY : known + WAKE_GRACE_MS\n if (targets.includes(undefined)) dueAt = Math.min(dueAt, now + UNKNOWN_WAKE_MS)\n const floor =\n fruitless === 0 ? MIN_WAKE_MS : Math.min(MAX_WAKE_MS, FRUITLESS_BASE_MS * 2 ** (fruitless - 1))\n dueAt = Math.max(dueAt, now + floor)\n const capped = dueAt - now > MAX_WAKE_MS\n return { dueAt, delayMs: capped ? MAX_WAKE_MS : dueAt - now, capped }\n}\n","// covers: [\"ADP-024\", \"ADP-060\"]\nimport { MAX_PARKED_ATTEMPTS } from \"@coool/adaptive-core/execution/parking/plan\"\nimport { isTierName, type TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { JsonFile } from \"./store.js\"\n\n/** Metadata only: user input stays in Pi's own session file, never this index. */\nexport interface Parked {\n readonly session: string\n readonly token: string\n readonly tier: TierName\n readonly due: number\n readonly wakes: number\n readonly claimed: boolean\n}\n\nexport interface ParkingSources {\n readonly file: JsonFile\n readonly clock: () => number\n readonly timer: (callback: () => void, delay: number) => () => void\n}\n\n/**\n * Failed wake deliveries before a parked task stops auto-waking (the same\n * give-up budget OpenCode derives from MAX_PARKED_ATTEMPTS). A wake that\n * re-parks because the tier is still blocked does not consume the budget:\n * waiting for a stated reset is free, only resumed work that failed again\n * counts.\n */\nexport const MAX_WAKES = MAX_PARKED_ATTEMPTS\nexport const SHORT_WAIT_MS = 120_000\nexport const PARK_ENTRY = \"adaptive.parked\"\nexport class WaitCancelled extends Error {\n constructor() {\n super(\"Adaptive wait cancelled\")\n }\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\nexport function parseParked(value: unknown): Parked {\n const session = field(value, \"session\")\n const token = field(value, \"token\")\n const tier = field(value, \"tier\")\n const due = field(value, \"due\")\n const wakes = field(value, \"wakes\")\n const claimed = field(value, \"claimed\")\n if (typeof session !== \"string\" || session.length === 0)\n throw new Error(\"Adaptive parked: session must be a non-empty string\")\n if (typeof token !== \"string\" || token.length === 0)\n throw new Error(\"Adaptive parked: token must be a non-empty string\")\n if (typeof tier !== \"string\" || !isTierName(tier))\n throw new Error(\"Adaptive parked: tier must be quick, standard, or advanced\")\n if (typeof due !== \"number\" || !Number.isFinite(due) || due < 0)\n throw new Error(\"Adaptive parked: due must be a finite timestamp\")\n // Manual retries after the give-up may keep failing, so `wakes` has no\n // upper bound: MAX_WAKES is policy (stop auto-waking), not a format limit.\n if (typeof wakes !== \"number\" || !Number.isSafeInteger(wakes) || wakes < 0)\n throw new Error(\"Adaptive parked: wakes must be a non-negative integer\")\n if (typeof claimed !== \"boolean\") throw new Error(\"Adaptive parked: claimed must be boolean\")\n return { session, token, tier, due, wakes, claimed }\n}\n\nfunction records(value: unknown): Parked[] {\n if (value === undefined) return []\n const rows = field(value, \"records\")\n if (field(value, \"version\") !== 1 || !Array.isArray(rows) || rows.length > 512)\n throw new Error(\"Adaptive parked: expected version 1 and at most 512 records\")\n return rows.map(parseParked)\n}\n\nexport function savePark(file: JsonFile, record: Parked): Promise<void> {\n return file.update((value) => ({\n next: {\n version: 1,\n records: [...records(value).filter((row) => row.session !== record.session), record].slice(\n -512,\n ),\n },\n result: undefined,\n }))\n}\n\nexport function findPark(file: JsonFile, session: string): Promise<Parked | undefined> {\n return file.update((value) => ({\n next: undefined,\n result: records(value).find((row) => row.session === session && !row.claimed),\n }))\n}\n\n/**\n * Claim before dispatch under the same cross-process file lock. The claim\n * does not touch `wakes`: only a re-park after the delivered task failed\n * again does (parkingAfterRun). `manual` retries a given-up task on the\n * user's explicit request instead of silently refusing it.\n */\nexport function claimPark(\n file: JsonFile,\n record: Parked,\n now: number,\n manual = false,\n): Promise<boolean> {\n return file.update((value) => {\n const rows = records(value)\n const found = rows.find((row) => row.session === record.session && row.token === record.token)\n const claimed =\n found !== undefined &&\n !found.claimed &&\n found.due <= now &&\n (manual || found.wakes < MAX_WAKES)\n return {\n next: claimed\n ? {\n version: 1,\n records: rows.map((row) => (row === found ? { ...row, claimed: true } : row)),\n }\n : undefined,\n result: claimed,\n }\n })\n}\n\n/** Drops the session's records; true when one was still waiting (not yet claimed). */\nexport function cancelPark(file: JsonFile, session: string): Promise<boolean> {\n return file.update((value) => {\n const rows = records(value)\n return {\n next: { version: 1, records: rows.filter((row) => row.session !== session) },\n result: rows.some((row) => row.session === session && !row.claimed),\n }\n })\n}\n\n/** Abortable ticks, shared by countdowns and long owned headless waits. */\nexport async function waitUntil(\n sources: ParkingSources,\n due: number,\n signal: AbortSignal,\n tick: (remaining: number) => void,\n): Promise<void> {\n while (sources.clock() < due) {\n if (signal.aborted) throw new WaitCancelled()\n const remaining = due - sources.clock()\n tick(remaining)\n await new Promise<void>((resolve, reject) => {\n const abort = () => {\n cancel()\n reject(new WaitCancelled())\n }\n const cancel = sources.timer(\n () => {\n signal.removeEventListener(\"abort\", abort)\n resolve()\n },\n Math.min(remaining, 1_000),\n )\n signal.addEventListener(\"abort\", abort, { once: true })\n })\n }\n if (signal.aborted) throw new WaitCancelled()\n}\n","/** Extract and join text from message content. */\nexport function contentText(content, separator = \"\\n\") {\n if (typeof content === \"string\")\n return content;\n return content\n .filter((block) => block.type === \"text\")\n .map((block) => block.text)\n .join(separator);\n}\n/** Render a system message as a complete prompt: its content followed by its sections. */\nexport function getSystemMessageText(message) {\n const parts = [contentText(message.content)];\n for (const text of Object.values(message.sections ?? {})) {\n if (text !== null)\n parts.push(text);\n }\n return parts.filter((part) => part.length > 0).join(\"\\n\\n\");\n}\n/**\n * Render a later system message for APIs that accept system messages mid-conversation.\n * Section changes are framed by name so the model can relate them to the leading prompt.\n * This framing is request-time only and may change between versions.\n */\nexport function renderSystemMessageUpdate(message) {\n const parts = [];\n const text = contentText(message.content);\n if (text.length > 0)\n parts.push(text);\n for (const [name, value] of Object.entries(message.sections ?? {})) {\n parts.push(value === null\n ? `Removed system prompt section \"${name}\".`\n : `Updated system prompt section \"${name}\":\\n\\n${value}`);\n }\n return parts.join(\"\\n\\n\");\n}\n/**\n * `text.slice(start, end)` as a string of its own. V8 represents a slice of 13 or more characters as a view that keeps\n * all of `text` alive, so a short excerpt kept from a large text (a 500-character error message cut from a megabyte\n * response body) would keep the whole text alive as long as the excerpt lives. Appending a character and slicing it off\n * again makes V8 copy just the slice.\n */\nexport function ownedSlice(text, start, end = text.length) {\n return `${text.slice(start, end)} `.slice(0, -1);\n}\n//# sourceMappingURL=text.js.map","import { getSystemMessageText } from \"./text.js\";\nconst CHARS_PER_TOKEN = 3.5;\nconst ESTIMATED_IMAGE_CHARS = 4800;\nexport function calculateContextTokens(usage) {\n return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n}\nfunction safeJsonStringify(value) {\n try {\n return JSON.stringify(value) ?? \"undefined\";\n }\n catch {\n return \"[unserializable]\";\n }\n}\nfunction estimateTextAndImageContentChars(content) {\n if (typeof content === \"string\")\n return content.length;\n let chars = 0;\n for (const block of content)\n chars += block.type === \"text\" ? block.text.length : ESTIMATED_IMAGE_CHARS;\n return chars;\n}\nexport function estimateTextTokens(text) {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\nexport function estimateTextAndImageContentTokens(content) {\n return Math.ceil(estimateTextAndImageContentChars(content) / CHARS_PER_TOKEN);\n}\nexport function estimateMessageTokens(message) {\n let chars = 0;\n if (message.role === \"system\") {\n return (estimateTextTokens(getSystemMessageText(message)) +\n estimateToolsTokens(message.toolsAdded) +\n estimateToolsTokens(message.toolsRemoved));\n }\n if (message.role === \"user\")\n return estimateTextAndImageContentTokens(message.content);\n if (message.role === \"toolResult\")\n return estimateTextAndImageContentTokens(message.content);\n for (const block of message.content) {\n if (block.type === \"text\") {\n chars += block.text.length;\n }\n else if (block.type === \"thinking\") {\n chars += block.thinking.length;\n }\n else {\n chars += block.name.length + safeJsonStringify(block.arguments).length;\n }\n }\n return Math.ceil(chars / CHARS_PER_TOKEN);\n}\nfunction getLastAssistantUsageInfo(messages) {\n let latestPrefixTimestamp = Number.NEGATIVE_INFINITY;\n let usageInfo;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (message.role === \"assistant\") {\n const assistant = message;\n // A newer prefix message was inserted after this response (for example, a\n // compaction summary), so its usage cannot describe the current prefix.\n const usageAppliesToPrefix = assistant.timestamp >= latestPrefixTimestamp;\n if (usageAppliesToPrefix &&\n assistant.stopReason !== \"aborted\" &&\n assistant.stopReason !== \"error\" &&\n calculateContextTokens(assistant.usage) > 0) {\n usageInfo = { usage: assistant.usage, index: i };\n }\n }\n latestPrefixTimestamp = Math.max(latestPrefixTimestamp, message.timestamp);\n }\n return usageInfo;\n}\nexport function estimateContextTokens(context) {\n const messages = \"messages\" in context ? context.messages : context;\n const usageInfo = getLastAssistantUsageInfo(messages);\n if (usageInfo) {\n const usageTokens = calculateContextTokens(usageInfo.usage);\n let trailingTokens = 0;\n for (let i = usageInfo.index + 1; i < messages.length; i++) {\n trailingTokens += estimateMessageTokens(messages[i]);\n }\n return { tokens: usageTokens + trailingTokens, usageTokens, trailingTokens, lastUsageIndex: usageInfo.index };\n }\n let tokens = 0;\n for (const message of messages)\n tokens += estimateMessageTokens(message);\n return { tokens, usageTokens: 0, trailingTokens: tokens, lastUsageIndex: null };\n}\nfunction estimateToolsTokens(tools) {\n if (!tools || tools.length === 0)\n return 0;\n return estimateTextTokens(safeJsonStringify(tools));\n}\n//# sourceMappingURL=estimate.js.map","import {\n clampThinkingLevel,\n getSupportedThinkingLevels,\n type Api,\n type Message,\n type Model,\n type ModelThinkingLevel,\n} from \"@earendil-works/pi-ai\"\nimport { estimateContextTokens } from \"@earendil-works/pi-ai/utils/estimate\"\nimport type { CandidateModel, Demand } from \"@coool/adaptive-core/routing/compatibility/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { ModelSummary } from \"@coool/adaptive-core/flow/tiers\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport type { ProposalModel } from \"../ui/proposal.js\"\n\nexport function availablePhysicalModels(registry: { getAvailable(): Model<Api>[] }): Model<Api>[] {\n return registry\n .getAvailable()\n .filter((model) => model.provider !== \"adaptive\" && model.api !== \"pi-virtual\")\n}\n\n/** All thinking variants are explicit SDK capabilities, never inferred from names. */\nexport function modelInventory(\n models: readonly Model<Api>[],\n declarations: readonly ToolCapability[],\n): CandidateModel[] {\n return models.flatMap((model) => {\n const declared = declarations.find(\n (entry) => entry.providerID === model.provider && entry.id === model.id,\n )\n const base: CandidateModel = {\n providerID: model.provider,\n modelID: model.id,\n enabled: true,\n providerEnabled: true,\n capabilities: {\n input: model.input,\n output: [\"text\"],\n ...(declared === undefined ? {} : { tools: declared.tools }),\n },\n limit: { context: model.contextWindow },\n }\n return [\n base,\n ...getSupportedThinkingLevels(model).map((variant) => ({\n ...base,\n variant,\n variantAvailable: true,\n })),\n ]\n })\n}\n\nexport function modelSummaries(models: readonly Model<Api>[]): ModelSummary[] {\n return models.map((model) => ({\n providerID: model.provider,\n modelID: model.id,\n name: model.name,\n variants: getSupportedThinkingLevels(model),\n }))\n}\n\nexport function proposalModels(models: readonly Model<Api>[]): ProposalModel[] {\n return models.map((model) => ({\n ref: { providerID: model.provider, id: model.id },\n inputCost: model.cost.input,\n outputCost: model.cost.output,\n reasoning: model.reasoning,\n contextWindow: model.contextWindow,\n thinkingLevels: getSupportedThinkingLevels(model),\n }))\n}\n\nexport function requestDemand(messages: readonly Message[], tools: readonly string[]): Demand {\n return {\n tools: tools.length > 0,\n contextTokens: estimateContextTokens(messages).tokens,\n input: messages.some(\n (message) =>\n typeof message.content !== \"string\" &&\n message.content.some((part) => part.type === \"image\"),\n )\n ? [\"text\", \"image\"]\n : [\"text\"],\n }\n}\n\nexport function thinkingLevelFor(\n model: Model<Api>,\n ref: ModelRef,\n requested: ModelThinkingLevel,\n): ModelThinkingLevel {\n if (ref.variant === undefined) return clampThinkingLevel(model, requested)\n const level = getSupportedThinkingLevels(model).find((candidate) => candidate === ref.variant)\n if (level === undefined)\n throw new Error(\"Adaptive variant is unavailable. Check the tier's thinking level.\")\n return level\n}\n","import type { Api, Model } from \"@earendil-works/pi-ai\"\nimport type { ExtensionContext, ModelRouteRequest } from \"@earendil-works/pi-coding-agent\"\nimport { ResourceHealthRegistry } from \"@coool/adaptive-core/health/index\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { planWake, resourceUsableAt } from \"@coool/adaptive-core/execution/parking/wake\"\nimport { resourceChain } from \"@coool/adaptive-core/health/resource-health/key\"\nimport { checkCompatibility } from \"@coool/adaptive-core/routing/compatibility/gate\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type {\n AdmissionDecision,\n SchedulerInput,\n} from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { schedulerHealthKey } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readCapacity } from \"../capacity.js\"\nimport { assessCandidates, releaseUnselected, withHealth } from \"../health.js\"\nimport { admissionCandidates, routeAdmission, VIRTUAL_IDS, type VirtualID } from \"../router.js\"\nimport { requestedTier } from \"../session.js\"\nimport {\n parseTaskState,\n planRoute,\n type BranchEntry,\n type RoutePlan,\n type TaskState,\n} from \"../task.js\"\nimport { WaitCancelled } from \"../parking.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport type { RoutingFeedback } from \"./status-chip.js\"\nimport {\n availablePhysicalModels,\n modelInventory,\n requestDemand,\n thinkingLevelFor,\n} from \"./inventory.js\"\n\nexport interface RouteContext {\n readonly modelRegistry: { getAvailable(): Model<Api>[] }\n readonly sessionManager: {\n getBranch(): readonly BranchEntry[]\n getSessionId?(): string\n buildSessionProjection?: ExtensionContext[\"sessionManager\"][\"buildSessionProjection\"]\n }\n readonly hasUI?: boolean\n readonly mode?: string\n readonly signal?: AbortSignal | undefined\n readonly ui?: Pick<\n ExtensionContext[\"ui\"],\n \"setStatus\" | \"setWidget\" | \"setWorkingMessage\" | \"notify\" | \"confirm\"\n >\n}\n\nexport function physical(registry: RouteContext[\"modelRegistry\"]): Model<Api>[] {\n return availablePhysicalModels(registry)\n}\n\nexport interface Admission {\n readonly decision: AdmissionDecision\n readonly due: number\n}\n\n/** One scheduler for preview, dispatch, and re-admission after a wait. */\nexport async function prepareAdmission(\n id: VirtualID,\n request: ModelRouteRequest,\n ctx: RouteContext,\n sources: AdaptiveSources,\n activeTools: () => readonly string[],\n preview = false,\n resumedInput?: TaskState,\n degraded?: () => void,\n) {\n const current = await sources.settings()\n const declarations = await sources.capabilities()\n const models = physical(ctx.modelRegistry)\n const state = parseTaskState(request.state)\n const computed = planRoute({\n id,\n reason: request.reason,\n state,\n branch: ctx.sessionManager.getBranch(),\n requestedTier: requestedTier(ctx.sessionManager.getBranch()),\n failed:\n request.failed === undefined\n ? undefined\n : {\n model: { providerID: request.failed.model.provider, id: request.failed.model.id },\n message: request.failed.message,\n },\n newId: sources.newId,\n })\n const plan =\n resumedInput === undefined\n ? computed\n : { ...computed, tier: resumedInput.tier, state: resumedInput }\n const previous = request.previous?.model\n const input = {\n tier: plan.tier,\n sticky: plan.sticky,\n settings: current,\n previous:\n previous === undefined\n ? undefined\n : {\n providerID: previous.provider,\n id: previous.id,\n ...(request.previous?.thinkingLevel === undefined\n ? {}\n : { variant: request.previous.thinkingLevel }),\n },\n inventory: modelInventory(models, declarations),\n demand: requestDemand(request.messages, activeTools()),\n }\n const decide = (\n health: SchedulerInput[\"health\"],\n capacity: SchedulerInput[\"capacity\"],\n ): AdmissionDecision => routeAdmission({ ...input, health, capacity, exclude: plan.exclude })\n /**\n * ADP-003: a defer (an unusable pin) keeps ordinary behaviour — the tier's\n * first resource that passes the compatibility gates, ignoring the pin.\n */\n const deferFallback = () =>\n current.tiers[plan.tier].find((ref) =>\n input.inventory.some(\n (entry) =>\n entry.providerID === ref.providerID &&\n entry.modelID === ref.id &&\n entry.variant === ref.variant &&\n checkCompatibility(entry, input.demand).compatible,\n ),\n )\n const choose = async (ignoreHealth = false): Promise<Admission> => {\n const now = sources.health.clock()\n const fallback = () => ({ decision: decide({}, {}), due: now })\n if (ignoreHealth || plan.sticky) return fallback()\n const candidates = admissionCandidates(current, plan.tier)\n const view = await readCapacity(sources.capacity, candidates)\n // A usage sample describes its old window. Keep it for status, but once\n // its stated reset passes it cannot block admission into the new window.\n const capacity = Object.fromEntries(\n Object.entries(view.capacity).filter(([key]) => {\n const reset = view.readings[key]?.resetAt\n return reset === undefined || reset > now\n }),\n )\n try {\n const assess = (registry: ResourceHealthRegistry) => {\n const { health, tickets } = assessCandidates(registry, candidates)\n const decision = decide(health, capacity)\n releaseUnselected(\n registry,\n tickets,\n !preview && decision.kind === \"apply\" ? decision.model : undefined,\n )\n const targets = candidates.flatMap((ref) => {\n const entry = input.inventory.find(\n (candidate) =>\n candidate.providerID === ref.providerID &&\n candidate.modelID === ref.id &&\n candidate.variant === ref.variant,\n )\n if (entry === undefined || !checkCompatibility(entry, input.demand).compatible) return []\n const chain = resourceChain({\n providerID: ref.providerID,\n modelID: ref.id,\n variantID: ref.variant,\n }).map((key) => registry.recordFor(key))\n return [resourceUsableAt(chain, view.readings[schedulerHealthKey(ref)] ?? null, now)]\n })\n const wake = planWake(targets, now, 0)\n return { decision, due: wake?.dueAt ?? now + 300_000 }\n }\n if (preview) {\n // Preview may simulate a due probe, but never leases or mutates shared health.\n const registry = new ResourceHealthRegistry(sources.health.clock)\n registry.restore(parseHealthPayload(await sources.health.file.read()))\n return assess(registry)\n }\n return await withHealth(sources.health, assess)\n } catch (error) {\n degraded?.()\n logFailOpen(\"health\", error)\n return fallback()\n }\n }\n return { choose, plan, models, state, deferFallback }\n}\n\nexport interface RouteParking {\n takeInput(): TaskState | undefined\n blocked(\n plan: RoutePlan,\n admission: Admission,\n request: ModelRouteRequest,\n ctx: RouteContext,\n ): Promise<RoutePlan | undefined>\n}\n\nexport function virtualModels(\n sources: AdaptiveSources,\n activeTools: () => readonly string[],\n parking?: RouteParking,\n dispatched?: (\n model: Model<Api>,\n info: {\n decision: AdmissionDecision\n unit: string | undefined\n tier: TierName\n session: string | undefined\n retry: boolean\n state: TaskState | undefined\n },\n ) => void,\n feedback?: (ctx: RouteContext) => RoutingFeedback & { readonly context: RouteContext },\n) {\n return VIRTUAL_IDS.map((id) => ({\n provider: \"adaptive\",\n id,\n name: `Adaptive ${id === \"auto\" ? \"Auto\" : id}`,\n async route(request: ModelRouteRequest, ctx: RouteContext) {\n const report = feedback?.(ctx)\n const prepared = await prepareAdmission(\n id,\n request,\n ctx,\n sources,\n activeTools,\n false,\n request.reason === \"user\" ? parking?.takeInput() : undefined,\n () => report?.show({ kind: \"degraded\" }),\n ).catch((error: unknown) => {\n report?.show({ kind: \"degraded\" })\n throw error\n })\n let plan = prepared.plan\n let admission: Admission =\n (plan.state?.hops ?? 0) >= 3 && request.reason === \"retry\"\n ? {\n decision: { kind: \"park\", reason: \"all-blocked\", detail: \"retry budget spent\" },\n due: sources.health.clock() + 300_000,\n }\n : await prepared.choose()\n if (admission.decision.kind === \"park\" && admission.decision.reason === \"no-candidates\") {\n report?.show({ kind: \"setup\" })\n throw new Error(\"Adaptive unavailable: no-candidates. Check your tier settings.\")\n }\n for (\n let attempt = 0;\n admission.decision.kind === \"park\" && parking !== undefined && attempt < 4;\n attempt += 1\n ) {\n try {\n const resumed = await parking.blocked(plan, admission, request, report?.context ?? ctx)\n if (resumed === undefined) break\n plan = resumed\n admission = await prepared.choose()\n } catch (error) {\n if (error instanceof WaitCancelled) throw error\n report?.show({ kind: \"degraded\" })\n logFailOpen(\"parking\", error)\n admission = await prepared.choose(true)\n break\n }\n }\n const { decision } = admission\n let selectedRef: ModelRef\n if (decision.kind === \"defer\") {\n const fallback = prepared.deferFallback()\n if (fallback === undefined) {\n report?.show({ kind: \"setup\" })\n throw new Error(\n `Adaptive is not set up: ${decision.reason}. Run /adaptive to set up tiers.`,\n )\n }\n selectedRef = fallback\n } else {\n if (decision.kind !== \"apply\") {\n // Pi's catalog does not declare tool support, so a tool turn can fail\n // the gate on every configured model: point at the declaration flow.\n const undeclared =\n decision.reason === \"no-compatible-resource\" &&\n decision.detail?.includes(\"tool-use-unsupported\") === true\n throw new Error(\n undeclared\n ? `Adaptive unavailable: ${decision.reason}. Run /adaptive tools to declare which of your models call tools.`\n : `Adaptive unavailable: ${decision.reason}. Check your tier settings.`,\n )\n }\n selectedRef = decision.model\n }\n const selected = prepared.models.find(\n (model) => model.provider === selectedRef.providerID && model.id === selectedRef.id,\n )\n if (selected === undefined) {\n report?.show({ kind: \"degraded\" })\n throw new Error(\"Adaptive inventory changed. Try again.\")\n }\n report?.dispatched(selected, {\n tier: plan.tier,\n retry: request.reason === \"retry\",\n state: plan.state,\n })\n dispatched?.(selected, {\n decision,\n unit: plan.state?.unit,\n tier: plan.tier,\n session: ctx.sessionManager.getSessionId?.(),\n retry: request.reason === \"retry\",\n state: plan.state,\n })\n return {\n model: selected,\n thinkingLevel: thinkingLevelFor(selected, selectedRef, request.thinkingLevel),\n state: plan.state === prepared.state ? request.state : plan.state,\n }\n },\n }))\n}\n","// covers: [\"ADP-015\", \"ADP-055\"]\nimport {\n ESCALATION_TOOL_NAME,\n MAX_ESCALATIONS_PER_TASK,\n parseEscalationRequest,\n} from \"@coool/adaptive-core/execution/escalation/index\"\nimport { isTierName, nextTier } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { VIRTUAL_IDS, type VirtualID } from \"../router.js\"\nimport { branchState, TIER_TOOL, type BranchEntry } from \"../task.js\"\n\n/** The structural subset of Pi's `ExtensionToolContext` the tools read. */\nexport interface ToolContext {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly sessionManager: { getBranch(): readonly BranchEntry[] }\n}\n\ninterface ToolResult {\n readonly content: [{ readonly type: \"text\"; readonly text: string }]\n readonly details: Record<string, unknown>\n readonly isError?: true\n}\n\nfunction reply(text: string, details: Record<string, unknown> = {}): ToolResult {\n return { content: [{ type: \"text\", text }], details }\n}\n\nfunction rejected(text: string): ToolResult {\n return { ...reply(text), isError: true }\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\n/** The Adaptive virtual entry the user selected, if any. */\nexport function selectedVirtual(model: ToolContext[\"model\"]): VirtualID | undefined {\n return model?.provider === \"adaptive\" ? VIRTUAL_IDS.find((id) => id === model.id) : undefined\n}\n\n/**\n * Resolve routing eligibility and the selected task together. Physical model\n * pins always win; tier pins require the user's explicit escalation opt-in.\n */\nfunction routing(\n settings: SettingsV1,\n model: ToolContext[\"model\"],\n escalateFromPinned: boolean,\n): { readonly id: VirtualID } | { readonly ignored: string } {\n const id = selectedVirtual(model)\n if (id === undefined)\n return { ignored: \"Adaptive is not routing this session: the user picked a model.\" }\n if (settings.pin !== null)\n return { ignored: `The user pinned ${settings.pin.providerID}/${settings.pin.id}.` }\n if (id !== \"auto\" && !escalateFromPinned) return { ignored: `The user pinned Adaptive ${id}.` }\n return { id }\n}\n\nexport function tierTool(settings: () => Promise<SettingsV1>) {\n return {\n name: TIER_TOOL,\n label: \"Adaptive tier\",\n description:\n \"Declare the capability tier of the task you are starting: quick (routine edits, mechanical steps), standard (the default), or advanced (multi-step design, broad refactors, hard debugging). The declaration applies from the next user prompt and stays in force for this session until you declare a different tier. Only declare when the task's tier differs from the default; never use this to work around unavailability.\",\n parameters: {\n type: \"object\",\n properties: {\n tier: {\n type: \"string\",\n enum: [\"quick\", \"standard\", \"advanced\"],\n description: \"The tier the task needs.\",\n },\n },\n required: [\"tier\"],\n additionalProperties: false,\n },\n async execute(\n _toolCallId: string,\n params: unknown,\n _signal: unknown,\n _onUpdate: unknown,\n ctx: ToolContext,\n ): Promise<ToolResult> {\n const requested = field(params, \"tier\")\n if (typeof requested !== \"string\" || !isTierName(requested))\n return rejected(\"adaptive_tier rejected: tier must be quick, standard, or advanced.\")\n const current = await settings()\n const route = routing(current, ctx.model, false)\n if (\"ignored\" in route) return reply(`${route.ignored} The tier request was not recorded.`)\n // A selected virtual model is active regardless of the global default.\n return reply(`Tier request recorded: ${requested}. It applies from the next user prompt.`, {\n tier: requested,\n })\n },\n }\n}\n\nexport function escalationTool(\n settings: () => Promise<SettingsV1>,\n escalateFromPinned: () => Promise<boolean>,\n) {\n return {\n name: ESCALATION_TOOL_NAME,\n label: \"Adaptive escalate\",\n description:\n \"Request stronger model capability for the current task. Provide a short reason and the concrete evidence (what failed or was blocked). Adaptive records the request and weighs it only if this run then fails on a capability gap (for example context overflow or a content-policy rejection), within a finite budget; recording alone does not switch models. This is not a planning or task-management tool.\",\n parameters: {\n type: \"object\",\n properties: {\n reason: {\n type: \"string\",\n minLength: 1,\n description: \"Short reason why the current task needs stronger capability.\",\n },\n evidence: {\n type: \"string\",\n minLength: 1,\n description: \"Concrete evidence of the capability gap: what failed or was blocked.\",\n },\n },\n required: [\"reason\", \"evidence\"],\n additionalProperties: false,\n },\n async execute(\n _toolCallId: string,\n params: unknown,\n _signal: unknown,\n _onUpdate: unknown,\n ctx: ToolContext,\n ): Promise<ToolResult> {\n const request = parseEscalationRequest(params)\n if (request === undefined)\n return rejected(\n \"adaptive_escalate rejected: reason and evidence are required non-empty strings.\",\n )\n const current = await settings()\n const route = routing(current, ctx.model, await escalateFromPinned())\n if (\"ignored\" in route)\n return reply(\n `${route.ignored} Adaptive will not escalate; tell the user if you need a stronger model.`,\n )\n const state = branchState(ctx.sessionManager.getBranch(), route.id)\n const tier = state?.tier ?? (route.id === \"auto\" ? \"standard\" : route.id)\n const used = state?.escalations ?? 0\n const next = nextTier(tier)\n const details = { reason: request.reason, evidence: request.evidence }\n if (next === undefined)\n return reply(\n `Recorded, but ${tier} is already the strongest tier; tell the user if you need a stronger model.`,\n details,\n )\n if (used >= MAX_ESCALATIONS_PER_TASK)\n return reply(\n `Recorded, but this task already used its ${String(MAX_ESCALATIONS_PER_TASK)} escalations.`,\n details,\n )\n return reply(\n `Recorded. If this run fails on a capability gap, the task continues on ${next} (${String(used)} of ${String(MAX_ESCALATIONS_PER_TASK)} escalations used).`,\n details,\n )\n },\n }\n}\n","// covers: [\"ADP-029\"]\nimport type { ExtensionAPI, InputEvent, InputEventResult } from \"@earendil-works/pi-coding-agent\"\nimport type { Api, Model } from \"@earendil-works/pi-ai\"\nimport { convertToLlm } from \"@earendil-works/pi-coding-agent\"\nimport { forMode } from \"@coool/adaptive-core/routing/scheduler/mode\"\nimport type { Decision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport { readPreferences } from \"../preferences.js\"\nimport { recordReceipt } from \"../receipts.js\"\nimport { effectiveMode } from \"../session.js\"\nimport { decisionNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { appendNote } from \"./entries.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport { prepareAdmission, type RouteContext } from \"./routing.js\"\nimport { selectedVirtual } from \"./tools.js\"\n\ntype Host = Pick<ExtensionAPI, \"appendEntry\" | \"getActiveTools\">\ninterface ObserveContext extends RouteContext {\n readonly model: Model<Api> | undefined\n}\n\ntype ObserveFeedback =\n { readonly kind: \"observing\"; readonly tier: TierName } | { readonly kind: \"degraded\" }\n\n/** The last decision a transcript note was written for, across handlers. */\nexport interface NoteTracker {\n last: Decision | undefined\n}\n\n/**\n * Manual-model sessions run the identical scheduler; nothing is ever applied\n * and the model keeps the user's choice (ADP-029). Runs on the same `input`\n * boundary the virtual dispatch uses, and never intercepts.\n */\nexport function observeInput(\n pi: Host,\n sources: AdaptiveSources,\n tracker: NoteTracker,\n feedback?: (ctx: ObserveContext) => (state: ObserveFeedback) => void,\n): (event: InputEvent, ctx: ObserveContext) => Promise<InputEventResult> {\n return async (event, ctx) => {\n if (event.source === \"extension\") return { action: \"continue\" }\n let report: ((state: ObserveFeedback) => void) | undefined\n try {\n const model = ctx.model\n if (model === undefined || selectedVirtual(model) !== undefined) return { action: \"continue\" }\n const captured = feedback?.(ctx)\n report = (state) => {\n try {\n captured?.(state)\n } catch (error) {\n logFailOpen(\"status\", error)\n }\n }\n const settings = await sources.settings()\n if (effectiveMode(model, settings.mode, ctx.sessionManager.getBranch()) !== \"observe\")\n return { action: \"continue\" }\n if (ctx.sessionManager.buildSessionProjection === undefined) return { action: \"continue\" }\n const history = convertToLlm(ctx.sessionManager.buildSessionProjection().messages)\n const status = { degraded: false }\n const prepared = await prepareAdmission(\n \"auto\",\n {\n model,\n reason: \"user\",\n thinkingLevel: \"off\",\n messages: [\n ...history,\n {\n role: \"user\",\n timestamp: sources.health.clock(),\n content: [{ type: \"text\", text: event.text }, ...(event.images ?? [])],\n },\n ],\n },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n undefined,\n () => {\n status.degraded = true\n },\n )\n const chosen = await prepared.choose()\n if (status.degraded) report({ kind: \"degraded\" })\n else report({ kind: \"observing\", tier: prepared.plan.tier })\n const decision = forMode(chosen.decision, \"observe\")\n const session = ctx.sessionManager.getSessionId?.()\n if (session !== undefined) {\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.health.clock(),\n sessionID: session,\n tier: prepared.plan.tier,\n decision,\n })\n const { verbosity } = await readPreferences(sources.preferences)\n if (shouldWriteNote(verbosity, decision, tracker.last)) {\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(decision, prepared.plan.tier),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = decision\n }\n }\n } catch (error) {\n report?.({ kind: \"degraded\" })\n logFailOpen(\"observe\", error)\n }\n return { action: \"continue\" }\n }\n}\n","import type { ImageContent } from \"@earendil-works/pi-ai\"\nimport { MAX_WAKES, PARK_ENTRY, type Parked } from \"../parking.js\"\nimport { parseTaskState, type TaskState } from \"../task.js\"\nimport type { RouteContext } from \"./routing.js\"\n\nexport interface ParkedInput {\n readonly text: string\n readonly images?: ImageContent[]\n}\nexport interface ParkPayload {\n readonly token: string\n readonly state: TaskState\n readonly input?: ParkedInput\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? Object.getOwnPropertyDescriptor(value, key)?.value\n : undefined\n}\n\n/** Only the host session, not the global parked index, holds user input. */\nexport function parkedPayload(ctx: RouteContext, token: string): ParkPayload | undefined {\n const data = ctx.sessionManager\n .getBranch()\n .findLast(\n (entry) =>\n entry.type === \"custom\" &&\n entry.customType === PARK_ENTRY &&\n field(entry.data, \"token\") === token,\n )?.data\n if (data === undefined) return undefined\n const state = parseTaskState(field(data, \"state\"))\n if (state === undefined) throw new Error(\"Adaptive parked: state missing\")\n const input = field(data, \"input\")\n if (input === undefined) return { token, state }\n const text = field(input, \"text\")\n if (typeof text !== \"string\") throw new Error(\"Adaptive parked: input.text must be a string\")\n const images = field(input, \"images\")\n if (images === undefined) return { token, state, input: { text } }\n if (!Array.isArray(images)) throw new Error(\"Adaptive parked: input.images must be an array\")\n const parsed: ImageContent[] = images.map((image: unknown) => {\n const data = field(image, \"data\")\n const mimeType = field(image, \"mimeType\")\n if (\n field(image, \"type\") !== \"image\" ||\n typeof data !== \"string\" ||\n typeof mimeType !== \"string\"\n )\n throw new Error(\"Adaptive parked: input.images entry must be an image\")\n return { type: \"image\", data, mimeType }\n })\n return { token, state, input: { text, images: parsed } }\n}\n\nexport function clearParked(ctx: RouteContext): void {\n ctx.ui?.setStatus(\"adaptive\", undefined)\n ctx.ui?.setWidget(\"adaptive\", undefined)\n ctx.ui?.setWorkingMessage()\n}\n\nexport function showParked(ctx: RouteContext, record: Parked): void {\n if (!ctx.hasUI) return\n const when = new Date(record.due).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" })\n const exhausted = record.wakes >= MAX_WAKES\n ctx.ui?.setStatus(\n \"adaptive\",\n `${record.tier} parked · ${exhausted ? \"needs your input\" : `resumes ${when}`}`,\n )\n ctx.ui?.setWidget(\"adaptive\", [\n `Parked: no available ${record.tier} model`,\n exhausted\n ? \"Automatic retries used up · /adaptive resume tries now\"\n : `Resumes ${when} · /adaptive resume tries now`,\n \"Send a message or pick a model to cancel.\",\n ])\n}\n","import type { ExtensionAPI, InputEvent, InputEventResult } from \"@earendil-works/pi-coding-agent\"\nimport type { Api, Model } from \"@earendil-works/pi-ai\"\nimport { CONTINUATION_PROMPT } from \"@coool/adaptive-core/execution/continuation/prompts\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport {\n cancelPark,\n claimPark,\n findPark,\n MAX_WAKES,\n PARK_ENTRY,\n savePark,\n SHORT_WAIT_MS,\n waitUntil,\n WaitCancelled,\n type Parked,\n} from \"../parking.js\"\nimport {\n CONTINUATION_TYPE,\n startTask,\n type Recovery,\n type RoutePlan,\n type TaskState,\n} from \"../task.js\"\nimport type { AdaptiveSources, SettleContext } from \"./extension.js\"\nimport { prepareAdmission, type RouteContext, type RouteParking } from \"./routing.js\"\nimport { selectedVirtual } from \"./tools.js\"\nimport {\n clearParked as clear,\n showParked as card,\n parkedPayload as payload,\n type ParkedInput as Input,\n type ParkPayload as Payload,\n} from \"./parked-view.js\"\nimport type { AdmissionDecision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readPreferences } from \"../preferences.js\"\nimport { recordReceipt } from \"../receipts.js\"\nimport { decisionNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { appendNote } from \"./entries.js\"\nimport type { NoteTracker } from \"./observe.js\"\n\ntype Host = Pick<ExtensionAPI, \"appendEntry\" | \"sendUserMessage\" | \"sendMessage\" | \"getActiveTools\">\ninterface ParkingContext extends RouteContext {\n readonly model: Model<Api> | undefined\n}\ninterface ParkingHandlers extends RouteParking {\n readonly input: (event: InputEvent, ctx: ParkingContext) => Promise<InputEventResult>\n modelSelect(\n model: { readonly provider: string; readonly id: string },\n ctx: RouteContext,\n ): Promise<void>\n sessionStart(ctx: ParkingContext): Promise<void>\n /** `/adaptive resume`: wake this session's parked task now. */\n resume(ctx: RouteContext): Promise<\"resumed\" | \"not-parked\">\n /**\n * Drop the parked record of a wake lineage whose run just finished. Task-id\n * scoped: a park from another task in the same session is left alone.\n */\n clearServed(\n task: string,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<void>\n /** `/adaptive cancel`: drop this session's wait and parked record. */\n cancel(ctx: RouteContext): Promise<\"cancelled\" | \"not-parked\">\n readonly shutdown: () => void\n recover(\n recovery: Recovery,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<boolean>\n}\n/** Session-bound lifecycle; only TUI wakes may outlive their owning handler. */\nexport function parkingHandlers(\n pi: Host,\n sources: AdaptiveSources,\n tracker: NoteTracker = { last: undefined },\n): ParkingHandlers {\n let active: AbortController | undefined\n let disarm: (() => void) | undefined\n let generation = 0\n let resumedInput: TaskState | undefined\n const stop = () => {\n generation += 1\n resumedInput = undefined\n active?.abort()\n active = undefined\n disarm?.()\n disarm = undefined\n }\n /** True when a still-waiting record was dropped. */\n const cancel = async (ctx: RouteContext): Promise<boolean> => {\n stop()\n clear(ctx)\n const session = ctx.sessionManager.getSessionId?.()\n return (\n session !== undefined &&\n ctx.sessionManager.getBranch().some((entry) => entry.customType === PARK_ENTRY) &&\n cancelPark(sources.parking.file, session)\n )\n }\n const noteResume = async (owned: number, tier: RoutePlan[\"tier\"]): Promise<void> => {\n try {\n const { verbosity } = await readPreferences(sources.preferences)\n if (owned !== generation || verbosity === \"quiet\") return\n appendNote(pi, { version: 1, text: `${tier} resumed · retrying parked work` })\n } catch (error) {\n logFailOpen(\"notes\", error)\n }\n }\n const wake = async (\n ctx: RouteContext,\n record: Parked,\n saved: Payload,\n now = sources.parking.clock(),\n manual = false,\n ): Promise<boolean> => {\n const owned = generation\n if (!(await claimPark(sources.parking.file, record, now, manual))) {\n clear(ctx)\n return false\n }\n // Superseded while claiming: whoever bumped the generation owns the session now.\n if (owned !== generation) return false\n clear(ctx)\n if (saved.input !== undefined) {\n resumedInput = { ...saved.state, wakes: record.wakes, wakeToken: record.token }\n const content = [\n { type: \"text\" as const, text: saved.input.text },\n ...(saved.input.images ?? []),\n ]\n pi.sendUserMessage(content, { expandPromptTemplates: false })\n } else {\n pi.sendMessage(\n {\n customType: CONTINUATION_TYPE,\n content: CONTINUATION_PROMPT,\n display: false,\n details: {\n task: saved.state.task,\n token: record.token,\n tier: record.tier,\n escalations: saved.state.escalations,\n restarts: saved.state.restarts,\n wakes: record.wakes,\n wakeToken: record.token,\n tried: [],\n },\n },\n { triggerTurn: true },\n )\n }\n await noteResume(owned, record.tier)\n return true\n }\n const arm = (ctx: RouteContext, record: Parked, saved: Payload) => {\n card(ctx, record)\n if (record.wakes >= MAX_WAKES) return\n const owned = generation\n disarm = sources.parking.timer(\n () => {\n if (owned !== generation) return\n if (sources.parking.clock() < record.due) {\n arm(ctx, record, saved)\n return\n }\n void wake(ctx, record, saved).catch((error: unknown) => {\n logFailOpen(\"parking\", error)\n })\n },\n Math.max(0, Math.min(1_800_000, record.due - sources.parking.clock())),\n )\n }\n const persist = async (ctx: RouteContext, state: TaskState, due: number, input?: Input) => {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) throw new Error(\"Adaptive parked: session id missing\")\n const record: Parked = {\n session,\n token: sources.newId(),\n tier: state.tier,\n due,\n wakes: state.wakes ?? 0,\n claimed: false,\n }\n const saved: Payload = { token: record.token, state, ...(input === undefined ? {} : { input }) }\n // Pi's session is already a user-content store; the shared index is metadata only.\n pi.appendEntry(PARK_ENTRY, saved)\n await savePark(sources.parking.file, record)\n card(ctx, record)\n // Give-up is a terminal event: no auto wake will fire again, so say so once.\n if (record.wakes >= MAX_WAKES) {\n try {\n appendNote(pi, {\n version: 1,\n text: `Gave up after ${String(record.wakes)} failed resumes · /adaptive resume tries now`,\n })\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n return { record, saved }\n }\n const wait = async (ctx: RouteContext, due: number, signal?: AbortSignal) => {\n const controller = new AbortController()\n active = controller\n const combined =\n signal === undefined ? controller.signal : AbortSignal.any([signal, controller.signal])\n try {\n await waitUntil(sources.parking, due, combined, (remaining) => {\n if (!ctx.hasUI) return\n const seconds = Math.ceil(remaining / 1_000)\n const countdown = `${String(Math.floor(seconds / 60))}:${String(seconds % 60).padStart(2, \"0\")}`\n const text = `Waiting for a model · ${countdown} · Esc cancels`\n ctx.ui?.setStatus(\"adaptive\", text)\n ctx.ui?.setWorkingMessage(text)\n })\n } finally {\n if (active === controller) active = undefined\n clear(ctx)\n }\n }\n\n /** Parks are receipted and noted like every other routing decision (ADP-030/058). */\n const parkNote = async (\n session: string,\n tier: RoutePlan[\"tier\"],\n decision: AdmissionDecision,\n unit: string,\n ): Promise<void> => {\n try {\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.parking.clock(),\n sessionID: session,\n unitID: unit,\n tier,\n decision,\n })\n const { verbosity } = await readPreferences(sources.preferences)\n if (!shouldWriteNote(verbosity, decision, tracker.last)) return\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(decision, tier),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = decision\n } catch (error) {\n logFailOpen(\"receipts\", error)\n }\n }\n\n const input = async (event: InputEvent, ctx: ParkingContext): Promise<InputEventResult> => {\n if (event.source === \"extension\") return { action: \"continue\" }\n let parked = false\n const owned = generation + 1\n try {\n await cancel(ctx)\n if (owned !== generation) return { action: \"handled\" }\n const model = ctx.model\n if (model === undefined) return { action: \"continue\" }\n const id = selectedVirtual(model)\n // A virtual selection schedules in every global mode (effectiveMode).\n if (id === undefined || event.streamingBehavior !== undefined) return { action: \"continue\" }\n const prepared = await prepareAdmission(\n id,\n {\n model,\n reason: \"user\",\n thinkingLevel: \"off\",\n messages: [\n {\n role: \"user\",\n timestamp: sources.parking.clock(),\n content: [{ type: \"text\", text: event.text }, ...(event.images ?? [])],\n },\n ],\n },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n )\n const admission = await prepared.choose()\n if (owned !== generation) return { action: \"handled\" }\n if (\n admission.decision.kind !== \"park\" ||\n admission.decision.reason === \"no-candidates\" ||\n admission.due - sources.parking.clock() <= SHORT_WAIT_MS\n )\n return { action: \"continue\" }\n // Pi buffers extension entries until its first conversation message. Let the\n // host persist that message; route() can park before any provider dispatch.\n if (\n !ctx.sessionManager\n .getBranch()\n .some(\n (entry) =>\n entry.type === \"message\" &&\n (entry.message?.role === \"user\" || entry.message?.role === \"assistant\"),\n )\n )\n return { action: \"continue\" }\n const state = startTask(prepared.plan.tier, sources.newId)\n const { record, saved } = await persist(ctx, state, admission.due, {\n text: event.text,\n ...(event.images === undefined ? {} : { images: event.images }),\n })\n await parkNote(record.session, prepared.plan.tier, admission.decision, state.unit)\n parked = true\n if (owned !== generation) return { action: \"handled\" }\n if (ctx.mode === \"tui\") arm(ctx, record, saved)\n else {\n await wait(ctx, record.due, ctx.signal)\n await wake(ctx, record, saved)\n }\n return { action: \"handled\" }\n } catch (error) {\n if (error instanceof WaitCancelled) {\n if (owned === generation) await cancel(ctx)\n } else logFailOpen(\"parking\", error)\n return {\n action:\n parked || error instanceof WaitCancelled || owned !== generation ? \"handled\" : \"continue\",\n }\n }\n }\n const modelSelect: ParkingHandlers[\"modelSelect\"] = async (model, ctx) => {\n if (selectedVirtual(model) !== undefined) return\n try {\n await cancel(ctx)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n const sessionStart: ParkingHandlers[\"sessionStart\"] = async (ctx) => {\n stop()\n if (ctx.mode !== \"tui\" || selectedVirtual(ctx.model) === undefined) return\n try {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) return\n const record = await findPark(sources.parking.file, session)\n if (record === undefined) return\n const saved = payload(ctx, record.token)\n if (saved === undefined) return\n if (record.due <= sources.parking.clock() && record.wakes < MAX_WAKES) {\n if (await ctx.ui?.confirm(\"Parked task\", \"Resume the parked task now?\")) {\n // A person pressing Enter is a manual resume: it bypasses the give-up\n // budget just like /adaptive resume does.\n await wake(ctx, record, saved, record.due, true)\n } else await cancel(ctx)\n } else arm(ctx, record, saved)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n const resume: ParkingHandlers[\"resume\"] = async (ctx) => {\n const session = ctx.sessionManager.getSessionId?.()\n const record = session === undefined ? undefined : await findPark(sources.parking.file, session)\n const saved = record === undefined ? undefined : payload(ctx, record.token)\n if (record === undefined || saved === undefined) return \"not-parked\"\n stop()\n // Resuming early is a request to try again now; routing parks again if the tier is still\n // blocked. Manual resume bypasses the automatic give-up budget — the person decided.\n return (await wake(ctx, record, saved, record.due, true)) ? \"resumed\" : \"not-parked\"\n }\n const clearServed = async (\n task: string,\n ctx: SettleContext & Pick<RouteContext, \"mode\" | \"signal\" | \"ui\">,\n ): Promise<void> => {\n try {\n const session = ctx.sessionManager.getSessionId?.()\n if (session === undefined) return\n const record = await findPark(sources.parking.file, session)\n if (record === undefined) return\n const saved = payload(ctx, record.token)\n // Another task's park stays parked; only the served lineage is stale now.\n if (saved?.state.task !== task) return\n stop()\n clear(ctx)\n await cancelPark(sources.parking.file, session)\n } catch (error) {\n logFailOpen(\"parking\", error)\n }\n }\n return {\n input,\n modelSelect,\n sessionStart,\n resume,\n clearServed,\n cancel: async (ctx) => ((await cancel(ctx)) ? \"cancelled\" : \"not-parked\"),\n shutdown: stop,\n async recover(recovery, ctx) {\n const id = selectedVirtual(ctx.model)\n const model = ctx.modelRegistry.getAvailable()[0]\n if (id === undefined || model === undefined) return false\n let parked = false\n const owned = generation\n try {\n const state: TaskState = {\n version: 1,\n task: recovery.task,\n unit: sources.newId(),\n tier: recovery.tier,\n escalations: recovery.escalations,\n restarts: recovery.restarts,\n wakes: recovery.wakes ?? 0,\n ...(recovery.wakeToken === undefined ? {} : { wakeToken: recovery.wakeToken }),\n tried: recovery.tried,\n }\n const prepared = await prepareAdmission(\n id,\n { model, reason: \"user\", thinkingLevel: \"off\", messages: [] },\n ctx,\n sources,\n () => pi.getActiveTools(),\n true,\n state,\n )\n const admission = await prepared.choose()\n if (owned !== generation) return true\n if (\n admission.decision.kind !== \"park\" ||\n admission.decision.reason === \"no-candidates\" ||\n admission.due - sources.parking.clock() <= SHORT_WAIT_MS\n )\n return false\n const { record, saved } = await persist(ctx, state, admission.due)\n await parkNote(record.session, prepared.plan.tier, admission.decision, state.unit)\n parked = true\n if (owned !== generation) return true\n if (ctx.mode === \"tui\" || record.wakes >= MAX_WAKES) arm(ctx, record, saved)\n else {\n await wait(ctx, record.due, ctx.signal)\n await wake(ctx, record, saved)\n }\n return true\n } catch (error) {\n if (error instanceof WaitCancelled) {\n if (owned === generation) await cancel(ctx)\n } else logFailOpen(\"parking\", error)\n return parked || owned !== generation\n }\n },\n takeInput() {\n const state = resumedInput\n resumedInput = undefined\n return state\n },\n async blocked(plan, admission, request, ctx): Promise<RoutePlan | undefined> {\n const state = plan.state\n if (request.reason === \"direct\" || state === undefined) return undefined\n const owned = generation\n try {\n if (admission.due - sources.parking.clock() <= SHORT_WAIT_MS) {\n await wait(ctx, admission.due, request.signal)\n return plan\n }\n const { record, saved } = await persist(ctx, state, admission.due)\n if (owned !== generation) return undefined\n // A throwing route never commits its returned state. Save it before parking\n // so an owned hidden continuation can consume the wake token after restart.\n pi.appendEntry(\"pi.virtual-model-state\", {\n provider: \"adaptive\",\n modelId: request.model.id,\n state,\n })\n await parkNote(record.session, plan.tier, admission.decision, state.unit)\n if (ctx.mode === \"tui\" || record.wakes >= MAX_WAKES) {\n arm(ctx, record, saved)\n return undefined\n }\n await wait(ctx, record.due, request.signal)\n if (!(await claimPark(sources.parking.file, record, sources.parking.clock())))\n return undefined\n await noteResume(owned, record.tier)\n if (owned !== generation) return undefined\n return {\n ...plan,\n state: {\n ...state,\n unit: sources.newId(),\n wakes: record.wakes,\n wakeToken: record.token,\n hops: 0,\n tried: [],\n },\n }\n } catch (error) {\n if (error instanceof WaitCancelled && owned === generation) await cancel(ctx)\n throw error\n }\n },\n }\n}\n","import { isDeepStrictEqual } from \"node:util\"\nimport { parseHealthPayload } from \"@coool/adaptive-core/state/health/parse\"\nimport { resourceChain, resourceKeyID } from \"@coool/adaptive-core/health/resource-health/key\"\nimport type { ResourceRecord } from \"@coool/adaptive-core/health/resource-health/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { JsonFile } from \"./store.js\"\n\nexport function parseSharedHealth(raw: unknown): ResourceRecord[] {\n if (raw === undefined) return []\n const records = parseHealthPayload(raw)\n if (!isDeepStrictEqual(raw, { version: 1, records }))\n throw new Error(\"Adaptive health: invalid health.json payload\")\n return records\n}\n\nexport async function readSharedHealth(file: Pick<JsonFile, \"read\">): Promise<ResourceRecord[]> {\n return parseSharedHealth(await file.read())\n}\n\n/** Explicit reset also clears inherited blockers; the UI warns that siblings may be affected. */\nexport function resetResourceHealth(file: JsonFile, ref: ModelRef): Promise<void> {\n return file.update((current) => {\n const chain = new Set(\n resourceChain({ providerID: ref.providerID, modelID: ref.id, variantID: ref.variant }).map(\n resourceKeyID,\n ),\n )\n const records = parseSharedHealth(current).filter(\n (record) => !chain.has(resourceKeyID(record.key)),\n )\n return { next: { version: 1, records }, result: undefined }\n })\n}\n","import type { HostCopy, HostDeferReason } from \"@coool/adaptive-core/flow/host-copy\"\nimport type { ParkReason } from \"@coool/adaptive-core/routing/scheduler/types\"\n\nconst defer: Record<HostDeferReason, string> = {\n \"routing-defer\":\n \"No routing rule applied. Pi keeps the manual model; an Adaptive entry needs a compatible configured model in its tier.\",\n \"adaptive-off\": \"Adaptive is off. Pi keeps your selected model.\",\n \"pin-unverifiable\":\n \"The pinned resource is not available in Pi. Check credentials or change the pin in /adaptive.\",\n \"pin-incompatible\":\n \"The pinned resource cannot handle this request. Change the pin or tier in /adaptive.\",\n}\nconst park: Record<ParkReason, string> = {\n \"all-blocked\":\n \"Every model in the required tier is unavailable. Work waits for recovery; /adaptive resume or cancel manages the wait.\",\n \"no-candidates\": \"This tier has no configured models. Open /adaptive tiers to add one.\",\n \"no-compatible-resource\":\n \"No configured model fits this request. Check context, inputs and tool capabilities with /adaptive doctor.\",\n \"pin-blocked\":\n \"Your pinned resource is unavailable. Adaptive does not silently replace a pin; change it in /adaptive.\",\n}\n\nexport const PI_COPY: HostCopy = {\n inviteTitle: \"Pi Adaptive\",\n modelSearchPlaceholder: \"Search Pi models\",\n receiptExplanation: (reason) => defer[reason],\n parkExplanation: (reason) => park[reason],\n}\n","/**\n * Status-view helpers (ADP-033): flatten the status snapshot into one page\n * showing every configured model with its state, grouped by tier in priority\n * order. Pure and deterministic; local wall-clock rendering is derived from\n * the snapshot's own timestamps.\n */\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot, TierResourceStatus } from \"../status.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\n/** Configured resources in tier order (quick → standard → advanced). */\nexport function healthEntries(\n snapshot: StatusSnapshot,\n): { tier: TierName; status: TierResourceStatus }[] {\n const entries: { tier: TierName; status: TierResourceStatus }[] = []\n for (const tier of TIERS) {\n for (const status of snapshot.tiers[tier]) entries.push({ tier, status })\n }\n return entries\n}\n\n/** Local date and time: quota windows may reset days or weeks from now. */\nexport function clockTime(until: number): string {\n const at = new Date(until)\n const hours = String(at.getHours()).padStart(2, \"0\")\n const minutes = String(at.getMinutes()).padStart(2, \"0\")\n const month = String(at.getMonth() + 1).padStart(2, \"0\")\n const day = String(at.getDate()).padStart(2, \"0\")\n return `${String(at.getFullYear())}-${month}-${day} ${hours}:${minutes}`\n}\n\nfunction pinnedTo(ref: TierResourceStatus[\"ref\"], pin: StatusSnapshot[\"pin\"]): boolean {\n if (pin === null) return false\n return pin.providerID === ref.providerID && pin.id === ref.id && pin.variant === ref.variant\n}\n\n/** Everything after the health state: capacity usage, window, breaker, pin. */\nfunction stateSuffix(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n let suffix = \"\"\n if (status.windowed) {\n suffix +=\n status.windowUntil === null\n ? \", windowed (deadline unknown)\"\n : `, windowed until ${clockTime(status.windowUntil)}`\n }\n if (status.usedPercent !== null) {\n suffix += `, used ${String(status.usedPercent)}%`\n if (status.resetAt !== null) suffix += `, resets ${clockTime(status.resetAt)}`\n }\n if (status.breaker === \"open\") suffix += \", breaker open\"\n else if (status.breaker === \"half_open\") suffix += \", probing\"\n if (pinnedTo(status.ref, pin)) suffix += \" (pinned)\"\n return suffix\n}\n\n/** The STATE column of the status table: window, breaker, pin markers. */\nexport function stateCell(status: TierResourceStatus, pin: StatusSnapshot[\"pin\"]): string {\n return stateSuffix(status, pin).replace(/^[, ]+/, \"\") || \"-\"\n}\n\n/**\n * The whole inventory as a column-aligned table (header row first): models\n * grouped in tier order (quick → standard → advanced), one row per model,\n * columns padded to the widest cell so the grid reads at a glance. There is\n * no per-resource selection step: the table IS the view.\n */\nexport function statusTable(snapshot: StatusSnapshot): string[] {\n const header = [\"MODEL\", \"TIER\", \"HEALTH\", \"STATE\"]\n const rows = healthEntries(snapshot).map(({ tier, status }) => [\n resourceLabel(status.ref),\n tier,\n status.health,\n stateCell(status, snapshot.pin),\n ])\n // Header and rows are built together, always four cells wide — the column\n // index cannot be out of range.\n const widths = header.map((cell, column) =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n Math.max(cell.length, ...rows.map((row) => row[column]!.length)),\n )\n const render = (cells: string[]): string =>\n cells\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map((cell, column) => cell.padEnd(widths[column]!))\n .join(\" \")\n .trimEnd()\n return [render(header), ...rows.map(render)]\n}\n\n/** Narrow hosts keep health and capacity visible instead of clipping wide model columns. */\nexport function compactStatus(snapshot: StatusSnapshot): string[] {\n return healthEntries(snapshot).flatMap(({ tier, status }) => [\n resourceLabel(status.ref),\n `${tier} · ${status.health}`,\n ...stateCell(status, snapshot.pin)\n .split(\", \")\n .map((part) => ` ${part}`),\n \"\",\n ])\n}\n\n/** Empty-state copy for the status view when nothing is configured. */\nexport const STATUS_EMPTY_MESSAGE = \"No models configured yet — open Models to add some.\"\n","export interface ToolCapability {\n readonly providerID: string\n readonly id: string\n readonly tools: boolean\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nexport async function loadToolCapabilities(\n path: string,\n read: (path: string) => Promise<string>,\n): Promise<readonly ToolCapability[]> {\n let text: string\n try {\n text = await read(path)\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return []\n throw error\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n throw new Error(\"Adaptive capabilities: invalid JSON\")\n }\n return parseToolCapabilities(raw)\n}\n\nexport function parseToolCapabilities(raw: unknown): readonly ToolCapability[] {\n if (\n !(object(raw) && Array.isArray(raw[\"models\"])) ||\n Object.keys(raw).some((key) => key !== \"models\")\n )\n throw new Error(\"Adaptive capabilities.models: expected an array in a models-only object\")\n const seen = new Set<string>()\n return raw[\"models\"].map((entry: unknown, index: number) => {\n const field = `Adaptive capabilities.models[${String(index)}]`\n if (!object(entry)) throw new Error(`${field}: expected an object`)\n const providerID = entry[\"providerID\"]\n const id = entry[\"id\"]\n const tools = entry[\"tools\"]\n if (typeof providerID !== \"string\" || providerID.trim().length === 0)\n throw new Error(`${field}.providerID: expected a non-empty string`)\n if (typeof id !== \"string\" || id.trim().length === 0)\n throw new Error(`${field}.id: expected a non-empty string`)\n if (typeof tools !== \"boolean\") throw new Error(`${field}.tools: expected a boolean`)\n if (Object.keys(entry).some((key) => ![\"providerID\", \"id\", \"tools\"].includes(key)))\n throw new Error(`${field}: unknown field`)\n const key = JSON.stringify([providerID, id])\n if (seen.has(key)) throw new Error(`${field}: duplicate model`)\n seen.add(key)\n return { providerID, id, tools }\n })\n}\n\nexport function updateToolCapability(file: JsonFile, ref: ModelRef, tools: boolean): Promise<void> {\n return file.update((current) => {\n const entries = current === undefined ? [] : parseToolCapabilities(current)\n const entry = { providerID: ref.providerID, id: ref.id, tools }\n const models = [\n ...entries.filter((model) => model.providerID !== ref.providerID || model.id !== ref.id),\n entry,\n ]\n parseToolCapabilities({ models })\n return { next: { models }, result: undefined }\n })\n}\nimport type { JsonFile } from \"./store.js\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\n","import type { AdaptiveView } from \"@coool/adaptive-core/flow/controller\"\nimport { STATUS_EMPTY_MESSAGE } from \"@coool/adaptive-core/flow/status\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { JsonFile } from \"../store.js\"\nimport { NOTE_VERBOSITIES, readPreferences, updatePreferences } from \"../preferences.js\"\nimport { updateToolCapability, type ToolCapability } from \"../capabilities.js\"\n\nexport const DEFAULT_MODEL_HELP =\n 'In Pi settings.json, set:\\n{\\n \"defaultProvider\": \"adaptive\",\\n \"defaultModel\": \"auto\"\\n}\\nPi exposes no extension API to save this default. Your current model is unchanged.'\n\nexport async function preferencesAction(view: AdaptiveView, file: JsonFile): Promise<void> {\n const current = await readPreferences(file)\n const choice = await view.select({\n title: \"Preferences\",\n options: [\n { title: `Transcript notes: ${current.verbosity}`, value: \"notes\" },\n {\n title: `Escalate from a pinned tier: ${current.escalateFromPinned ? \"on\" : \"off\"}`,\n value: \"escalate\",\n },\n ],\n })\n if (choice === \"notes\") {\n const verbosity = await view.select({\n title: \"Transcript notes\",\n options: NOTE_VERBOSITIES.map((value) => ({ title: value, value })),\n })\n if (verbosity === undefined) return\n await updatePreferences(file, { verbosity })\n } else if (choice === \"escalate\") {\n const confirmed = await view.confirm({\n title: \"Change pinned-tier escalation?\",\n message: current.escalateFromPinned\n ? \"Stop automatic capability escalation from pinned tiers?\"\n : \"Allow a failed task to move one tier above your pin, only with capability evidence and within the task budget?\",\n })\n if (confirmed !== true) return\n await updatePreferences(file, { escalateFromPinned: !current.escalateFromPinned })\n } else return\n view.toast(\"Preferences saved\", \"success\")\n}\n\nfunction declaredLabel(declared: readonly ToolCapability[], ref: ModelRef): string {\n const entry = declared.find((model) => model.providerID === ref.providerID && model.id === ref.id)\n if (entry === undefined) return \"not declared · skipped on tool turns\"\n return entry.tools ? \"calls tools\" : \"no tool calls\"\n}\n\n/**\n * Pi's catalog does not say which models call tools, and Adaptive never\n * guesses from a name: an undeclared model is skipped on every tool turn.\n */\nexport async function toolSupportAction(\n view: AdaptiveView,\n file: JsonFile,\n models: readonly ModelRef[],\n declared: readonly ToolCapability[],\n): Promise<void> {\n // Tool support is declared per model, not per variant.\n const unique = [\n ...new Map(\n models.map((model) => [\n `${model.providerID}/${model.id}`,\n { providerID: model.providerID, id: model.id },\n ]),\n ),\n ]\n if (unique.length === 0) {\n await view.alert({ title: \"Tool support\", message: STATUS_EMPTY_MESSAGE })\n return\n }\n const ref = await view.select({\n title: \"Tool support · select a model\",\n options: unique.map(([label, model]) => ({\n title: label,\n value: model,\n description: declaredLabel(declared, model),\n })),\n })\n if (ref === undefined) return\n const tools = await view.select({\n title: `${ref.providerID}/${ref.id}`,\n options: [\n { title: \"Calls tools\", value: true, description: \"eligible for tool turns\" },\n { title: \"No tool calls\", value: false, description: \"never routed to on tool turns\" },\n ],\n })\n if (tools === undefined) return\n if (\n !(await view.confirm({\n title: \"Confirm tool capability\",\n message: `${ref.providerID}/${ref.id}: record tool support as ${tools ? \"supported\" : \"unsupported\"}? Only confirm this from provider documentation or a verified request.`,\n }))\n )\n return\n await updateToolCapability(file, ref, tools)\n view.toast(\"Tool capability saved\", \"success\")\n}\n","/**\n * Doctor report (ADP-062): host checks plus the checks every host can derive\n * from the status snapshot, rendered problems-first so the first screen\n * answers \"is anything wrong, and what do I do\".\n */\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot } from \"../status.js\"\nimport { healthEntries } from \"./status.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\nexport interface DoctorCheck {\n readonly state: \"ok\" | \"warning\" | \"error\"\n readonly message: string\n /** Absent (never undefined): checks cross the RPC boundary as JSON. */\n readonly action?: string\n}\n\nfunction plural(count: number, noun: string): string {\n return `${String(count)} ${noun}${count === 1 ? \"\" : \"s\"}`\n}\n\n/** Empty tiers, limited models and parked work, from one status snapshot. */\nexport function statusChecks(snapshot: StatusSnapshot): DoctorCheck[] {\n const empty: DoctorCheck[] = TIERS.filter((tier) => snapshot.tiers[tier].length === 0).map(\n (tier) => ({\n state: \"warning\",\n message: `${tier}: no configured models`,\n action: \"Open /adaptive tiers to add a model.\",\n }),\n )\n // A model listed in two tiers is one resource with one health state.\n const limited = new Set(\n healthEntries(snapshot)\n .filter(({ status }) => status.health !== \"healthy\")\n .map(({ status }) => resourceLabel(status.ref)),\n ).size\n return [\n ...empty,\n limited === 0\n ? { state: \"ok\", message: \"Health: no models limited\" }\n : {\n state: \"ok\",\n message: `Health: ${plural(limited, \"model\")} limited`,\n action: \"Inspect /adaptive health; reset only after checking the provider.\",\n },\n snapshot.parked === 0\n ? { state: \"ok\", message: \"No parked work\" }\n : {\n state: \"ok\",\n message: plural(snapshot.parked, \"parked task\"),\n action: \"Use /adaptive resume or /adaptive cancel in the waiting session.\",\n },\n ]\n}\n\nconst LABELS: Record<DoctorCheck[\"state\"], string> = { ok: \"OK\", warning: \"CHECK\", error: \"FIX\" }\n\nconst SEVERITY: readonly DoctorCheck[\"state\"][] = [\"error\", \"warning\", \"ok\"]\n\n/** Problems first: the first screen answers \"is anything wrong, and what do I do\". */\nexport function doctorLines(checks: readonly DoctorCheck[]): string[] {\n const count = (state: DoctorCheck[\"state\"]) =>\n checks.filter((check) => check.state === state).length\n const problems = count(\"error\") + count(\"warning\")\n return [\n problems === 0\n ? `All ${String(checks.length)} checks OK`\n : `${String(count(\"error\"))} to fix · ${String(count(\"warning\"))} to check · ${String(count(\"ok\"))} OK`,\n ...SEVERITY.flatMap((state) => checks.filter((check) => check.state === state)).flatMap(\n (check) => [\n `${LABELS[check.state]} ${check.message}`,\n ...(check.action === undefined ? [] : [` ${check.action}`]),\n ],\n ),\n ]\n}\n","import type { StatusSnapshot } from \"../status.js\"\n\n/** How often a view re-reads parked sessions: wakes land at second granularity, a few seconds' lag is fine. */\nexport const WAITING_POLL_MS = 10_000\n\nconst DAY_MS = 24 * 60 * 60_000\nconst WEEK_DAYS = 6\n\n/** Parked sessions by id, mapped to when their tier is next expected to be usable (null = unknown). */\nexport function waitingSessions(snapshot: StatusSnapshot): Record<string, number | null> {\n const sessions: Record<string, number | null> = {}\n for (const entry of snapshot.waiting) sessions[entry.sessionID] = entry.resumeAt\n return sessions\n}\n\nfunction startOfDay(at: number): number {\n const date = new Date(at)\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()\n}\n\nfunction clock(date: Date): string {\n return `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`\n}\n\n/**\n * Short human text for a parked session (ADP-024): \"waiting · resumes 18:42\". Weekly limits reset days away, so\n * a later day gains its weekday, and beyond a week its date. Local fields, not the locale formatter, keep the\n * text identical across hosts.\n */\nexport function waitingLabel(resumeAt: number | null, now: number): string {\n if (resumeAt === null) return \"waiting\"\n if (resumeAt <= now) return \"waiting · resuming\"\n const date = new Date(resumeAt)\n // Calendar days, not elapsed time: 01:00 tomorrow is \"Sun 01:00\" even when it is only two hours away.\n const days = Math.round((startOfDay(resumeAt) - startOfDay(now)) / DAY_MS)\n if (days === 0) return `waiting · resumes ${clock(date)}`\n // toDateString is spec-fixed (\"Sat Nov 07 2026\"), unlike toLocaleString.\n const day = date.toDateString()\n if (days <= WEEK_DAYS) return `waiting · resumes ${day.slice(0, 3)} ${clock(date)}`\n return `waiting · resumes ${day.slice(4, 7)} ${String(date.getDate())} ${clock(date)}`\n}\n","/**\n * Local operations behind the `/adaptive` menu and subcommands (ADP-062):\n * health reset, parked work and the doctor report. Hosts wire only what they\n * support; the dialogs and outcome copy live here so every host reads alike.\n */\nimport type { ModelRef } from \"../routing/work-unit/types.js\"\nimport type { TierResourceStatus } from \"../status.js\"\nimport type { AdaptiveEnv } from \"./controller.js\"\nimport { doctorLines, type DoctorCheck } from \"./doctor.js\"\nimport { healthEntries, STATUS_EMPTY_MESSAGE, stateCell } from \"./status.js\"\nimport { resourceLabel } from \"./tiers.js\"\nimport { waitingLabel } from \"./waiting.js\"\n\n/** `waiting`: a manual resume found the tier still unavailable and stays parked. */\nexport type ResumeOutcome = \"resumed\" | \"waiting\" | \"not-parked\"\nexport type CancelOutcome = \"cancelled\" | \"not-parked\"\n\nexport interface AdaptiveActions {\n /** Mark a model healthy again, with its inherited provider limits. */\n readonly resetHealth?: (model: ModelRef) => Promise<void>\n /** Try the session's parked work now, bypassing the automatic give-up budget. */\n readonly resume?: (sessionID: string) => Promise<ResumeOutcome>\n /** Drop the session's wait and parked record. */\n readonly cancel?: (sessionID: string) => Promise<CancelOutcome>\n /** Declare which models can call tools, where the host catalog does not say. */\n readonly tools?: () => Promise<void>\n readonly doctor?: () => Promise<readonly DoctorCheck[]>\n readonly preferences?: () => Promise<void>\n readonly defaults?: () => Promise<void>\n}\n\nconst PARKED_TITLE = \"Parked work\"\nconst NOTHING_PARKED = \"Nothing is parked in this session.\"\nconst OPEN_SESSION = \"Open the waiting session and run /adaptive there to resume or cancel it.\"\n\n/** Pick a configured model, confirm, reset. Lists each model once, with its state. */\nexport async function runHealthReset(\n env: AdaptiveEnv,\n reset: (model: ModelRef) => Promise<void>,\n): Promise<void> {\n const snapshot = await env.api.status()\n const models = new Map<string, TierResourceStatus>()\n for (const { status } of healthEntries(snapshot)) models.set(resourceLabel(status.ref), status)\n if (models.size === 0) {\n await env.view.alert({ title: \"Health\", message: STATUS_EMPTY_MESSAGE })\n return\n }\n const model = await env.view.select({\n title: \"Health · select a model to reset\",\n options: [...models].map(([label, status]) => {\n const state = stateCell(status, snapshot.pin)\n return {\n title: label,\n value: status.ref,\n description: state === \"-\" ? status.health : `${status.health} · ${state}`,\n }\n }),\n })\n if (model === undefined) return\n const label = resourceLabel(model)\n const confirmed = await env.view.confirm({\n title: \"Reset model health?\",\n message: `Reset ${label} and its inherited provider limits? Other models on this provider may be affected. This does not restore actual provider quota.`,\n })\n if (confirmed !== true) return\n await reset(model)\n env.view.toast(\"Health reset\", \"success\")\n}\n\n/** Resume this session's parked work. True when the run continues and the menu should close. */\nexport async function resumeHere(\n env: AdaptiveEnv,\n resume: (sessionID: string) => Promise<ResumeOutcome>,\n): Promise<boolean> {\n if (env.sessionID === undefined) {\n await env.view.alert({ title: PARKED_TITLE, message: OPEN_SESSION })\n return false\n }\n const outcome = await resume(env.sessionID)\n switch (outcome) {\n case \"resumed\":\n env.view.toast(\"Resuming parked work\", \"success\")\n return true\n case \"waiting\":\n await env.view.alert({\n title: PARKED_TITLE,\n message: \"No model in this tier is available yet. Adaptive keeps waiting and retries.\",\n })\n return false\n case \"not-parked\":\n await env.view.alert({ title: PARKED_TITLE, message: NOTHING_PARKED })\n return false\n }\n}\n\n/** Drop this session's parked work. */\nexport async function cancelHere(\n env: AdaptiveEnv,\n cancel: (sessionID: string) => Promise<CancelOutcome>,\n): Promise<void> {\n if (env.sessionID === undefined) {\n await env.view.alert({ title: PARKED_TITLE, message: OPEN_SESSION })\n return\n }\n if ((await cancel(env.sessionID)) === \"cancelled\")\n env.view.toast(\"Parked work cancelled\", \"success\")\n else await env.view.alert({ title: PARKED_TITLE, message: NOTHING_PARKED })\n}\n\n/**\n * Waiting sessions, then what to do with this session's wait. Other sessions\n * are listed but act only from inside: a host can only continue the session\n * it runs in. True when a resumed run continues and the menu should close.\n */\nexport async function runParkedWork(env: AdaptiveEnv, actions: AdaptiveActions): Promise<boolean> {\n const { waiting } = await env.api.status()\n if (waiting.length === 0) {\n await env.view.alert({ title: PARKED_TITLE, message: \"No parked work.\" })\n return false\n }\n const now = (env.clock ?? Date.now)()\n const picked = await env.view.select({\n title: PARKED_TITLE,\n options: waiting.map((entry) => ({\n title: entry.sessionID === env.sessionID ? \"This session\" : entry.sessionID,\n value: entry.sessionID,\n description: `${entry.tier} · ${waitingLabel(entry.resumeAt, now)}`,\n })),\n })\n if (picked === undefined) return false\n if (picked !== env.sessionID) {\n await env.view.alert({ title: PARKED_TITLE, message: OPEN_SESSION })\n return false\n }\n const { resume, cancel } = actions\n const run = await env.view.select<() => Promise<boolean>>({\n title: \"This session's parked work\",\n options: [\n ...(resume === undefined\n ? []\n : [\n {\n title: \"Resume now\",\n value: () => resumeHere(env, resume),\n description: \"try the tier again\",\n },\n ]),\n ...(cancel === undefined\n ? []\n : [\n {\n title: \"Cancel\",\n value: async () => {\n await cancelHere(env, cancel)\n return false\n },\n description: \"drop the wait; your next prompt starts fresh\",\n },\n ]),\n ],\n })\n return run === undefined ? false : run()\n}\n\nexport async function runDoctor(\n env: AdaptiveEnv,\n doctor: () => Promise<readonly DoctorCheck[]>,\n): Promise<void> {\n await env.view.table({ title: \"Adaptive doctor\", lines: doctorLines(await doctor()) })\n}\n","/**\n * Main-menu and mode-menu view models for `/adaptive` (ADP-033): pure data\n * that the controller feeds into `ui.dialog.select`. Descriptions are dynamic\n * where state makes them more informative (health counters, tier contents).\n */\nimport { OPERATING_MODES } from \"../routing/scheduler/types.js\"\nimport type { OperatingMode } from \"../routing/scheduler/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { StatusSnapshot } from \"../status.js\"\nimport type { SettingsV1 } from \"../state/settings/index.js\"\nimport type { SelectOption } from \"./options.js\"\nimport { resourceLabel } from \"./tiers.js\"\n\nexport const MAIN_MENU_ITEMS = [\"status\", \"models\", \"mode\", \"tier\", \"pin\", \"receipts\"] as const\nexport type MainMenuChoice = (typeof MAIN_MENU_ITEMS)[number]\n\n/** \"3 resources · 1 windowed\" — the status line under the menu entry. */\nexport function statusSummary(status: StatusSnapshot | undefined): string {\n if (status === undefined) return \"how every configured model is doing\"\n const total = TIERS.reduce((sum, tier) => sum + status.tiers[tier].length, 0)\n if (total === 0) return \"no models configured yet\"\n const windowed = TIERS.reduce(\n (sum, tier) => sum + status.tiers[tier].filter((entry) => entry.windowed).length,\n 0,\n )\n const windowedNote = windowed === 0 ? \"\" : ` · ${String(windowed)} windowed`\n return `${String(total)} resource${total === 1 ? \"\" : \"s\"}${windowedNote}`\n}\n\n/** \"quick: 1 · standard: 0 · advanced: 2\" — what is configured where. */\nexport function modelsSummary(settings: SettingsV1): string {\n const parts = TIERS.map((tier: TierName) => `${tier}: ${String(settings.tiers[tier].length)}`)\n return parts.join(\" · \")\n}\n\nfunction tierRequestDescription(tierRequest: TierName | null | undefined): string {\n if (tierRequest === undefined) return \"pin a tier for the current session\"\n if (tierRequest === null) return \"not pinned — the routing ladder decides\"\n return `pinned to ${tierRequest} — steers this session`\n}\n\nfunction modeMarker(\n mode: OperatingMode,\n input: { override: OperatingMode | null; effective: OperatingMode },\n): \"override\" | \"current\" | undefined {\n if (mode === input.override) return \"override\"\n if (mode === input.effective) return \"current\"\n return undefined\n}\n\nexport function mainMenuOptions(\n settings: SettingsV1,\n status: StatusSnapshot | undefined,\n tierRequest?: TierName | null,\n effectiveMode: OperatingMode = settings.mode,\n): SelectOption<MainMenuChoice>[] {\n const optionFor = (item: MainMenuChoice): SelectOption<MainMenuChoice> => {\n switch (item) {\n case \"status\":\n return {\n title: \"Status\",\n value: item,\n description: statusSummary(status),\n }\n case \"models\":\n return {\n title: \"Models\",\n value: item,\n description: modelsSummary(settings),\n }\n case \"mode\":\n return {\n title: \"Mode\",\n value: item,\n description: `currently ${effectiveMode}`,\n }\n case \"tier\":\n return {\n title: \"Tier\",\n value: item,\n description: tierRequestDescription(tierRequest),\n }\n case \"pin\":\n return {\n title: \"Pin\",\n value: item,\n description:\n settings.pin === null\n ? \"force one resource\"\n : `pinned to ${resourceLabel(settings.pin)}`,\n }\n case \"receipts\":\n return { title: \"Receipts\", value: item, description: \"why each turn ran the model it ran\" }\n }\n }\n return MAIN_MENU_ITEMS.map(optionFor)\n}\n\nexport function modeOptions(current: OperatingMode): SelectOption<OperatingMode>[] {\n return OPERATING_MODES.map((mode) => ({\n title: mode === current ? `${mode} (current)` : mode,\n value: mode,\n description: modeDescription(mode),\n }))\n}\n\n/** What one mode does — shared by the global and the per-session menus. */\nexport function modeDescription(mode: OperatingMode): string {\n switch (mode) {\n case \"off\":\n return \"Adaptive does nothing\"\n case \"observe\":\n return \"Record decisions without applying them\"\n case \"active\":\n return \"Apply routing and recovery decisions\"\n }\n}\n\n/** One per-session mode-menu pick: follow the global mode, or set an override. */\nexport type SessionModeChoice = { kind: \"global\" } | { kind: \"mode\"; mode: OperatingMode }\n\n/** Which mode the user steers inside a session: the global default or the session override. */\nexport type ModeTarget = \"global\" | \"session\"\n\n/**\n * The first select of the in-session mode flow (ADP-054): ask which mode to\n * steer before showing any mode list — the global default or this session's\n * override. Each row names the current value so the user can tell at a\n * glance which side needs changing.\n */\nexport function modeTargetOptions(\n global: OperatingMode,\n effective: OperatingMode,\n): SelectOption<ModeTarget>[] {\n return [\n {\n title: \"Global mode…\",\n description: `applies to every session without an override (now ${global})`,\n value: \"global\",\n },\n {\n title: \"This session…\",\n description: `override for this session only (now ${effective})`,\n value: \"session\",\n },\n ]\n}\n\n/**\n * The per-session mode menu (ADP-054): first \"Follow global\" (clearing the\n * override), then every mode. An existing override is marked \"(override)\" —\n * distinct from the effective mode's \"(current)\" — so the user can tell a\n * set override apart from a session merely inheriting the global mode.\n */\nexport function sessionModeOptions(input: {\n global: OperatingMode\n override: OperatingMode | null\n effective: OperatingMode\n}): SelectOption<SessionModeChoice>[] {\n const options: SelectOption<SessionModeChoice>[] = [\n {\n title: `Follow global (${input.global})`,\n description: \"clear this session's override\",\n value: { kind: \"global\" },\n },\n ]\n for (const mode of OPERATING_MODES) {\n const marker = modeMarker(mode, input)\n options.push({\n title: marker === undefined ? mode : `${mode} (${marker})`,\n value: { kind: \"mode\", mode },\n description: modeDescription(mode),\n })\n }\n return options\n}\n\n/** What one tier is for — shared by the tier editor and the per-session menu. */\nfunction tierDescription(tier: TierName): string {\n switch (tier) {\n case \"quick\":\n return \"routine edits, mechanical steps\"\n case \"standard\":\n return \"the default\"\n case \"advanced\":\n return \"multi-step design, broad refactors\"\n }\n}\n\n/** One per-session tier-menu pick: follow the routing ladder, or pin a tier. */\nexport type SessionTierChoice = { kind: \"ladder\" } | { kind: \"tier\"; tier: TierName }\n\n/**\n * The per-session tier menu (ADP-055): first \"Follow routing ladder\" (clearing\n * the request), then every tier. A pinned request is marked \"(pinned)\" so the\n * user can tell the sticky request apart from the ordinary ladder.\n */\nexport function sessionTierOptions(input: {\n pinned: TierName | null\n}): SelectOption<SessionTierChoice>[] {\n const options: SelectOption<SessionTierChoice>[] = [\n {\n title: \"Follow routing ladder\",\n description: \"clear this session's tier request\",\n value: { kind: \"ladder\" },\n },\n ]\n for (const tier of TIERS) {\n options.push({\n title: tier === input.pinned ? `${tier} (pinned)` : tier,\n value: { kind: \"tier\", tier },\n description: tierDescription(tier),\n })\n }\n return options\n}\n","/**\n * Shared option shapes for the dialog-driven /adaptive flow (TUI and GUI). These mirror the subset of\n * the host `ui.dialog.select` contract the Adaptive flows use; `tui.tsx` and `gui.tsx` adapt\n * them to the real plugin types (structural superset).\n */\nexport interface SelectOption<Value> {\n readonly title: string\n readonly value: Value\n readonly description?: string\n}\n\n/** Friendly one-line rendering of an API failure for toasts. */\nexport function errorText(error: unknown): string {\n if (error instanceof Error) return error.message\n // RPC failures surface as plain objects ({type, message}); String() would\n // render \"[object Object]\" and throw away the only diagnostic the user gets.\n if (typeof error === \"object\" && error !== null) {\n const message = (error as { message?: unknown }).message\n if (typeof message === \"string\" && message.length > 0) return message\n // JSON.stringify throws on BigInt values, which host payloads can carry;\n // stringify them as strings instead of losing the whole diagnostic.\n return JSON.stringify(error, (_, value: unknown) =>\n typeof value === \"bigint\" ? String(value) : value,\n )\n }\n return String(error)\n}\n","/**\n * Receipt view models (ADP-030/033): one-line summaries and bounded detail\n * text for the `/adaptive` receipts browser. No secrets — receipt content is\n * already bounded at write time; this layer only formats.\n */\nimport type {\n ApplyReason,\n Decision,\n ParkReason,\n SchedulerDeferReason,\n} from \"../routing/scheduler/types.js\"\nimport { resourceLabel } from \"./tiers.js\"\nimport type { Receipt, ReceiptOutcome } from \"../state/receipts/types.js\"\nimport type { HostCopy, HostDeferReason } from \"./host-copy.js\"\n\nexport function summarizeDecision(decision: Decision): string {\n switch (decision.kind) {\n case \"apply\": {\n const tier = decision.tier === undefined ? \"\" : ` [${decision.tier}]`\n return `apply ${resourceLabel(decision.model)}${tier} (${decision.reason})`\n }\n case \"defer\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `defer: ${decision.reason}${detail}`\n }\n case \"park\": {\n const detail = decision.detail === undefined ? \"\" : ` — ${decision.detail}`\n return `park: ${decision.reason}${detail}`\n }\n case \"escalate\": {\n return `escalate ${decision.step} → ${resourceLabel(decision.target)} [${decision.tier}]`\n }\n case \"observe-only\": {\n return `observe: ${summarizeDecision(decision.would)}`\n }\n }\n}\n\nexport function outcomeLine(outcome: ReceiptOutcome | undefined): string {\n if (outcome === undefined) return \"pending\"\n if (outcome.status === \"succeeded\") return \"succeeded\"\n if (outcome.status === \"failed\") return `failed (${outcome.category})`\n return `interrupted (${outcome.reason})`\n}\n\nexport function receiptLine(receipt: Receipt): string {\n return `#${String(receipt.id)} ${summarizeDecision(receipt.decision)} — ${outcomeLine(receipt.outcome)}`\n}\n\nexport function receiptDetail(receipt: Receipt, copy: HostCopy, now: number = Date.now()): string {\n return [\n `id: ${String(receipt.id)}`,\n `when: ${relativeTime(receipt.at, now)} (${new Date(receipt.at).toISOString()})`,\n `session: ${receipt.sessionID}`,\n `unit: ${receipt.unitID ?? \"-\"}`,\n `tier: ${receipt.tier ?? \"-\"}`,\n `decision: ${summarizeDecision(receipt.decision)}`,\n `outcome: ${outcomeLine(receipt.outcome)}`,\n \"\",\n `What happened: ${whatHappened(receipt, copy)}`,\n ].join(\"\\n\")\n}\n\n/** \"just now\" / \"2m ago\" / \"3h ago\" / \"5d ago\" for a receipt timestamp. */\nexport function relativeTime(at: number, now: number): string {\n const seconds = Math.max(0, Math.floor((now - at) / 1000))\n if (seconds < 60) return \"just now\"\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${String(minutes)}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${String(hours)}h ago`\n return `${String(Math.floor(hours / 24))}d ago`\n}\n\n/**\n * Plain-language explanation for a receipt, keyed on the finite reason\n * vocabulary (the maps are total over it).\n */\nexport function whatHappened(receipt: Receipt, copy: HostCopy): string {\n const decision = receipt.decision\n switch (decision.kind) {\n case \"apply\":\n return applyExplanation[decision.reason]\n case \"defer\":\n if (\n decision.reason === \"routing-defer\" ||\n decision.reason === \"adaptive-off\" ||\n decision.reason === \"pin-unverifiable\" ||\n decision.reason === \"pin-incompatible\"\n )\n return copy.receiptExplanation(decision.reason)\n return deferExplanation[decision.reason]\n case \"park\":\n return copy.parkExplanation?.(decision.reason) ?? parkExplanation[decision.reason]\n case \"escalate\":\n return `This turn needed stronger capability, so Adaptive moved it to ${resourceLabel(decision.target)}.`\n case \"observe-only\":\n return \"Adaptive is observing: this is what it would have done, without applying it.\"\n }\n}\n\nconst applyExplanation: Record<ApplyReason, string> = {\n pin: \"Adaptive routed to the resource you pinned.\",\n preferred:\n \"Adaptive chose this resource: it is the preferred resource for the tier and was available.\",\n fallback:\n \"The preferred resource was unavailable, so Adaptive moved the turn to the next resource in the tier.\",\n probe:\n \"Adaptive sent this turn as a recovery probe after an outage, to check whether the resource works again.\",\n draining: \"Adaptive routed to this resource while its provider was draining capacity.\",\n}\n\nconst deferExplanation: Record<Exclude<SchedulerDeferReason, HostDeferReason>, string> = {\n \"escalation-not-justified\":\n \"No structured capability evidence justified escalation, so Adaptive kept the current capability.\",\n \"escalation-budget-exhausted\":\n \"This unit has used its escalation budget; no further escalation is allowed.\",\n \"escalation-ceiling\":\n \"Adaptive is already at the highest capability tier; no stronger tier is configured.\",\n \"escalation-no-candidate\":\n \"No stronger resource was eligible to escalate to (unavailable, blocked, or not configured).\",\n}\n\nconst parkExplanation: Record<ParkReason, string> = {\n \"all-blocked\":\n \"Every resource in the tier is currently unavailable, so the turn ran without Adaptive routing.\",\n \"no-candidates\":\n \"There are no models configured for this tier, so the turn ran without Adaptive routing.\",\n \"no-compatible-resource\":\n \"No configured resource fits this turn's requirements, so the turn ran without Adaptive routing.\",\n \"pin-blocked\": \"The pinned resource is unavailable and no fallback is allowed while pinned.\",\n}\n\n/** Receipts shown per dialog page (bounded view). */\nexport const RECEIPTS_PAGE_SIZE = 20\n\nexport function receiptPage(receipts: readonly Receipt[]): Receipt[] {\n return receipts.slice(0, RECEIPTS_PAGE_SIZE)\n}\n","/**\n * The `/adaptive` keyboard-flow controller (ADP-033): a pure-ish state machine\n * over two seams — the typed RPC API and the host dialogs/toasts. It holds no\n * local settings state: every mutation goes through `settings.set` and the\n * returned snapshot becomes the new local view (the server is the single\n * source of truth, ADP-036).\n *\n * Flow contract: `undefined` selections always mean \"cancel this step\" — the\n * menu loop continues or exits; API failures toast and keep the loop alive.\n */\nimport type { OperatingMode } from \"../routing/scheduler/types.js\"\nimport type { TierName } from \"../routing/tier-policy/types.js\"\nimport { TIERS } from \"../routing/tier-policy/types.js\"\nimport type { ModelRef } from \"../routing/work-unit/types.js\"\nimport type { SettingsPatch, SettingsV1 } from \"../state/settings/index.js\"\nimport type { PatchResult } from \"../state/settings/types.js\"\nimport type { SessionModeSetResult } from \"../state/session-modes/index.js\"\nimport type { TierRequestSetResult } from \"../state/tier-requests/types.js\"\nimport type { Receipt } from \"../state/receipts/types.js\"\nimport type { StatusSnapshot } from \"../status.js\"\nimport { STATUS_EMPTY_MESSAGE, statusTable, compactStatus } from \"./status.js\"\nimport {\n mainMenuOptions,\n modeOptions,\n modeTargetOptions,\n sessionModeOptions,\n sessionTierOptions,\n type MainMenuChoice,\n} from \"./menu.js\"\nimport {\n modelPickerOptions,\n moveResource,\n moveResourceToTop,\n removeResource,\n resourceLabel,\n tierEditorOptions,\n tierMenuOptions,\n variantOptions,\n type ModelSummary,\n} from \"./tiers.js\"\nimport { errorText, type SelectOption } from \"./options.js\"\nimport type { HostCopy } from \"./host-copy.js\"\nimport { receiptDetail, receiptLine, receiptPage, RECEIPTS_PAGE_SIZE } from \"./receipts.js\"\nimport { runDoctor, runHealthReset, runParkedWork, type AdaptiveActions } from \"./actions.js\"\n\nexport interface AdaptiveView {\n select<Value>(options: {\n title: string\n placeholder?: string\n options: readonly SelectOption<Value>[]\n }): Promise<Value | undefined>\n /** A select with footer actions (page flips): the action closes the\n * dialog and is reported separately from an option pick. */\n selectPaged<Value>(spec: {\n title: string\n options: readonly { title: string; value: Value }[]\n actions: readonly { title: string; value: string; bind: string }[]\n }): Promise<{ picked: Value | undefined; action: string | undefined }>\n confirm(options: { title: string; message: string }): Promise<boolean | undefined>\n alert(options: { title: string; message: string }): Promise<void>\n /** A column-aligned text table (header row first); Escape closes it. */\n table(spec: { title: string; lines: string[]; compactLines?: string[] }): Promise<void>\n toast(message: string, variant: \"success\" | \"error\"): void\n}\n\nexport interface AdaptiveApi {\n settings: () => Promise<SettingsV1>\n setSettings: (patch: SettingsPatch) => Promise<PatchResult>\n status: () => Promise<StatusSnapshot>\n receipts: () => Promise<Receipt[]>\n /** The session's mode override (`null` = follows the global mode). */\n sessionMode: (sessionID: string) => Promise<OperatingMode | null>\n setSessionMode: (sessionID: string, mode: OperatingMode | null) => Promise<SessionModeSetResult>\n /** The session's pinned tier request (`null` = follows the routing ladder). */\n tierRequest: (sessionID: string) => Promise<TierName | null>\n setTierRequest: (sessionID: string, tier: string | null) => Promise<TierRequestSetResult>\n}\n\nexport type ModelLister = () => readonly ModelSummary[]\n\nexport interface AdaptiveEnv {\n copy: HostCopy\n api: AdaptiveApi\n view: AdaptiveView\n models: ModelLister\n /**\n * The session the command was opened from (ADP-054). Present only when the\n * palette command ran inside a session screen — the mode menu then steers\n * that session's override instead of the global mode.\n */\n sessionID?: string | undefined\n /** Local operations; each menu row appears only when its operation is wired. */\n actions?: AdaptiveActions\n /** Wall clock for relative times; injected so views are deterministic in tests. */\n clock?: () => number\n}\n\nexport const INVITE_MESSAGE =\n \"Adaptive starts in Observe mode: routing decisions are recorded as receipts, \" +\n \"but no model is switched. Open /adaptive to configure tiers or switch to Active.\"\n\n/** Tracks whether this dialog session already showed the save toast. */\nexport interface SaveFeedback {\n once: boolean\n}\n\n/** Run one API call; on failure toast and return undefined. */\nasync function tryApi<T>(env: AdaptiveEnv, run: () => Promise<T>): Promise<T | undefined> {\n try {\n return await run()\n } catch (error) {\n env.view.toast(errorText(error), \"error\")\n return undefined\n }\n}\n\n/**\n * Apply one patch; alert on validation errors, toast on success. The host\n * never auto-dismisses toasts, so the success toast is shown only on the\n * first successful save of a dialog session — later saves stay silent\n * (the updated menu already reflects them).\n */\nasync function applySettings(\n env: AdaptiveEnv,\n patch: SettingsPatch,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const result = await tryApi(env, () => env.api.setSettings(patch))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid settings\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result.settings\n}\n\n/**\n * Persist one session-mode override; alert on errors, toast on success. Same\n * once-toast semantics as `applySettings` — the success toast is shown only\n * on the first successful save of a dialog session.\n */\nasync function applySessionMode(\n env: AdaptiveEnv,\n sessionID: string,\n mode: OperatingMode | null,\n feedback: SaveFeedback,\n): Promise<SessionModeSetResult | undefined> {\n const result = await tryApi(env, () => env.api.setSessionMode(sessionID, mode))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid settings\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result\n}\n\n/**\n * Persist one session tier request; alert on errors, toast on success. Same\n * once-toast semantics as `applySettings` — the success toast is shown only\n * on the first successful save of a dialog session.\n */\nasync function applyTierRequest(\n env: AdaptiveEnv,\n sessionID: string,\n tier: string | null,\n feedback: SaveFeedback,\n): Promise<TierRequestSetResult | undefined> {\n const result = await tryApi(env, () => env.api.setTierRequest(sessionID, tier))\n if (result === undefined) return undefined\n if (!result.ok) {\n await env.view.alert({ title: \"Invalid tier request\", message: result.errors.join(\"; \") })\n return undefined\n }\n if (!feedback.once) {\n env.view.toast(\"Settings saved\", \"success\")\n feedback.once = true\n }\n return result\n}\n\n/** A wired local operation; true when the menu should close (a resumed run continues). */\ntype ActionRun = () => Promise<boolean>\n\nfunction actionOptions(env: AdaptiveEnv): SelectOption<ActionRun>[] {\n const actions = env.actions ?? {}\n const { resetHealth, resume, cancel, tools, doctor, preferences, defaults } = actions\n const done =\n (run: () => Promise<void>): ActionRun =>\n async () => {\n await run()\n return false\n }\n const rows: (SelectOption<ActionRun> | false)[] = [\n resetHealth !== undefined && {\n title: \"Health\",\n value: done(() => runHealthReset(env, resetHealth)),\n description: \"reset a model marked limited\",\n },\n (resume !== undefined || cancel !== undefined) && {\n title: \"Parked work\",\n value: () => runParkedWork(env, actions),\n description: \"resume or cancel waiting work\",\n },\n tools !== undefined && {\n title: \"Tool support\",\n value: done(tools),\n description: \"declare which models can call tools\",\n },\n doctor !== undefined && {\n title: \"Doctor\",\n value: done(() => runDoctor(env, doctor)),\n description: \"check setup and compatibility\",\n },\n preferences !== undefined && {\n title: \"Preferences\",\n value: done(preferences),\n description: \"transcript notes and pinned-tier escalation\",\n },\n defaults !== undefined && {\n title: \"Use Adaptive for new sessions\",\n value: done(defaults),\n description: \"Pi settings to copy\",\n },\n ]\n return rows.filter((row) => row !== false)\n}\n\nexport async function runAdaptive(env: AdaptiveEnv, initial?: MainMenuChoice): Promise<void> {\n const loaded = await tryApi(env, () => env.api.settings())\n if (loaded === undefined) return\n let settings = loaded\n const feedback: SaveFeedback = { once: false }\n const sessionID = env.sessionID\n // The session's current override: fetched once when the flow starts inside\n // a session; a failure degrades to \"follow global\" (the menu still works).\n let override: OperatingMode | null =\n sessionID === undefined\n ? null\n : ((await tryApi(env, () => env.api.sessionMode(sessionID))) ?? null)\n if (!settings.inviteDismissed) {\n await env.view.confirm({ title: env.copy.inviteTitle, message: INVITE_MESSAGE })\n const pick = await env.view.select({\n title: env.copy.inviteTitle,\n options: [\n { title: \"Open the menu now\", value: true },\n { title: \"Later\", value: false },\n ],\n })\n const dismissed = await applySettings(env, { inviteDismissed: true }, feedback)\n if (dismissed !== undefined) settings = dismissed\n if (pick !== true) return\n }\n let next = initial\n for (;;) {\n // Fresh status and settings on every pass: the menu rows pair the two,\n // and the server is the single source of truth (ADP-036). A failed read\n // degrades silently to the last known values — the menu descriptions\n // must not spam a toast on every loop iteration (the flows that need\n // status toast through tryApi themselves).\n const [freshSettings, status] = await Promise.all([\n env.api.settings().catch(() => undefined),\n env.api.status().catch(() => undefined),\n ])\n if (freshSettings !== undefined) settings = freshSettings\n // The session's pinned tier request: fetched per loop so the entry\n // description tracks the latest request; a failure degrades to the\n // generic description (the menu still works).\n const tierPinned =\n sessionID === undefined\n ? undefined\n : await env.api.tierRequest(sessionID).catch(() => undefined)\n const choice =\n next ??\n (await env.view.select<MainMenuChoice | ActionRun>({\n title: `Adaptive (${override ?? settings.mode})`,\n options: [\n ...mainMenuOptions(settings, status, tierPinned, override ?? settings.mode),\n ...actionOptions(env),\n ],\n }))\n next = undefined\n if (choice === undefined) return\n if (typeof choice === \"function\") {\n // A resumed run continues in the session: the menu steps aside for it.\n if ((await tryApi(env, choice)) === true) return\n continue\n }\n if (choice === \"status\") {\n await runStatusView(env)\n continue\n }\n if (choice === \"models\") {\n settings = (await runTierEditor(env, feedback)) ?? settings\n continue\n }\n if (choice === \"mode\") {\n const next = await runModeMenu(env, settings, feedback, sessionID, override)\n if (next !== undefined) {\n settings = next.settings\n override = next.override\n }\n continue\n }\n if (choice === \"tier\") {\n if (sessionID === undefined) {\n // The tier request only exists inside a session; on home the pick is\n // explained (not silently dropped) and the menu re-opens.\n await env.view.alert({\n title: \"This session\",\n message:\n \"This session's tier request can only be changed inside a session. Open a session and run /adaptive from there.\",\n })\n continue\n }\n await runTierRequestMenu(env, sessionID, feedback)\n continue\n }\n if (choice === \"pin\") {\n settings = (await runPinMenu(env, settings, feedback)) ?? settings\n continue\n }\n await runReceiptsView(env)\n }\n}\n\n/** What one mode-menu pass changed (settings and/or the session override). */\ninterface ModeMenuOutcome {\n settings: SettingsV1\n override: OperatingMode | null\n}\n\nasync function runModeMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n feedback: SaveFeedback,\n sessionID: string | undefined,\n override: OperatingMode | null,\n): Promise<ModeMenuOutcome | undefined> {\n // Every screen gets the same first question — which mode to steer — so a\n // user who opens the menu on home learns the two-level structure before\n // they ever run the command inside a session.\n for (;;) {\n const target = await env.view.select({\n title: \"Operating mode\",\n options: modeTargetOptions(settings.mode, override ?? settings.mode),\n })\n if (target === undefined) return undefined\n if (target === \"global\") {\n const pick = await env.view.select({\n title: \"Global mode\",\n options: modeOptions(settings.mode),\n })\n if (pick === undefined || pick === settings.mode) return undefined\n const applied = await applySettings(env, { mode: pick }, feedback)\n // The session override is deliberately untouched: changing the global\n // default must not rewrite what a session was pinned to.\n return applied === undefined ? undefined : { settings: applied, override }\n }\n if (sessionID === undefined) {\n // The session override only exists inside a session; on home the pick\n // is explained (not silently dropped) and the target question repeats.\n await env.view.alert({\n title: \"This session\",\n message:\n \"This session's mode can only be changed inside a session. Open a session and run /adaptive from there.\",\n })\n continue\n }\n const pick = await env.view.select({\n title: \"This session's mode\",\n options: sessionModeOptions({\n global: settings.mode,\n override,\n effective: override ?? settings.mode,\n }),\n })\n if (pick === undefined) return undefined\n if (pick.kind === \"global\") {\n if (override === null) return undefined\n const saved = await applySessionMode(env, sessionID, null, feedback)\n return saved === undefined ? undefined : { settings, override: null }\n }\n if (pick.mode === (override ?? settings.mode)) return undefined\n const saved = await applySessionMode(env, sessionID, pick.mode, feedback)\n return saved === undefined ? undefined : { settings, override: pick.mode }\n }\n}\n\n/** The per-session tier-request menu (ADP-055): pin a tier or clear it. */\nasync function runTierRequestMenu(\n env: AdaptiveEnv,\n sessionID: string,\n feedback: SaveFeedback,\n): Promise<void> {\n const pinned = await tryApi(env, () => env.api.tierRequest(sessionID))\n if (pinned === undefined) return\n const pick = await env.view.select({\n title: \"This session's tier\",\n options: sessionTierOptions({ pinned }),\n })\n if (pick === undefined) return\n const next = pick.kind === \"ladder\" ? null : pick.tier\n if (next === pinned) return\n await applyTierRequest(env, sessionID, next, feedback)\n}\n\n/**\n * The status view: every configured model with its state as a column-aligned\n * table (header row, tier order, priority order within tiers). No\n * per-resource selection step — the table IS the view; Escape returns to the\n * menu.\n */\nasync function runStatusView(env: AdaptiveEnv): Promise<void> {\n const snapshot = await tryApi(env, () => env.api.status())\n if (snapshot === undefined) return\n const configured = TIERS.some((tier) => snapshot.tiers[tier].length > 0)\n if (!configured) {\n await env.view.alert({ title: \"Status\", message: STATUS_EMPTY_MESSAGE })\n return\n }\n await env.view.table({\n title: \"Status\",\n lines: statusTable(snapshot),\n compactLines: compactStatus(snapshot),\n })\n}\n\ntype TierEditorOutcome = SettingsV1 | undefined\n\nasync function runTierEditor(env: AdaptiveEnv, feedback: SaveFeedback): Promise<TierEditorOutcome> {\n // The last confirmed server snapshot from this editor session, returned\n // when the editor closes so the menu view stays in sync with the server.\n let saved: SettingsV1 | undefined\n for (;;) {\n // The server is the single source of truth (ADP-036): settings and\n // status are re-fetched on every tier-list pass — entering the editor\n // and after each Escape out of a tier page — so an edit can never\n // clobber a change made outside this dialog. A failed read toasts and\n // closes the editor: the tier list cannot render meaningfully without\n // them.\n const settings = await tryApi(env, () => env.api.settings())\n if (settings === undefined) return saved\n const status = await tryApi(env, () => env.api.status())\n if (status === undefined) return saved\n const tier = await env.view.select({ title: \"Tier\", options: tierMenuOptions(status) })\n if (tier === undefined) return saved\n let pageStatus = status\n let pageSettings = settings\n // The tier page owns the loop until Escape: an add, move, or remove\n // re-opens this page instead of bouncing back to the tier list, so\n // consecutive edits on one tier stay in context. The page's settings\n // and status carry across iterations: each action's save response\n // updates them for the next render.\n for (;;) {\n const choice = await env.view.select({\n title: `Tier: ${tier}`,\n options: tierEditorOptions(pageSettings, tier, pageStatus, env.copy.modelSearchPlaceholder),\n })\n if (choice === undefined) break\n if (choice.kind === \"add\") {\n const next = await runAddModel(env, pageSettings, tier, feedback)\n if (next !== undefined) {\n saved = next\n pageSettings = next\n }\n } else {\n const next = await runResourceMenu(env, pageSettings, tier, choice, feedback)\n if (next !== undefined) {\n saved = next\n pageSettings = next\n }\n }\n // The rows re-pair with the server after every action; a failed read\n // keeps the last known values so the page still renders (the save\n // already reported itself — a failed cosmetic refresh must neither\n // spam a toast nor bounce the page).\n const [freshSettings, freshStatus] = await Promise.all([\n env.api.settings().catch(() => undefined),\n env.api.status().catch(() => undefined),\n ])\n if (freshSettings !== undefined) {\n saved = freshSettings\n pageSettings = freshSettings\n }\n if (freshStatus !== undefined) pageStatus = freshStatus\n }\n }\n}\n\nasync function runAddModel(\n env: AdaptiveEnv,\n settings: SettingsV1,\n tier: TierName,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const models = env.models()\n const pick = await env.view.select({\n title: \"Add model\",\n placeholder: \"Search provider / model / name\",\n options: modelPickerOptions(models),\n })\n if (pick === undefined) return undefined\n const variants = pick.variants\n let variant: string | undefined\n if (variants.length > 0) {\n const choice = await env.view.select({\n title: `Variant: ${pick.providerID}/${pick.modelID}`,\n options: variantOptions(variants),\n })\n if (choice === undefined) return undefined\n variant = choice.variant\n }\n const ref: ModelRef =\n variant === undefined\n ? { providerID: pick.providerID, id: pick.modelID }\n : { providerID: pick.providerID, id: pick.modelID, variant }\n const list = [...settings.tiers[tier], ref]\n return applySettings(env, { tiers: { ...settings.tiers, [tier]: list } }, feedback)\n}\n\ntype ResourceMenuChoice = \"top\" | \"up\" | \"down\" | \"remove\"\n\nfunction resourceMenuOptions(): SelectOption<ResourceMenuChoice>[] {\n return [\n { title: \"Move to top\", value: \"top\", description: \"Make this the primary resource\" },\n { title: \"Move up\", value: \"up\", description: \"Higher priority within the tier\" },\n { title: \"Move down\", value: \"down\", description: \"Lower priority within the tier\" },\n { title: \"Remove\", value: \"remove\" },\n ]\n}\n\nasync function runResourceMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n tier: TierName,\n { index, ref }: { index: number; ref: ModelRef },\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const pick = await env.view.select({\n title: `Resource: ${resourceLabel(ref)}`,\n options: resourceMenuOptions(),\n })\n if (pick === undefined) return undefined\n if (pick === \"remove\") {\n const confirmed = await env.view.confirm({\n title: \"Remove resource\",\n message: `Remove ${resourceLabel(ref)} from ${tier}?`,\n })\n if (confirmed !== true) return undefined\n return applySettings(\n env,\n { tiers: { ...settings.tiers, [tier]: removeResource(settings.tiers[tier], index) } },\n feedback,\n )\n }\n const list =\n pick === \"top\"\n ? moveResourceToTop(settings.tiers[tier], index)\n : moveResource(settings.tiers[tier], index, pick === \"up\" ? -1 : 1)\n return applySettings(env, { tiers: { ...settings.tiers, [tier]: list } }, feedback)\n}\n\ntype PinChoice = { kind: \"clear\" } | { kind: \"pin\"; ref: ModelRef }\n\nfunction pinOptions(settings: SettingsV1): SelectOption<PinChoice>[] {\n const options: SelectOption<PinChoice>[] = [\n { title: \"No pin\", value: { kind: \"clear\" }, description: \"clear the pin\" },\n ]\n for (const tier of TIERS) {\n for (const ref of settings.tiers[tier]) {\n options.push({\n title: `${resourceLabel(ref)} (${tier})`,\n description: \"route every turn to this resource, even in active mode\",\n value: { kind: \"pin\", ref },\n })\n }\n }\n return options\n}\n\nasync function runPinMenu(\n env: AdaptiveEnv,\n settings: SettingsV1,\n feedback: SaveFeedback,\n): Promise<SettingsV1 | undefined> {\n const configured = TIERS.some((tier) => settings.tiers[tier].length > 0)\n if (!configured) {\n await env.view.alert({ title: \"Pin\", message: \"(no configured resources to pin)\" })\n return undefined\n }\n const pick = await env.view.select({ title: \"Pin\", options: pinOptions(settings) })\n if (pick === undefined) return undefined\n return applySettings(env, { pin: pick.kind === \"clear\" ? null : pick.ref }, feedback)\n}\n\nasync function runReceiptsView(env: AdaptiveEnv): Promise<void> {\n const all = await tryApi(env, () => env.api.receipts())\n if (all === undefined) return\n if (all.length === 0) {\n await env.view.alert({\n title: \"Receipts\",\n message: \"No decisions recorded yet.\",\n })\n return\n }\n // Paginated browse: every page is a bounded view, and the page flips are\n // footer actions (not list items) — they close the dialog and the loop\n // reopens it at the new offset. Viewing a detail returns to the same\n // page; Escape (no pick, no action) leaves the browser.\n for (let offset = 0; ;) {\n const page = receiptPage(all.slice(offset))\n const hasNext = offset + RECEIPTS_PAGE_SIZE < all.length\n const result = await env.view.selectPaged({\n title: `Receipts (${String(all.length)}, newest first)`,\n options: page.map((receipt) => ({ title: receiptLine(receipt), value: receipt })),\n actions: [\n ...(offset > 0 ? [{ title: \"Previous page\", value: \"prev\", bind: \"ctrl+b\" }] : []),\n ...(hasNext ? [{ title: \"Next page\", value: \"next\", bind: \"ctrl+f\" }] : []),\n ],\n })\n if (result.action === \"next\") {\n offset += RECEIPTS_PAGE_SIZE\n continue\n }\n if (result.action === \"prev\") {\n offset = Math.max(0, offset - RECEIPTS_PAGE_SIZE)\n continue\n }\n const pick = result.picked\n if (pick === undefined) return\n await env.view.alert({\n title: `Receipt #${String(pick.id)}`,\n message: receiptDetail(pick, env.copy),\n })\n }\n}\n\n/** Exported for tests: the receipts page size used by the receipts browser. */\nexport { RECEIPTS_PAGE_SIZE }\n\nexport type {\n MainMenuChoice,\n OperatingMode,\n StatusSnapshot,\n SettingsV1,\n SettingsPatch,\n PatchResult,\n Receipt,\n}\n","/**\n * `/adaptive <subcommand>`, shared by every host (ADP-062): one parser, one\n * copy, so a subcommand typed in Pi behaves the same in OpenCode. Action-backed\n * subcommands exist only where the host wires the action.\n */\nimport {\n cancelHere,\n resumeHere,\n runDoctor,\n runHealthReset,\n type AdaptiveActions,\n} from \"./actions.js\"\nimport { runAdaptive, type AdaptiveEnv } from \"./controller.js\"\nimport { receiptDetail } from \"./receipts.js\"\n\nexport const ADAPTIVE_SUBCOMMANDS = [\n \"status\",\n \"why\",\n \"tiers\",\n \"tools\",\n \"health\",\n \"resume\",\n \"cancel\",\n \"observe on\",\n \"observe off\",\n \"doctor\",\n] as const\nexport type AdaptiveSubcommand = (typeof ADAPTIVE_SUBCOMMANDS)[number]\n\nconst REQUIRES: Partial<Record<AdaptiveSubcommand, keyof AdaptiveActions>> = {\n tools: \"tools\",\n health: \"resetHealth\",\n resume: \"resume\",\n cancel: \"cancel\",\n doctor: \"doctor\",\n}\n\n/** The subcommands a host with these actions can run, in menu order. */\nexport function adaptiveSubcommands(actions: AdaptiveActions | undefined): AdaptiveSubcommand[] {\n return ADAPTIVE_SUBCOMMANDS.filter((command) => {\n const needs = REQUIRES[command]\n return needs === undefined || actions?.[needs] !== undefined\n })\n}\n\n/** Runs `/adaptive <input>`; an empty input opens the menu. API failures propagate to the host. */\nexport async function runAdaptiveCommand(env: AdaptiveEnv, input: string): Promise<void> {\n const command = input.trim().replace(/\\s+/g, \" \")\n const { resetHealth, resume, cancel, tools, doctor } = env.actions ?? {}\n switch (command) {\n case \"\":\n await runAdaptive(env)\n return\n case \"status\":\n await runAdaptive(env, \"status\")\n return\n case \"tiers\":\n await runAdaptive(env, \"models\")\n return\n case \"why\": {\n const latest = (await env.api.receipts()).find(\n (receipt) => receipt.sessionID === env.sessionID,\n )\n await env.view.alert({\n title: \"Latest decision\",\n message:\n latest === undefined\n ? \"No decisions recorded in this session yet.\"\n : receiptDetail(latest, env.copy, (env.clock ?? Date.now)()),\n })\n return\n }\n case \"observe on\":\n case \"observe off\": {\n const result = await env.api.setSettings({\n mode: command === \"observe on\" ? \"observe\" : \"off\",\n })\n env.view.toast(\n result.ok\n ? \"Observation setting saved. Your selected model is unchanged.\"\n : result.errors.join(\"; \"),\n result.ok ? \"success\" : \"error\",\n )\n return\n }\n case \"tools\":\n if (tools === undefined) break\n await tools()\n return\n case \"health\":\n if (resetHealth === undefined) break\n await runHealthReset(env, resetHealth)\n return\n case \"resume\":\n if (resume === undefined) break\n await resumeHere(env, resume)\n return\n case \"cancel\":\n if (cancel === undefined) break\n await cancelHere(env, cancel)\n return\n case \"doctor\":\n if (doctor === undefined) break\n await runDoctor(env, doctor)\n return\n }\n env.view.toast(\n `Unknown adaptive command. Use: ${adaptiveSubcommands(env.actions).join(\", \")}.`,\n \"error\",\n )\n}\n","import { ADAPTIVE_SUBCOMMANDS, runAdaptiveCommand } from \"@coool/adaptive-core/flow/command\"\nimport type { AdaptiveEnv } from \"@coool/adaptive-core/flow/controller\"\n\ninterface CommandContext {\n readonly hasUI: boolean\n readonly ui: { notify(message: string, type: \"warning\" | \"error\" | \"info\"): void }\n}\ninterface CommandOptions<C> {\n env(ctx: C): Promise<AdaptiveEnv>\n}\ninterface CommandHost<C> {\n registerCommand(\n name: string,\n options: {\n description: string\n getArgumentCompletions(prefix: string): { value: string; label: string }[]\n handler(args: string, ctx: C & { waitForIdle(): Promise<void> }): Promise<void>\n },\n ): void\n registerShortcut(\n key: \"ctrl+alt+a\",\n options: {\n description: string\n handler(ctx: C & { isIdle(): boolean }): Promise<void>\n },\n ): void\n}\n\nexport async function runCommand<C extends CommandContext>(\n args: string,\n ctx: C,\n options: CommandOptions<C>,\n): Promise<void> {\n if (!ctx.hasUI) {\n ctx.ui.notify(\"Open /adaptive in an interactive or RPC session.\", \"warning\")\n return\n }\n await runAdaptiveCommand(await options.env(ctx), args)\n}\n\nexport function registerCommands<C extends CommandContext>(\n pi: CommandHost<C>,\n options: CommandOptions<C>,\n): void {\n pi.registerCommand(\"adaptive\", {\n description: \"Adaptive settings, decisions and diagnostics\",\n getArgumentCompletions: (prefix) =>\n ADAPTIVE_SUBCOMMANDS.filter((command) => command.startsWith(prefix)).map((command) => ({\n value: command,\n label: command,\n })),\n async handler(args, ctx) {\n await ctx.waitForIdle()\n try {\n await runCommand(args, ctx, options)\n } catch {\n ctx.ui.notify(\n \"Adaptive could not open. Run /adaptive doctor; your model is unchanged.\",\n \"error\",\n )\n }\n },\n })\n pi.registerShortcut(\"ctrl+alt+a\", {\n description: \"Open Adaptive\",\n async handler(ctx) {\n if (!ctx.isIdle()) {\n ctx.ui.notify(\"Wait for the current run before opening Adaptive.\", \"info\")\n return\n }\n try {\n await runCommand(\"\", ctx, options)\n } catch {\n ctx.ui.notify(\n \"Adaptive could not open. Run /adaptive doctor; your model is unchanged.\",\n \"error\",\n )\n }\n },\n })\n}\n","import type { AdaptiveApi } from \"@coool/adaptive-core/flow/controller\"\nimport type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { isTierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { StatusSnapshot } from \"@coool/adaptive-core/status\"\nimport { readSettings, updateSettings } from \"../settings.js\"\nimport { readReceipts } from \"../receipts.js\"\nimport { effectiveMode, requestedTier, SESSION_ENTRY, sessionModeOverride } from \"../session.js\"\nimport type { BranchEntry } from \"../task.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\n\nexport interface ControlOptions {\n readonly settings: JsonFile\n readonly receipts: JsonTransactionFile\n readonly sessionID: string\n readonly branch: () => readonly BranchEntry[]\n readonly model: () => { readonly provider: string; readonly id: string } | undefined\n readonly manualModel: () => ModelRef | undefined\n readonly selectModel: (model: ModelRef) => Promise<boolean>\n readonly append: (type: string, data: unknown) => void\n readonly idle: () => boolean\n readonly status: () => Promise<StatusSnapshot>\n}\n\n/** In-process binding of the shared flow; no second settings or routing state. */\nexport function controlApi(options: ControlOptions): AdaptiveApi {\n const validSession = (id: string) => id === options.sessionID && id.trim() !== \"\"\n return {\n settings: () => readSettings(options.settings),\n setSettings: (patch) => updateSettings(options.settings, patch),\n status: options.status,\n receipts: () => readReceipts(options.receipts),\n async sessionMode(id) {\n if (!validSession(id))\n throw new Error(\"Adaptive sessionID: this command belongs to another session\")\n const settings = await readSettings(options.settings)\n return options.model()?.provider === \"adaptive\"\n ? effectiveMode(options.model(), settings.mode, options.branch())\n : sessionModeOverride(options.branch())\n },\n async setSessionMode(id, mode) {\n if (!validSession(id)) return { ok: false, errors: [\"invalid sessionID\"] }\n if (!options.idle())\n return { ok: false, errors: [\"Wait for the current run before changing its mode.\"] }\n const settings = await readSettings(options.settings)\n const next: OperatingMode = mode ?? settings.mode\n const selected = options.model()\n let target: ModelRef | undefined\n if (next === \"active\") target = { providerID: \"adaptive\", id: \"auto\" }\n else if (selected?.provider === \"adaptive\") target = options.manualModel()\n if (next !== \"active\" && selected?.provider === \"adaptive\" && target === undefined)\n return {\n ok: false,\n errors: [\"Pick a normal model in Pi's model picker to pause Adaptive.\"],\n }\n if (target !== undefined && !(await options.selectModel(target)))\n return {\n ok: false,\n errors: [\"Model could not be selected. Check credentials with /adaptive doctor.\"],\n }\n options.append(SESSION_ENTRY, { version: 1, mode })\n return { ok: true }\n },\n tierRequest(id) {\n if (!validSession(id))\n return Promise.reject(\n new Error(\"Adaptive sessionID: this command belongs to another session\"),\n )\n return Promise.resolve(requestedTier(options.branch()))\n },\n setTierRequest(id, tier) {\n if (!validSession(id)) return Promise.resolve({ ok: false, errors: [\"invalid sessionID\"] })\n if (tier !== null && !isTierName(tier))\n return Promise.resolve({\n ok: false,\n errors: [\"invalid tier: expected quick, standard, advanced, or null\"],\n })\n options.append(SESSION_ENTRY, { version: 1, tier })\n return Promise.resolve({ ok: true })\n },\n }\n}\n","import type { DoctorCheck } from \"@coool/adaptive-core/flow/doctor\"\n\nfunction parts(version: string): readonly [number, number, number] | undefined {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(version)) return undefined\n const [major, minor, patch] = version.split(\".\")\n return [Number(major), Number(minor), Number(patch)]\n}\n\nfunction compare(\n a: readonly [number, number, number],\n b: readonly [number, number, number],\n): number {\n for (const index of [0, 1, 2] as const) {\n const difference = a[index] - b[index]\n if (difference !== 0) return difference\n }\n return 0\n}\n\nexport function versionChecks(\n version: string,\n minimum: string,\n testedUpTo: string | undefined,\n): DoctorCheck[] {\n const actual = parts(version)\n const floor = parts(minimum)\n const tested = testedUpTo === undefined ? undefined : parts(testedUpTo)\n if (actual === undefined || floor === undefined)\n return [\n {\n state: \"warning\",\n message: `Pi ${version}: version support could not be checked`,\n action: \"Pick a normal model and report this version.\",\n },\n ]\n if (actual[0] !== 1 || compare(actual, floor) < 0)\n return [\n {\n state: \"error\",\n message: `Pi ${version} is unsupported (requires ≥${minimum} <2)`,\n action: \"Install a supported Pi version or pick a normal model.\",\n },\n ]\n const checks: DoctorCheck[] = [\n { state: \"ok\", message: `Pi ${version} (supported: ≥${minimum} <2)` },\n ]\n if (tested === undefined)\n checks.push({\n state: \"warning\",\n message: \"Packed-host tested-up-to evidence is not recorded\",\n action: \"Run the complete Pi host matrix before release.\",\n })\n else if (compare(actual, tested) > 0)\n checks.push({\n state: \"warning\",\n message: `Pi ${version} is newer than last tested ${String(testedUpTo)}`,\n action: \"If routing misbehaves, pick a normal model and report it.\",\n })\n else checks.push({ state: \"ok\", message: `Packed hosts tested up to ${String(testedUpTo)}` })\n return checks\n}\n","import type { ModelRegistry } from \"@earendil-works/pi-coding-agent\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport { VIRTUAL_IDS } from \"../router.js\"\nimport { statusChecks, type DoctorCheck } from \"@coool/adaptive-core/flow/doctor\"\nimport type { StatusSnapshot } from \"@coool/adaptive-core/status\"\nimport { versionChecks } from \"../ui/doctor.js\"\n\nexport interface DoctorOptions {\n readonly version: string\n readonly minimum: string\n readonly testedUpTo: string | undefined\n readonly registry: Pick<\n ModelRegistry,\n \"getAll\" | \"find\" | \"hasConfiguredAuth\" | \"getRegisteredProviderConfig\"\n >\n readonly settings: () => Promise<SettingsV1>\n readonly capabilities: () => Promise<readonly ToolCapability[]>\n readonly storage: () => Promise<void>\n readonly status: () => Promise<StatusSnapshot>\n}\n\n/** Probe failures use fixed copy: upstream errors/configs may contain credentials. */\nexport async function doctorChecks(options: DoctorOptions): Promise<DoctorCheck[]> {\n const checks = versionChecks(options.version, options.minimum, options.testedUpTo)\n const missing = VIRTUAL_IDS.filter((id) => options.registry.find(\"adaptive\", id) === undefined)\n checks.push(\n missing.length === 0\n ? { state: \"ok\", message: \"All four Adaptive models registered\" }\n : {\n state: \"error\",\n message: `Missing Adaptive models: ${missing.join(\", \")}`,\n action: \"Reload Pi with the Adaptive extension enabled.\",\n },\n )\n try {\n const settings = await options.settings()\n const capabilities = await options.capabilities()\n const credentialed: string[] = []\n const undeclared = new Set<string>()\n for (const tier of TIERS) {\n for (const ref of settings.tiers[tier]) {\n const model = options.registry.find(ref.providerID, ref.id)\n if (model === undefined)\n checks.push({\n state: \"error\",\n message: `${resourceLabel(ref)} (${tier}): model missing`,\n action: \"Refresh Pi's model catalog or remove this tier entry.\",\n })\n else if (!options.registry.hasConfiguredAuth(model))\n checks.push({\n state: \"error\",\n message: `${resourceLabel(ref)} (${tier}): no credentials configured`,\n action: `Run /login ${ref.providerID}, or remove it from the tier.`,\n })\n else credentialed.push(resourceLabel(ref))\n if (\n !capabilities.some(\n (entry) => entry.providerID === ref.providerID && entry.id === ref.id && entry.tools,\n )\n )\n undeclared.add(resourceLabel(ref))\n }\n }\n if (credentialed.length > 0)\n checks.push({\n state: \"ok\",\n message: `Credentials configured for ${String(credentialed.length)} tier ${credentialed.length === 1 ? \"model\" : \"models\"}`,\n })\n if (undeclared.size > 0)\n checks.push({\n state: \"warning\",\n message: `Tool support not declared: ${[...undeclared].join(\", \")}`,\n action: \"Open /adaptive tools to declare them; Adaptive never guesses from a name.\",\n })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Settings or capabilities could not be read\",\n action:\n \"Inspect adaptive/settings.json and capabilities.json; corrupt files were not replaced.\",\n })\n }\n try {\n await options.storage()\n checks.push({ state: \"ok\", message: \"Shared storage writable; exclusive lock works\" })\n } catch {\n checks.push({\n state: \"error\",\n message: \"Shared storage or lock unavailable\",\n action: \"Check permissions and other Pi processes in the agent's adaptive directory.\",\n })\n }\n const models = options.registry.getAll()\n const virtuals = models.filter(\n (model) => model.api === \"pi-virtual\" && model.provider !== \"adaptive\",\n )\n for (const model of virtuals)\n checks.push({\n state: \"warning\",\n message: `Other router model: ${model.provider}/${model.id}`,\n action: \"Use one router for a session; do not put another virtual model in Adaptive tiers.\",\n })\n for (const provider of new Set(models.map((model) => model.provider))) {\n if (provider === \"adaptive\") continue\n if (options.registry.getRegisteredProviderConfig(provider)?.streamSimple !== undefined)\n checks.push({\n state: \"warning\",\n message: `Custom request handler: ${provider}`,\n action:\n \"If this handler routes requests too, use one router. No conflict is assumed from a handler alone.\",\n })\n }\n try {\n checks.push(...statusChecks(await options.status()))\n } catch {\n checks.push({\n state: \"error\",\n message: \"Health or parked work could not be read\",\n action:\n \"Inspect adaptive/health.json and parked.json; do not delete them while another Pi process is running.\",\n })\n }\n return checks\n}\n","// covers: [\"ADP-004\", \"ADP-005\", \"ADP-063\"]\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\n\nexport interface ProposalModel {\n readonly ref: ModelRef\n readonly inputCost: number\n readonly outputCost: number\n readonly reasoning: boolean\n readonly contextWindow: number\n readonly thinkingLevels: readonly string[]\n}\n\nfunction identity(model: ProposalModel): string {\n return JSON.stringify([model.ref.providerID, model.ref.id])\n}\n\nfunction cost(model: ProposalModel): number {\n const sum = model.inputCost + model.outputCost\n return Number.isFinite(sum) && model.inputCost >= 0 && model.outputCost >= 0 ? sum : Infinity\n}\n\nfunction order(left: ProposalModel, right: ProposalModel): number {\n const a = cost(left)\n const b = cost(right)\n if (a !== b) return a < b ? -1 : 1\n const l = identity(left)\n const r = identity(right)\n if (l !== r) return l < r ? -1 : 1\n return (\n Number(left.reasoning) - Number(right.reasoning) ||\n left.contextWindow - right.contextWindow ||\n Number(left.thinkingLevels.includes(\"high\")) - Number(right.thinkingLevels.includes(\"high\"))\n )\n}\n\n/** A proposal is a starting point, not the catalog: a primary and a fallback per tier keep\n * the first-run decision small; the tier editor offers every configured model. */\nconst PROPOSAL_TIER_CAP = 2\n\n/** Settings bootstrap only: never consulted during routing, and never persists. */\nexport function proposeTiers(models: readonly ProposalModel[]): SettingsV1[\"tiers\"] {\n const unique = new Map<string, ProposalModel>()\n for (const model of [...models].sort(order)) unique.set(identity(model), model)\n const ordered = [...unique.values()]\n const first = Math.ceil(ordered.length / 3)\n const second = Math.ceil((ordered.length * 2) / 3)\n const refs = (group: readonly ProposalModel[], advanced: boolean): ModelRef[] =>\n group.slice(0, PROPOSAL_TIER_CAP).map((model) => ({\n providerID: model.ref.providerID,\n id: model.ref.id,\n ...(advanced && model.reasoning && model.thinkingLevels.includes(\"high\")\n ? { variant: \"high\" }\n : {}),\n }))\n return {\n quick: refs(ordered.slice(0, first), false),\n standard: refs(ordered.slice(first, second), false),\n advanced: refs(\n ordered\n .slice(second)\n .sort(\n (a, b) =>\n Number(b.reasoning) - Number(a.reasoning) ||\n b.contextWindow - a.contextWindow ||\n order(a, b),\n ),\n true,\n ),\n }\n}\n","/**\n * Status snapshot for the control surfaces (ADP-033): a bounded, secret-free\n * view of the settings and the resource-health state of every configured\n * resource. Pure — the supervisor (or any future caller) gathers the inputs.\n */\nimport type { OperatingMode } from \"./routing/scheduler/types.js\"\nimport { schedulerHealthKey } from \"./routing/scheduler/index.js\"\nimport type { ModelRef } from \"./routing/work-unit/types.js\"\nimport type { TierName } from \"./routing/tier-policy/types.js\"\nimport { TIERS } from \"./routing/tier-policy/types.js\"\nimport type { ResourceRecord } from \"./health/resource-health/types.js\"\nimport type { CapacityReading } from \"./health/capacity/types.js\"\nimport { resourceKeyID } from \"./health/resource-health/index.js\"\nimport type { SettingsV1 } from \"./state/settings/index.js\"\n\nexport interface TierResourceStatus {\n ref: ModelRef\n health: ResourceRecord[\"health\"]\n breaker: ResourceRecord[\"breaker\"][\"state\"]\n windowed: boolean\n /**\n * Wall-clock deadline of the active window (ms epoch); null when unwindowed.\n * Null — not undefined: the host RPC encoder rejects JSON objects carrying a\n * present-but-undefined key (\"Expected JSON value\"), which 500'd every\n * status.get once any resource was configured.\n */\n windowUntil: number | null\n /** Used capacity as a rounded whole percent; null when no reading exists. */\n usedPercent: number | null\n /** Wall-clock capacity reset deadline (ms epoch); null when unread. */\n resetAt: number | null\n}\n\n/** A session whose parked work waits for its tier to recover (ADP-024). */\nexport interface WaitingSession {\n sessionID: string\n tier: TierName\n /** When the wake resumes it (ms epoch); null when no resource states a reset. */\n resumeAt: number | null\n}\n\nexport interface StatusSnapshot {\n mode: OperatingMode\n pin: ModelRef | null\n tiers: Readonly<Record<TierName, readonly TierResourceStatus[]>>\n parked: number\n waiting: readonly WaitingSession[]\n receipts: number\n}\n\nexport function buildStatus(input: {\n settings: SettingsV1\n health: readonly ResourceRecord[]\n capacity: Readonly<Record<string, CapacityReading | null>>\n parked: number\n waiting: readonly WaitingSession[]\n receipts: number\n}): StatusSnapshot {\n const byKey = new Map<string, ResourceRecord>()\n for (const record of input.health) byKey.set(resourceKeyID(record.key), record)\n const tiers = {} as Record<TierName, TierResourceStatus[]>\n for (const tier of TIERS) {\n tiers[tier] = input.settings.tiers[tier].map((ref) => {\n const record = byKey.get(schedulerHealthKey(ref))\n const capacityReading = input.capacity[schedulerHealthKey(ref)] ?? null\n return {\n ref,\n health: record?.health ?? \"healthy\",\n breaker: record?.breaker.state ?? \"closed\",\n windowed: record?.window !== undefined,\n windowUntil: record?.window?.until ?? null,\n usedPercent: capacityUsedPercent(capacityReading),\n resetAt: capacityReading?.resetAt ?? null,\n }\n })\n }\n return {\n mode: input.settings.mode,\n pin: input.settings.pin,\n tiers,\n parked: input.parked,\n waiting: input.waiting,\n receipts: input.receipts,\n }\n}\n\n/**\n * Derives the used-capacity percentage from a reading. Readings may carry any\n * subset of the two ratios: usedRatio directly, or the remainder inferred from\n * remainingRatio. A reading with neither ratio is still present (confidence,\n * resetAt may be set) but yields no percentage — null, not undefined.\n */\nfunction capacityUsedPercent(reading: CapacityReading | null): number | null {\n if (reading?.usedRatio !== undefined) return Math.round(reading.usedRatio * 100)\n if (reading?.remainingRatio !== undefined) return Math.round((1 - reading.remainingRatio) * 100)\n return null\n}\n","// covers: [\"ADP-032\", \"ADP-063\"]\nimport {\n runAdaptive,\n type AdaptiveApi,\n type AdaptiveEnv,\n type AdaptiveView,\n} from \"@coool/adaptive-core/flow/controller\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport { resourceLabel } from \"@coool/adaptive-core/flow/tiers\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { proposeTiers, type ProposalModel } from \"../ui/proposal.js\"\nimport { migrateSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport { buildStatus } from \"@coool/adaptive-core/status\"\n\n/** The shared tier editor writes a local draft; only the wizard commits it. */\nexport async function editTierProposal(env: AdaptiveEnv, initial: SettingsV1): Promise<SettingsV1> {\n let draft = initial\n await runAdaptive(\n {\n copy: env.copy,\n view: env.view,\n models: env.models,\n api: {\n ...env.api,\n settings: () => Promise.resolve(draft),\n setSettings: (patch) => {\n draft = migrateSettings({ ...draft, ...patch })\n return Promise.resolve({ ok: true, settings: draft })\n },\n status: () =>\n Promise.resolve(\n buildStatus({\n settings: draft,\n health: [],\n capacity: {},\n parked: 0,\n waiting: [],\n receipts: 0,\n }),\n ),\n },\n },\n \"models\",\n )\n return draft\n}\n\nexport interface OnboardingOptions {\n readonly hasUI: boolean\n readonly api: Pick<AdaptiveApi, \"settings\" | \"setSettings\">\n readonly view: AdaptiveView\n readonly models: () => readonly ProposalModel[]\n readonly edit: (draft: SettingsV1) => Promise<SettingsV1>\n readonly activate: () => Promise<boolean>\n}\n\nexport async function runOnboarding(options: OnboardingOptions): Promise<void> {\n const current = await options.api.settings()\n if (current.inviteDismissed) return\n // Print and JSON runs keep stdout/stderr machine-clean; they observe by default.\n if (!options.hasUI) return\n let draft = {\n ...current,\n mode: \"observe\" as const,\n inviteDismissed: true,\n tiers: TIERS.some((tier) => current.tiers[tier].length > 0)\n ? current.tiers\n : proposeTiers(options.models()),\n }\n for (;;) {\n const summary = TIERS.map(\n (tier) =>\n `${tier}: ${draft.tiers[tier].map(resourceLabel).join(\" · \") || \"no models available\"}`,\n ).join(\"\\n\")\n const choice = await options.view.select({\n title: `Adaptive is installed\\n${summary}\\nTool support must be confirmed separately; /adaptive doctor checks it.`,\n options: [\n { title: \"Save tiers and use Adaptive this session\", value: \"use\" },\n { title: \"Save tiers, keep my current model\", value: \"save\" },\n { title: \"Edit suggested tiers…\", value: \"edit\" },\n { title: \"Not now\", value: \"later\" },\n ],\n })\n if (choice === \"edit\") {\n draft = { ...(await options.edit(draft)), mode: \"observe\", inviteDismissed: true }\n continue\n }\n if (choice !== \"save\" && choice !== \"use\") {\n await options.api.setSettings({ inviteDismissed: true })\n return\n }\n const confirmed = await options.view.confirm({\n title: \"Save these tiers?\",\n message: `${summary}\\nGlobal mode stays Observe. Nothing changes until you confirm.`,\n })\n if (confirmed !== true) continue\n const saved = await options.api.setSettings({\n tiers: draft.tiers,\n mode: \"observe\",\n inviteDismissed: true,\n })\n if (!saved.ok) {\n await options.view.alert({ title: \"Could not save tiers\", message: saved.errors.join(\"; \") })\n return\n }\n options.view.toast(\"Tiers saved\", \"success\")\n if (choice === \"use\" && !(await options.activate()))\n options.view.toast(\n \"Tiers saved, but Adaptive could not be selected. Open Pi's model picker.\",\n \"error\",\n )\n return\n }\n}\n","import { isDeepStrictEqual } from \"node:util\"\nimport { buildStatus, type StatusSnapshot } from \"@coool/adaptive-core/status\"\nimport { DEFAULT_HEALTH_CONFIG, ResourceHealthRegistry } from \"@coool/adaptive-core/health/index\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { OperatingMode } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport { readCapacity, type SharedCapacity } from \"../capacity.js\"\nimport { readSharedHealth } from \"../health-actions.js\"\nimport type { SharedHealth } from \"../health.js\"\nimport { readReceipts } from \"../receipts.js\"\nimport { object } from \"../settings.js\"\nimport { parseParked, type Parked } from \"../parking.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\n\nexport async function readParked(file: Pick<JsonFile, \"read\">): Promise<Parked[]> {\n const raw = await file.read()\n if (raw === undefined) return []\n if (!(object(raw) && Array.isArray(raw[\"records\"])) || raw[\"records\"].length > 512)\n throw new Error(\"Adaptive parked: invalid parked.json payload\")\n const records = raw[\"records\"].map((entry: unknown) => parseParked(entry))\n if (!isDeepStrictEqual(raw, { version: 1, records }))\n throw new Error(\"Adaptive parked: invalid parked.json payload\")\n return records.filter((record) => !record.claimed)\n}\n\ninterface StatusSources {\n settings(): Promise<SettingsV1>\n readonly health: SharedHealth\n readonly capacity: SharedCapacity\n readonly receipts: JsonTransactionFile\n readonly parked: JsonFile\n effectiveMode(global: OperatingMode): OperatingMode\n}\n\nexport async function readStatus(sources: StatusSources): Promise<StatusSnapshot> {\n const [settings, health, receipts, parked] = await Promise.all([\n sources.settings(),\n readSharedHealth(sources.health.file),\n readReceipts(sources.receipts),\n readParked(sources.parked),\n ])\n const refs = TIERS.flatMap((tier) => [...settings.tiers[tier]])\n const capacity = await readCapacity(sources.capacity, refs)\n const registry = new ResourceHealthRegistry(\n sources.health.clock,\n DEFAULT_HEALTH_CONFIG,\n sources.health.newId,\n )\n registry.restore(health)\n // Core status rows are leaf-keyed. Project inherited blockers to each row,\n // without changing the shared health or claiming a half-open probe.\n const projected = refs.flatMap((ref) => {\n const key = {\n providerID: ref.providerID,\n modelID: ref.id,\n ...(ref.variant === undefined ? {} : { variantID: ref.variant }),\n }\n const assessment = registry.evaluate(key)\n const record = registry.recordFor(assessment.kind === \"blocked\" ? assessment.key : key)\n return record === undefined ? [] : [{ ...record, key }]\n })\n return buildStatus({\n settings: { ...settings, mode: sources.effectiveMode(settings.mode) },\n health: projected,\n capacity: capacity.readings,\n parked: parked.length,\n waiting: parked.map((record) => ({\n sessionID: record.session,\n tier: record.tier,\n resumeAt: record.due,\n })),\n receipts: receipts.length,\n })\n}\n","import {\n parseKey,\n replaceControlCharacters,\n visibleWidth,\n wrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\"\nimport type { AdaptiveView } from \"@coool/adaptive-core/flow/controller\"\nimport type { SelectOption } from \"@coool/adaptive-core/flow/options\"\nimport { fitLine } from \"./entries.js\"\n\ninterface Component {\n render(width: number): string[]\n handleInput(data: string): void\n invalidate(): void\n}\ninterface DialogHost {\n readonly mode: string\n readonly ui: {\n select(title: string, choices: string[]): Promise<string | undefined>\n confirm(title: string, message: string): Promise<boolean>\n input(title: string, placeholder?: string): Promise<string | undefined>\n notify(message: string, type: \"info\" | \"error\"): void\n custom<T>(\n factory: (\n tui: { requestRender(): void; terminal: { rows: number } },\n theme: unknown,\n keys: unknown,\n done: (result: T) => void,\n ) => Component,\n ): Promise<T>\n }\n}\n/**\n * Pi draws a two-line footer under a dialog and mis-renders (drops the dialog's last line) a\n * frame exactly as tall as the terminal, so a dialog keeps one spare row.\n */\nfunction available(rows: number): number {\n return rows - 3\n}\ninterface PickResult<T> {\n picked: T | undefined\n action: string | undefined\n}\n\n/** Wrapping keeps whole model names and remedies readable; continuations keep the line's indent. */\nfunction wrap(lines: readonly string[], width: number): string[] {\n return lines.flatMap((raw) => {\n const line = replaceControlCharacters(raw)\n const indent = Math.min(line.length - line.trimStart().length, Math.max(0, width - 1))\n const pad = \" \".repeat(indent)\n return wrapTextWithAnsi(line.slice(indent), Math.max(1, width - indent)).map(\n (part) => `${pad}${part}`,\n )\n })\n}\n\n/** Search and page actions stay keyboard-accessible without becoming fake model rows. */\nexport function picker<T>(\n title: string,\n options: readonly SelectOption<T>[],\n actions: readonly { title: string; value: string; bind: string }[],\n height: number,\n done: (result: PickResult<T>) => void,\n refresh: () => void,\n): Component {\n let query = \"\"\n let selected = 0\n const filtered = () =>\n options.filter((option) =>\n `${option.title} ${option.description ?? \"\"}`.toLowerCase().includes(query.toLowerCase()),\n )\n return {\n render(width) {\n const rows = filtered()\n const headings = wrap(title.split(\"\\n\"), width)\n const count = Math.max(1, available(height) - headings.length - actions.length - 2)\n const offset = Math.max(0, selected - count + 1)\n return [\n ...headings,\n `Search: ${query}`,\n ...rows\n .slice(offset, offset + count)\n .map(\n (row, index) =>\n `${offset + index === selected ? \">\" : \" \"} ${row.title}${row.description === undefined ? \"\" : ` — ${row.description}`}`,\n ),\n ...(rows.length === 0 ? [\"No matches\"] : []),\n `${String(rows.length)} ${rows.length === 1 ? \"choice\" : \"choices\"} · Enter select · Esc back`,\n ...actions.map((action) => `${action.bind}: ${action.title}`),\n ].map((line) => fitLine(line, width))\n },\n handleInput(data) {\n const key = parseKey(data)\n const action = actions.find((candidate) => candidate.bind === key)\n if (action !== undefined) {\n done({ picked: undefined, action: action.value })\n return\n }\n if (key === \"escape\") {\n done({ picked: undefined, action: undefined })\n return\n }\n const rows = filtered()\n if (key === \"enter\") {\n done({ picked: rows[selected]?.value, action: undefined })\n return\n }\n if (key === \"up\") selected = Math.max(0, selected - 1)\n else if (key === \"down\") selected = Math.min(Math.max(0, rows.length - 1), selected + 1)\n else if (key === \"backspace\") {\n query = query.slice(0, -1)\n selected = 0\n } else if (/^[^\\p{C}]+$/u.test(data)) {\n query = `${query}${data}`.slice(0, 128)\n selected = 0\n }\n refresh()\n },\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n}\n\nexport function piView(host: DialogHost): AdaptiveView {\n async function select<T>(\n title: string,\n options: readonly SelectOption<T>[],\n actions: readonly { title: string; value: string; bind: string }[] = [],\n ): Promise<PickResult<T>> {\n if (host.mode === \"tui\")\n return host.ui.custom<PickResult<T>>((tui, _theme, _keys, done) =>\n picker(title, options, actions, tui.terminal.rows, done, () => {\n tui.requestRender()\n }),\n )\n const search =\n options.length > 20\n ? await host.ui.input(title, \"Search provider / model / name (empty shows all)\")\n : \"\"\n if (search === undefined) return { picked: undefined, action: undefined }\n const visible = options.filter((option) =>\n `${option.title} ${option.description ?? \"\"}`.toLowerCase().includes(search.toLowerCase()),\n )\n const labels = visible.map(\n (option, index) =>\n `${String(index + 1)}. ${option.title}${option.description === undefined ? \"\" : ` — ${option.description}`}`,\n )\n const actionLabels = actions.map((action) => `${action.bind}: ${action.title}`)\n const chosen = await host.ui.select(title, [...labels, ...actionLabels])\n const index = chosen === undefined ? -1 : labels.indexOf(chosen)\n const actionIndex = chosen === undefined ? -1 : actionLabels.indexOf(chosen)\n return { picked: visible[index]?.value, action: actions[actionIndex]?.value }\n }\n async function text(\n title: string,\n lines: readonly string[],\n compact: readonly string[] = lines,\n ): Promise<void> {\n if (host.mode !== \"tui\") {\n await host.ui.select(`${title}\\n${compact.join(\"\\n\")}`, [\"Back\"])\n return\n }\n await host.ui.custom<undefined>((tui, _theme, _keys, done) => {\n let offset = 0\n let total = Math.max(lines.length, compact.length)\n const count = Math.max(1, available(tui.terminal.rows) - 2)\n return {\n render(width) {\n const shown = wrap(\n lines.some((line) => visibleWidth(line) > width) ? compact : lines,\n width,\n )\n total = shown.length\n offset = Math.min(offset, Math.max(0, total - count))\n return [\n title,\n ...shown.slice(offset, offset + count),\n \"↑/↓ scroll · Enter or Esc back\",\n ].map((line) => fitLine(line, width))\n },\n handleInput(data) {\n const key = parseKey(data)\n if (key === \"escape\" || key === \"enter\") {\n done(undefined)\n return\n }\n if (key === \"up\") offset = Math.max(0, offset - 1)\n if (key === \"down\") offset = Math.min(Math.max(0, total - count), offset + 1)\n tui.requestRender()\n },\n invalidate() {\n /* Rendering is uncached; there is no stale output to discard. */\n },\n }\n })\n }\n return {\n select: async (spec) => (await select(spec.title, spec.options)).picked,\n selectPaged: (spec) => select(spec.title, spec.options, spec.actions),\n confirm: (spec) => host.ui.confirm(spec.title, spec.message),\n alert: (spec) => text(spec.title, spec.message.split(\"\\n\")),\n table: (spec) => text(spec.title, spec.lines, spec.compactLines),\n toast: (message, variant) => {\n host.ui.notify(message, variant === \"error\" ? \"error\" : \"info\")\n },\n }\n}\n","import type {\n ExtensionAPI,\n ExtensionContext,\n ModelChangeEntry,\n} from \"@earendil-works/pi-coding-agent\"\nimport type { AdaptiveEnv } from \"@coool/adaptive-core/flow/controller\"\nimport { TIERS } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { ModelRef } from \"@coool/adaptive-core/routing/work-unit/types\"\nimport { resetResourceHealth } from \"../health-actions.js\"\nimport { effectiveMode } from \"../session.js\"\nimport { readSettings, updateSettings } from \"../settings.js\"\nimport type { JsonFile } from \"../store.js\"\nimport { PI_COPY } from \"../ui/copy.js\"\nimport { DEFAULT_MODEL_HELP, preferencesAction, toolSupportAction } from \"./actions.js\"\nimport { registerCommands } from \"./commands.js\"\nimport { controlApi } from \"./control.js\"\nimport { doctorChecks } from \"./doctor.js\"\nimport type { AdaptiveSources } from \"./extension.js\"\nimport { availablePhysicalModels, modelSummaries, proposalModels } from \"./inventory.js\"\nimport { editTierProposal, runOnboarding } from \"./onboarding.js\"\nimport type { parkingHandlers } from \"./parking.js\"\nimport { readStatus } from \"./status.js\"\nimport { piView } from \"./view.js\"\n\n/** What only the packaged entry knows: the writable files and the Pi version. */\nexport interface HostSources {\n readonly settings: JsonFile\n readonly capabilities: JsonFile\n readonly version: string\n readonly minimum: string\n readonly testedUpTo: string | undefined\n}\n\ntype Host = Pick<ExtensionAPI, \"registerCommand\" | \"registerShortcut\" | \"appendEntry\" | \"setModel\">\n\n/** The `/adaptive` command, its shortcut, and the one-time first-run offer. */\nexport function adaptiveSurface(\n pi: Host,\n sources: AdaptiveSources,\n host: HostSources,\n parking: Pick<ReturnType<typeof parkingHandlers>, \"resume\" | \"cancel\">,\n feedback: (ctx: ExtensionContext) => () => Promise<void>,\n): { onboard(ctx: ExtensionContext): Promise<void> } {\n const select = async (ctx: ExtensionContext, ref: ModelRef): Promise<boolean> => {\n const model = ctx.modelRegistry.find(ref.providerID, ref.id)\n return model !== undefined && (await pi.setModel(model))\n }\n const environment = (ctx: ExtensionContext): Promise<AdaptiveEnv> => {\n const session = ctx.sessionManager.getSessionId()\n const refresh = async (): Promise<void> => {\n // A successful mode change may select a model and invalidate the old\n // footer binding. Rebind to the resulting model, but never a new session.\n if (ctx.sessionManager.getSessionId() === session) await feedback(ctx)()\n }\n const view = piView(ctx)\n const branch = () => ctx.sessionManager.getBranch()\n const control = controlApi({\n settings: host.settings,\n receipts: sources.receipts,\n sessionID: ctx.sessionManager.getSessionId(),\n branch,\n model: () => ctx.model,\n manualModel: () => {\n const change = branch().findLast(\n (entry): entry is ModelChangeEntry =>\n entry.type === \"model_change\" && entry.provider !== \"adaptive\",\n )\n return change === undefined\n ? undefined\n : { providerID: change.provider, id: change.modelId }\n },\n selectModel: (ref) => select(ctx, ref),\n append: (type, data) => {\n pi.appendEntry(type, data)\n },\n idle: () => ctx.isIdle(),\n status: () =>\n readStatus({\n settings: () => readSettings(host.settings),\n health: sources.health,\n capacity: sources.capacity,\n receipts: sources.receipts,\n parked: sources.parking.file,\n effectiveMode: (global) => effectiveMode(ctx.model, global, branch()),\n }),\n })\n const api = {\n ...control,\n async setSettings(patch: Parameters<typeof control.setSettings>[0]) {\n const result = await control.setSettings(patch)\n if (result.ok) await refresh()\n return result\n },\n async setSessionMode(...args: Parameters<typeof control.setSessionMode>) {\n const result = await control.setSessionMode(...args)\n if (result.ok) await refresh()\n return result\n },\n }\n const configured = async () => {\n const settings = await readSettings(host.settings)\n return TIERS.flatMap((tier) => [...settings.tiers[tier]])\n }\n return Promise.resolve({\n copy: PI_COPY,\n api,\n view,\n models: () => modelSummaries(availablePhysicalModels(ctx.modelRegistry)),\n sessionID: ctx.sessionManager.getSessionId(),\n clock: sources.parking.clock,\n actions: {\n resetHealth: (ref) => resetResourceHealth(sources.health.file, ref),\n resume: () => parking.resume(ctx),\n cancel: () => parking.cancel(ctx),\n tools: async () => {\n await toolSupportAction(\n view,\n host.capabilities,\n await configured(),\n await sources.capabilities(),\n )\n },\n doctor: () =>\n doctorChecks({\n version: host.version,\n minimum: host.minimum,\n testedUpTo: host.testedUpTo,\n registry: ctx.modelRegistry,\n settings: () => readSettings(host.settings),\n capabilities: sources.capabilities,\n // An update that changes nothing still takes the exclusive lock.\n storage: () => host.settings.update(() => ({ next: undefined, result: undefined })),\n status: api.status,\n }),\n preferences: () => preferencesAction(view, sources.preferences),\n defaults: () =>\n view.alert({ title: \"Use Adaptive for new sessions\", message: DEFAULT_MODEL_HELP }),\n },\n })\n }\n registerCommands<ExtensionContext>(pi, { env: environment })\n return {\n async onboard(ctx) {\n const env = await environment(ctx)\n await runOnboarding({\n hasUI: ctx.hasUI,\n api: {\n settings: () => readSettings(host.settings),\n setSettings: (patch) => updateSettings(host.settings, patch),\n },\n view: env.view,\n models: () => proposalModels(availablePhysicalModels(ctx.modelRegistry)),\n edit: (draft) => editTierProposal(env, draft),\n activate: () => select(ctx, { providerID: \"adaptive\", id: \"auto\" }),\n })\n },\n }\n}\n","import { stripVTControlCharacters } from \"node:util\"\nimport type { ExtensionContext } from \"@earendil-works/pi-coding-agent\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\n\nexport type RoutingStatus =\n | {\n readonly kind: \"routing\" | \"recovering\" | \"escalated\"\n readonly tier: TierName\n readonly model: string\n }\n | { readonly kind: \"observing\"; readonly tier: TierName }\n | { readonly kind: \"degraded\" | \"setup\" }\n\ninterface StatusContext {\n readonly hasUI?: boolean\n readonly ui?: Pick<ExtensionContext[\"ui\"], \"setStatus\">\n}\n\nexport interface RoutingFeedback {\n show(state: RoutingStatus): void\n dispatched(\n model: { readonly id: string },\n info: {\n readonly tier: TierName\n readonly retry: boolean\n readonly state: { readonly escalations: number; readonly restarts: number } | undefined\n },\n ): void\n}\n\nfunction statusText(state: RoutingStatus): string {\n switch (state.kind) {\n case \"routing\":\n return `${state.tier} | ${state.model}`\n case \"recovering\":\n return `Recovering ${state.tier} | ${state.model}`\n case \"escalated\":\n return `Escalated ${state.tier} | ${state.model}`\n case \"observing\":\n return `Observing | would use ${state.tier}`\n case \"degraded\":\n return \"Adaptive degraded | /adaptive doctor\"\n case \"setup\":\n return \"Adaptive: set up tiers | /adaptive\"\n }\n}\n\nfunction terminalText(text: string): string {\n // Provider model IDs are untrusted. ASCII bounds cells as well as characters,\n // leaving room beside Pi's own footer at the supported 60-column minimum.\n const safe = stripVTControlCharacters(text).replace(/[^\\x20-\\x7e]/g, \"?\")\n return safe.length <= 48 ? safe : `${safe.slice(0, 45)}...`\n}\n\n/** One footer key: parking overrides routing until parking clears its status. */\nexport function createStatusChip() {\n let generation = 0\n let routing: string | undefined\n let parking: string | undefined\n let owner: StatusContext[\"ui\"]\n const paint = (ui: StatusContext[\"ui\"], text: string | undefined): void => {\n try {\n ui?.setStatus(\"adaptive\", text)\n } catch (error) {\n logFailOpen(\"status\", error)\n }\n }\n const reset = (): void => {\n generation += 1\n routing = undefined\n parking = undefined\n paint(owner, undefined)\n owner = undefined\n }\n\n return {\n /** Reset before model/session changes and shutdown, not on tool continuations. */\n reset,\n /** Capture before awaiting work; old callbacks cannot repaint a new session. */\n connect<T extends StatusContext>(ctx: T) {\n const owned = generation\n const ui = ctx.hasUI ? ctx.ui : undefined\n let degraded = false\n const render = () => {\n owner = ui\n paint(ui, parking ?? routing)\n }\n const show = (state: RoutingStatus): void => {\n if (owned !== generation) return\n if (state.kind === \"degraded\") degraded = true\n routing = terminalText(statusText(state))\n render()\n }\n const setStatus = (key: string, text: string | undefined): void => {\n if (owned !== generation) return\n if (key !== \"adaptive\") {\n ui?.setStatus(key, text)\n return\n }\n // Do not reformat parking's countdown or resume time. It owns that copy.\n parking = text\n render()\n }\n // Pi contexts have live getters (notably model/sessionManager). A plain\n // spread would freeze them while a command is selecting another model.\n const context = Object.defineProperties(\n { ...ctx },\n {\n ...Object.getOwnPropertyDescriptors(ctx),\n ...(ctx.ui === undefined\n ? {}\n : {\n ui: { value: { ...ctx.ui, setStatus }, enumerable: true, configurable: true },\n }),\n },\n )\n return {\n context,\n clear(): void {\n if (owned === generation) reset()\n },\n show,\n /** Call only after admission, never for a preview or a parked route. */\n dispatched(\n model: { readonly id: string },\n info: {\n readonly tier: TierName\n readonly retry: boolean\n readonly state: { readonly escalations: number; readonly restarts: number } | undefined\n },\n ): void {\n if (owned !== generation) return\n parking = undefined\n if (degraded) {\n show({ kind: \"degraded\" })\n return\n }\n let kind: \"routing\" | \"recovering\" | \"escalated\" = \"routing\"\n if (info.retry || (info.state?.restarts ?? 0) > 0) kind = \"recovering\"\n else if ((info.state?.escalations ?? 0) > 0) kind = \"escalated\"\n show({\n kind,\n tier: info.tier,\n model: model.id,\n })\n },\n /** Substitute only this method in parking's ctx.ui; keep its other methods. */\n setStatus,\n }\n },\n }\n}\n","import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\"\nimport { CONTINUATION_PROMPT } from \"@coool/adaptive-core/execution/continuation/prompts\"\nimport { ESCALATION_TOOL_NAME } from \"@coool/adaptive-core/execution/escalation/index\"\nimport { logFailOpen } from \"@coool/adaptive-core/log\"\nimport type { Decision } from \"@coool/adaptive-core/routing/scheduler/types\"\nimport type { TierName } from \"@coool/adaptive-core/routing/tier-policy/types\"\nimport type { SettingsV1 } from \"@coool/adaptive-core/state/settings/types\"\nimport type { ReceiptOutcome } from \"@coool/adaptive-core/state/receipts/types\"\nimport { readPreferences } from \"../preferences.js\"\nimport { attachReceiptOutcome, recordReceipt } from \"../receipts.js\"\nimport { effectiveMode, requestedTier } from \"../session.js\"\nimport type { JsonFile, JsonTransactionFile } from \"../store.js\"\nimport { decisionNote, pausedNote, shouldWriteNote, type AdaptiveNote } from \"../ui/notes.js\"\nimport { observeOutcome, withHealth, type SharedHealth } from \"../health.js\"\nimport type { ToolCapability } from \"../capabilities.js\"\nimport type { ParkingSources } from \"../parking.js\"\nimport type { SharedCapacity } from \"../capacity.js\"\nimport { dispatchCapacity } from \"./dispatch-capacity.js\"\nimport { appendNote, registerEntries } from \"./entries.js\"\nimport { observeInput, type NoteTracker } from \"./observe.js\"\nimport {\n CONTINUATION_TYPE,\n escalationAfterRun,\n restartAfterRun,\n parkingAfterRun,\n servedTask,\n type BranchEntry,\n type Recovery,\n} from \"../task.js\"\nimport { escalationTool, selectedVirtual, tierTool } from \"./tools.js\"\nimport { physical, virtualModels, type RouteContext } from \"./routing.js\"\nimport { parkingHandlers } from \"./parking.js\"\nimport { adaptiveSurface, type HostSources } from \"./adaptive.js\"\nimport { createStatusChip } from \"./status-chip.js\"\n\nexport interface AdaptiveSources {\n readonly settings: () => Promise<SettingsV1>\n readonly capabilities: () => Promise<readonly ToolCapability[]>\n readonly newId: () => string\n readonly health: SharedHealth\n readonly parking: ParkingSources\n readonly capacity: SharedCapacity\n readonly receipts: JsonTransactionFile\n readonly preferences: JsonFile\n}\n\ntype Host = Pick<\n ExtensionAPI,\n | \"registerVirtualModel\"\n | \"getActiveTools\"\n | \"registerTool\"\n | \"on\"\n | \"sendMessage\"\n | \"sendUserMessage\"\n | \"appendEntry\"\n | \"registerCommand\"\n | \"registerShortcut\"\n | \"setModel\"\n | \"registerEntryRenderer\"\n>\n\nexport interface SettleContext extends Omit<RouteContext, \"ui\"> {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly hasUI: boolean\n readonly ui: { notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void }\n}\n\nexport function registerAdaptive(pi: Host, sources: AdaptiveSources, host: HostSources): void {\n const capacity = dispatchCapacity(sources.capacity)\n const status = createStatusChip()\n const refreshStatus = (ctx: ExtensionContext) => {\n const feedback = status.connect(ctx)\n return async (): Promise<void> => {\n if (!ctx.hasUI) return\n try {\n const current = await sources.settings()\n const branch = ctx.sessionManager.getBranch()\n const id = selectedVirtual(ctx.model)\n const mode = effectiveMode(ctx.model, current.mode, branch)\n const tier = id === undefined || id === \"auto\" ? (requestedTier(branch) ?? \"standard\") : id\n if (ctx.model === undefined || mode === \"off\") feedback.clear()\n else if (id === undefined && mode === \"observe\") feedback.show({ kind: \"observing\", tier })\n else if (current.tiers[tier].length === 0) feedback.show({ kind: \"setup\" })\n } catch (error) {\n feedback.show({ kind: \"degraded\" })\n logFailOpen(\"status\", error)\n }\n }\n }\n const tracker: NoteTracker = { last: undefined }\n const dispatched: DispatchTracker = { last: undefined }\n /** Every routed turn writes its decision and keeps the outcome attached (ADP-030). */\n const dispatchRecord = async (\n info: {\n decision: Decision\n unit: string | undefined\n tier: TierName\n session: string | undefined\n retry: boolean\n },\n model: { readonly provider: string; readonly id: string },\n ): Promise<void> => {\n if (info.session === undefined) return\n const receipt = await recordReceipt(sources.receipts, {\n at: sources.health.clock(),\n sessionID: info.session,\n unitID: info.unit,\n tier: info.tier,\n decision: info.decision,\n })\n if (info.decision.kind === \"apply\")\n dispatched.last = {\n unit: info.unit,\n session: info.session,\n provider: model.provider,\n model: model.id,\n }\n const { verbosity } = await readPreferences(sources.preferences)\n if (!shouldWriteNote(verbosity, info.decision, tracker.last)) return\n const note: AdaptiveNote = {\n version: 1,\n text: decisionNote(info.decision, info.tier, info.retry),\n receiptID: receipt.id,\n }\n appendNote(pi, note)\n tracker.last = info.decision\n }\n registerEntries(pi)\n const pausedAt = async (model: { readonly provider: string; readonly id: string }) => {\n try {\n const { verbosity } = await readPreferences(sources.preferences)\n if (verbosity === \"quiet\") return\n appendNote(pi, { version: 1, text: pausedNote(model) })\n tracker.last = undefined\n } catch (error) {\n logFailOpen(\"notes\", error)\n }\n }\n const parking = parkingHandlers(pi, sources, tracker)\n const surface = adaptiveSurface(\n pi,\n sources,\n host,\n {\n resume: (ctx) => parking.resume(status.connect(ctx).context),\n cancel: (ctx) => parking.cancel(status.connect(ctx).context),\n },\n refreshStatus,\n )\n pi.on(\"input\", async (event, ctx) => {\n const feedback = status.connect(ctx)\n const parked = await parking.input(event, feedback.context)\n if (parked.action === \"handled\") return parked\n return observeInput(pi, sources, tracker, () => feedback.show)(event, ctx)\n })\n pi.on(\"model_select\", async (event, ctx) => {\n status.reset()\n const feedback = status.connect(ctx)\n const refresh = refreshStatus(ctx)\n if (selectedVirtual(event.model) === undefined) {\n capacity.clear()\n // Only leaving Adaptive is news; startup and restored sessions are not.\n if (selectedVirtual(event.previousModel) !== undefined) await pausedAt(event.model)\n }\n await parking.modelSelect(event.model, feedback.context)\n await refresh()\n })\n pi.on(\"session_start\", async (_event, ctx) => {\n status.reset()\n const feedback = status.connect(ctx)\n const refresh = refreshStatus(ctx)\n capacity.clear()\n tracker.last = undefined\n await refresh()\n await parking.sessionStart(feedback.context)\n try {\n await surface.onboard(ctx)\n } catch (error) {\n logFailOpen(\"onboarding\", error)\n }\n })\n pi.on(\"session_tree\", async (_event, ctx) => {\n status.reset()\n await refreshStatus(ctx)()\n })\n // Receipt writes run beside the turn; settling them before the outcome is\n // attached and before the session goes away keeps both ordered and never\n // touches a replaced session context.\n let pending: Promise<void> = Promise.resolve()\n pi.on(\"session_shutdown\", async () => {\n status.reset()\n parking.shutdown()\n await pending\n })\n for (const definition of virtualModels(\n sources,\n () => pi.getActiveTools(),\n parking,\n (model, info) => {\n capacity.selected(model.provider)\n pending = pending.then(() =>\n dispatchRecord(info, model).catch((error: unknown) => {\n logFailOpen(\"receipts\", error)\n }),\n )\n },\n (ctx) => status.connect(ctx),\n ))\n pi.registerVirtualModel(definition)\n pi.registerTool(tierTool(sources.settings))\n pi.registerTool(\n escalationTool(\n sources.settings,\n async () => (await readPreferences(sources.preferences)).escalateFromPinned,\n ),\n )\n pi.on(\"message_end\", async (event, ctx) => {\n if (event.message.role === \"assistant\") capacity.clear()\n await pending\n await recordOutcome(event.message, ctx, sources, dispatched)\n })\n pi.on(\"after_provider_response\", (event) => capacity.response(event.headers))\n pi.on(\"agent_settled\", (event, ctx) => {\n capacity.clear()\n const feedback = status.connect(ctx)\n return afterRun(\n event,\n ctx,\n sources,\n (message) => {\n pi.sendMessage(message, { triggerTurn: true })\n },\n (recovery) => parking.recover(recovery, feedback.context),\n (task) => parking.clearServed(task, feedback.context),\n )\n })\n}\n\nexport interface OutcomeContext {\n readonly model: { readonly provider: string; readonly id: string } | undefined\n readonly sessionManager: { getBranch(): readonly BranchEntry[] }\n}\n\n/** The routed dispatch whose receipt outcome is still pending. */\nexport interface DispatchTracker {\n last:\n | {\n readonly unit: string | undefined\n readonly session: string\n readonly provider: string\n readonly model: string\n }\n | undefined\n}\n\ninterface DispatchedMessage {\n readonly role: string\n readonly provider?: string\n readonly model?: string\n readonly stopReason?: string\n readonly errorMessage?: string\n}\n\n/** Record before Pi retries, so re-admission already sees the failure. */\nexport async function recordOutcome(\n message: DispatchedMessage,\n ctx: OutcomeContext,\n sources: AdaptiveSources,\n dispatched: DispatchTracker = { last: undefined },\n): Promise<void> {\n const { provider, model, stopReason } = message\n if (\n message.role !== \"assistant\" ||\n provider === undefined ||\n provider === \"adaptive\" ||\n model === undefined ||\n stopReason === undefined\n )\n return\n try {\n const settings = await sources.settings()\n // OFF never learns: a manual model the user parked away stays untouched.\n if (effectiveMode(ctx.model, settings.mode, ctx.sessionManager.getBranch()) === \"off\") return\n const classification = await withHealth(sources.health, (registry) =>\n observeOutcome(\n registry,\n { providerID: provider, id: model },\n { stopReason, errorMessage: message.errorMessage },\n ),\n )\n const last = dispatched.last\n if (last === undefined) return\n if (last.provider !== provider || last.model !== model) return\n let outcome: ReceiptOutcome = { status: \"succeeded\" }\n if (stopReason === \"aborted\") outcome = { status: \"interrupted\", reason: \"user\" }\n else if (stopReason === \"error\" && classification !== undefined)\n outcome = { status: \"failed\", category: classification.category }\n await attachReceiptOutcome(\n sources.receipts,\n { sessionID: last.session, unitID: last.unit },\n outcome,\n )\n } catch (error) {\n logFailOpen(\"health\", error)\n }\n}\n\ninterface ContinuationMessage {\n readonly customType: string\n readonly content: string\n readonly display: false\n readonly details: unknown\n}\n\nfunction recoveryNotice(recovery: Recovery, escalated: boolean): string {\n if (escalated) return `Adaptive: the task needs more capability; continuing on ${recovery.tier}.`\n const failed = recovery.tried.map((ref) => ref.id).join(\", \")\n return failed === \"\"\n ? `Adaptive: the request failed; continuing on ${recovery.tier}.`\n : `Adaptive: ${failed} failed; continuing on another ${recovery.tier} model.`\n}\n\n/** Terminal recovery is owned by this handler, never a replay of user input. */\nexport async function afterRun(\n event: { readonly aborted: boolean },\n ctx: SettleContext,\n sources: AdaptiveSources,\n send: (message: ContinuationMessage) => void,\n park?: (recovery: Recovery) => Promise<boolean>,\n /** Called for a wake lineage whose run just finished successfully. */\n clear?: (task: string) => Promise<void>,\n): Promise<void> {\n const id = selectedVirtual(ctx.model)\n if (event.aborted || id === undefined) return\n try {\n const settings = await sources.settings()\n const branch = ctx.sessionManager.getBranch()\n const input = {\n id,\n escalateFromPinned: (await readPreferences(sources.preferences)).escalateFromPinned,\n settings: { ...settings, mode: effectiveMode(ctx.model, settings.mode, branch) },\n branch,\n available: physical(ctx.modelRegistry).map((model) => ({\n providerID: model.provider,\n id: model.id,\n })),\n tool: ESCALATION_TOOL_NAME,\n newId: sources.newId,\n }\n const escalation = escalationAfterRun(input)\n const recovery = escalation ?? restartAfterRun(input)\n if (recovery === undefined) {\n const waiting = parkingAfterRun(input)\n if (waiting !== undefined) {\n await park?.(waiting)\n return\n }\n // A resumed lineage that finished leaves a stale park behind when its\n // re-dispatch had to park through a still-blocked window before the\n // follow-up turn succeeded. Drop it so the chip does not promise work\n // that no longer exists.\n const task = servedTask(input)\n if (task !== undefined) await clear?.(task)\n return\n }\n if (await park?.(recovery)) return\n if (ctx.hasUI) ctx.ui.notify(recoveryNotice(recovery, escalation !== undefined))\n send({\n customType: CONTINUATION_TYPE,\n content: CONTINUATION_PROMPT,\n display: false,\n details: recovery,\n })\n } catch (error) {\n logFailOpen(\"escalation\", error)\n }\n}\n","// covers: [\"ADP-059\"]\n/**\n * Shared JSON state for every Pi process on the machine. Pi has no global\n * store and runs subagents as child processes, so health and parking live in\n * files under the agent directory. Each update holds an exclusive lock file\n * across read → change → write and replaces the file atomically, so two\n * processes never interleave a read-modify-write or observe a torn file.\n *\n * Corrupt or unreadable state throws and is never rewritten: callers fail\n * open (route without the state) and leave the file for the user to inspect.\n */\nimport { randomUUID } from \"node:crypto\"\nimport { mkdir, open, readFile, rename, rm, stat, writeFile } from \"node:fs/promises\"\nimport { dirname } from \"node:path\"\n\n// A lock older than this belongs to a crashed process: every holder finishes\n// a read-modify-write of a small file in milliseconds.\nconst STALE_LOCK_MS = 10_000\n// Waiting longer than this for a live holder fails the update (fail-open).\nconst LOCK_TIMEOUT_MS = 1_000\nconst LOCK_RETRY_MS = 10\n\nexport interface JsonFile {\n /** Current value, or `undefined` when the file does not exist. */\n read(): Promise<unknown>\n /**\n * Applies `change` under the lock. A `next` of `undefined` leaves the\n * file untouched (read-only decisions still serialize with writers).\n */\n update<R>(\n change: (current: unknown) => { readonly next: unknown; readonly result: R },\n ): Promise<R>\n}\n\n/** Async core stores must finish their read/modify/write before releasing the lock. */\nexport interface JsonTransactionFile {\n read(): Promise<unknown>\n transaction<R>(\n change: (current: unknown) => Promise<{ readonly next: unknown; readonly result: R }>,\n ): Promise<R>\n}\n\nfunction errorCode(error: unknown): unknown {\n return Reflect.get(Object(error), \"code\")\n}\n\nasync function parse(path: string): Promise<unknown> {\n let text: string\n try {\n text = await readFile(path, \"utf8\")\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") {\n return undefined\n }\n throw error\n }\n try {\n const value: unknown = JSON.parse(text)\n return value\n } catch {\n throw new Error(`Adaptive state: ${path} is not valid JSON`)\n }\n}\n\nasync function acquire(lock: string, clock: () => number): Promise<void> {\n const deadline = clock() + LOCK_TIMEOUT_MS\n for (;;) {\n try {\n const handle = await open(lock, \"wx\")\n await handle.writeFile(String(process.pid))\n await handle.close()\n return\n } catch (error) {\n if (errorCode(error) !== \"EEXIST\") {\n throw error\n }\n }\n // The holder usually released between `open` and `stat`; any failure to\n // inspect the lock just means \"try again until the deadline\".\n const seen = await readFile(lock, \"utf8\").catch(() => undefined)\n const held = await stat(lock).catch(() => undefined)\n if (seen !== undefined && held !== undefined && clock() - held.mtimeMs > STALE_LOCK_MS) {\n // Every waiter judges a crashed holder's lock stale at about the same\n // moment. Only the one whose judgement still describes the file may\n // remove it, or it would delete the fresh lock another waiter just took.\n if ((await readFile(lock, \"utf8\").catch(() => undefined)) === seen)\n await rm(lock, { force: true })\n continue\n }\n if (clock() >= deadline) {\n throw new Error(`Adaptive state: ${lock} is held by another Pi process`)\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS))\n }\n}\n\nexport function jsonFile(\n path: string,\n clock: () => number = Date.now,\n): JsonFile & JsonTransactionFile {\n const lock = `${path}.lock`\n return {\n read: () => parse(path),\n update(change) {\n return this.transaction((current) => Promise.resolve(change(current)))\n },\n async transaction(change) {\n await mkdir(dirname(path), { recursive: true })\n await acquire(lock, clock)\n try {\n const { next, result } = await change(await parse(path))\n if (next !== undefined) {\n const temporary = `${path}.${randomUUID()}.tmp`\n await writeFile(temporary, `${JSON.stringify(next)}\\n`, { mode: 0o600 })\n await rename(temporary, path)\n }\n return result\n } finally {\n await rm(lock, { force: true })\n }\n },\n }\n}\n","import type { ParkingSources } from \"../parking.js\"\n\n// Owned waits must keep print/json alive. TUI timers are cancelled on shutdown.\nexport const timer: ParkingSources[\"timer\"] = (callback, delay) => {\n const handle = setTimeout(callback, delay)\n return () => {\n clearTimeout(handle)\n }\n}\n","","","import { randomUUID } from \"node:crypto\"\nimport { readFile } from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { getAgentDir, VERSION } from \"@earendil-works/pi-coding-agent\"\nimport { applyPatch, defaultSettings } from \"@coool/adaptive-core/state/settings/parse\"\nimport { registerAdaptive } from \"./host/extension.js\"\nimport { loadToolCapabilities } from \"./capabilities.js\"\nimport { jsonFile } from \"./store.js\"\nimport { timer } from \"./host/timer.js\"\nimport baseline from \"../pi-host-baseline.json\" with { type: \"json\" }\nimport matrix from \"../pi-host-matrix.json\" with { type: \"json\" }\n\nexport default function adaptive(pi: Parameters<typeof registerAdaptive>[0]): void {\n const path = join(getAgentDir(), \"adaptive\", \"settings.json\")\n registerAdaptive(\n pi,\n {\n newId: randomUUID,\n capacity: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"capacity.json\")),\n clock: Date.now,\n },\n parking: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"parked.json\")),\n clock: Date.now,\n timer,\n },\n health: {\n file: jsonFile(join(getAgentDir(), \"adaptive\", \"health.json\")),\n clock: Date.now,\n newId: randomUUID,\n },\n receipts: jsonFile(join(getAgentDir(), \"adaptive\", \"receipts.json\")),\n preferences: jsonFile(join(getAgentDir(), \"adaptive\", \"preferences.json\")),\n settings: async () => {\n let text: string\n try {\n text = await readFile(path, \"utf8\")\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return defaultSettings()\n throw error\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n throw new Error(\"Adaptive settings: invalid JSON\")\n }\n const parsed = applyPatch(defaultSettings(), raw)\n if (!parsed.ok) throw new Error(`Adaptive settings: ${parsed.errors.join(\", \")}`)\n return parsed.settings\n },\n capabilities: () =>\n loadToolCapabilities(join(getAgentDir(), \"adaptive\", \"capabilities.json\"), (file) =>\n readFile(file, \"utf8\"),\n ),\n },\n {\n settings: jsonFile(path),\n capabilities: jsonFile(join(getAgentDir(), \"adaptive\", \"capabilities.json\")),\n version: VERSION,\n minimum: matrix.minimum,\n // The last recorded packed-host matrix; a release records its own after verification.\n testedUpTo: baseline.testedUpTo,\n },\n )\n}\n"],"ignoreList":[50,51],"mappings":";;;;;;;;;;;;AAkDA,MAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AC9CA,MAAa,iBAAiB;CAAC;CAAU;CAAQ;AAAW;AAoB5D,MAAa,yBAAwC;CACnD,kBAAkB;CAClB,YAAY;CACZ,cAAc;CACd,gBAAgB;AAClB;AAEA,MAAa,4BAAwD;CACnE;CACA;CACA;AACF;;;;;;;;;;;ACNA,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;AACF;AA6DA,MAAa,wBAA8C;CACzD,SAAS;CACT,0BAA0B;CAC1B,sBAAsB;AACxB;;;;;;;AAWA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;AACF;;;AC1HA,SAAgB,cAAc,KAAiC;CAC7D,IAAI,IAAI,cAAc,KAAA,GACpB,OAAO;CAET,IAAI,IAAI,YAAY,KAAA,GAClB,OAAO;CAET,IAAI,IAAI,cAAc,KAAA,GACpB,OAAO;CAET,OAAO;AACT;;AAGA,SAAgB,cAAc,KAA0B;CACtD,OAAO,KAAK,UAAU;EACpB,IAAI;EACJ,IAAI,aAAa;EACjB,IAAI,WAAW;EACf,IAAI,aAAa;CACnB,CAAC;AACH;;;;;;;;;;AAWA,SAAgB,cAAc,KAAiC;CAC7D,MAAM,QAAuB,CAAC,EAAE,YAAY,IAAI,WAAW,CAAC;CAC5D,IAAI,IAAI,cAAc,KAAA,GACpB,MAAM,KAAK;EAAE,YAAY,IAAI;EAAY,WAAW,IAAI;CAAU,CAAC;CAErE,IAAI,IAAI,YAAY,KAAA,GAClB,MAAM,KACJ,IAAI,cAAc,KAAA,IACd;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;CAAQ,IACnD;EAAE,YAAY,IAAI;EAAY,WAAW,IAAI;EAAW,SAAS,IAAI;CAAQ,CACnF;CAEF,IAAI,IAAI,YAAY,KAAA,KAAa,IAAI,cAAc,KAAA,GACjD,MAAM,KACJ,IAAI,cAAc,KAAA,IACd;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;EAAS,WAAW,IAAI;CAAU,IAC7E;EACE,YAAY,IAAI;EAChB,WAAW,IAAI;EACf,SAAS,IAAI;EACb,WAAW,IAAI;CACjB,CACN;CAEF,OAAO;AACT;;;AC5CA,MAAa,kBAAkB;CAAC;CAAO;CAAW;AAAQ;;AAK1D,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;AAgBA,MAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;AASA,MAAa,eAAe;CAC1B;CACA;CACA;CACA;AACF;;AAKA,MAAa,eAAe;CAC1B;CACA;CACA,GAAG;CACH,GAAG;AACL;;AAwCA,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACA;AACF;AAWA,MAAa,mBAAmB,CAAC,WAAW,MAAM;;AAkElD,SAAgB,mBAAmB,KAAuB;CACxD,OAAO,cACL,IAAI,YAAY,KAAA,IACZ;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;CAAG,IAC9C;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;EAAI,WAAW,IAAI;CAAQ,CAC5E;AACF;;;AC9LA,SAAgB,aAAa,GAAa,GAAsB;CAC9D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE;AAC3E;;;;;;;;;;ACVA,SAAgB,kBAAkB,WAA4C;CAC5E,MAAM,OAAmB,CAAC;CAC1B,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI,SAAS,WAAW,WAAW,KAAK,SAAS,GAAG,WAAW,GAC7D;EAEF,IAAI,KAAK,MAAM,aAAa,aAAa,UAAU,QAAQ,CAAC,GAC1D;EAEF,KAAK,KAAK,QAAQ;CACpB;CACA,OAAO;AACT;;ACfA,MAAa,QAAQ;CAAC;CAAS;CAAY;AAAU;;AAKrD,SAAgB,WAAW,MAAgC;CACzD,OAAO,MAAM,MAAM,SAAS,SAAS,IAAI;AAC3C;;;;;AAoGA,SAAgB,SAAS,MAAsC;CAC7D,MAAM,QAAQ,MAAM,QAAQ,IAAI;CAChC,OAAO,MAAM,QAAQ;AACvB;;;;;;;;;;;;AClGA,SAASA,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;;;;AAUA,SAAS,mBAAmB,OAAwB;CAClD,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,SAAS,KAAK,UAAU,KAAK;EACnC,OAAO,OAAO,SAAS,KAAK,GAAG,OAAO,MAAM,GAAG,EAAE,EAAE,KAAK;CAC1D;CACA,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,OAAO,KAAK;CAChF,OAAO,OAAO;AAChB;AAEA,SAAgB,UAAU,KAAyC;CACjE,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,gBAAgB,MAAM,SAAS,SAAS,GAAG;AACpD;;;;;;AAOA,SAAS,gBAAgB,KAAyC;CAChE,OAAO,QAAQ,YAAY,WAAW,UAAU,GAAG;AACrD;AAEA,SAAgB,eACd,KAC6D;CAC7D,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,QAAQ,CAAC;CACf,KAAK,MAAM,QAAQ,OACjB,MAAM,QAAQ,uBAAuB,IAAI,KAAK;CAEhD,OAAO;AACT;;AAGA,SAAS,uBAAuB,MAAoC;CAClE,OAAO,MAAM,QAAQ,IAAI,IACrB,kBACE,KAAK,IAAI,aAAa,CAAC,CAAC,QAAQ,QAAyB,QAAQ,KAAA,CAAS,CAC5E,CAAC,CAAC,MAAM,GAAA,EAAqB,IAC7B,CAAC;AACP;AAEA,SAAgB,cAAc,KAAoC;CAChE,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,aAAa,IAAI;CACvB,MAAM,KAAK,IAAI;CACf,MAAM,UAAU,IAAI;CACpB,IAAI,OAAO,eAAe,YAAY,eAAe,IAAI,OAAO,KAAA;CAChE,IAAI,OAAO,OAAO,YAAY,OAAO,IAAI,OAAO,KAAA;CAChD,OAAO;EACL;EACA;EACA,GAAI,OAAO,YAAY,YAAY,YAAY,KAAK,EAAE,QAAQ,IAAI,CAAC;CACrE;AACF;AAEA,SAAgB,SAAS,KAA2C;CAClE,IAAI,QAAQ,MAAM,OAAO;CACzB,OAAO,cAAc,GAAG;AAC1B;AAEA,SAAgB,gBAAgB,KAA8D;CAC5F,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,UAAgC,CAAC;CACvC,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,GAAG,GAAG;EAC/C,IAAI,UAAU,IAAI;EAClB,MAAM,SAAS,kBAAkB,IAAI;EACrC,IAAI,WAAW,KAAA,GAAW;EAC1B,QAAQ,KAAK,CAAC,OAAO,MAAM,CAAC;EAC5B,IAAI,QAAQ,WAAA,IAA4B;CAC1C;CAGA,OAAO,OAAO,YAAY,OAAO;AACnC;AAEA,SAAS,kBAAkB,KAAoC;CAC7D,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,MAAM,MAAM,SAAS,SAAS,GAAG;AAC1C;;;;;;;;;AAUA,SAAS,oBACP,KAC6D;CAC7D,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO;EAAE,IAAI;EAAO,OAAO;CAAgB;CAC/D,MAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,UAAU,KAAA,CAAS;CAC9D,IAAI,QAAQ,SAAS,GAEnB,OAAO;EAAE,IAAI;EAAO,OAAO,0BADb,QAAQ,KAAK,SAAS,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,KAAK,IACN;CAAI;CAE/D,MAAM,QAAQ,CAAC;CACf,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,IAAI;EACjB,IAAI,CAAC,MAAM,QAAQ,IAAI,GACrB,OAAO;GAAE,IAAI;GAAO,OAAO,kBAAkB,KAAK,UAAU,IAAI,EAAE;EAAmB;EAEvF,MAAM,QAAQ,uBAAuB,IAAI;CAC3C;CACA,OAAO;EAAE,IAAI;EAAM,OAAO;CAAM;AAClC;;;;;;;;AASA,SAAS,qBAAqB,KAA8D;CAC1F,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO;EAAE,IAAI;EAAO,OAAO;CAAqB;CACpE,MAAM,UAAgC,CAAC;CACvC,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,GAAG,GAAG;EAC/C,IAAI,QAAQ,WAAA,IACV,OAAO;GACL,IAAI;GACJ,OAAO,iCAAiC,OAAA,EAAsB,EAAE;EAClE;EAEF,IAAI,UAAU,IAAI,OAAO;GAAE,IAAI;GAAO,OAAO;EAAuC;EACpF,MAAM,SAAS,kBAAkB,IAAI;EACrC,IAAI,WAAW,KAAA,GACb,OAAO;GACL,IAAI;GACJ,OAAO,4BAA4B,mBAAmB,KAAK,EAAE,IAAI,mBAAmB,IAAI;EAC1F;EAEF,QAAQ,KAAK,CAAC,OAAO,MAAM,CAAC;CAC9B;CAGA,OAAO;EAAE,IAAI;EAAM,OAAO,OAAO,YAAY,OAAO;CAAE;AACxD;;AAGA,SAAgB,kBAA8B;CAC5C,OAAO;EACL,SAAA;EACA,MAAM;EACN,OAAO;GAAE,OAAO,CAAC;GAAG,UAAU,CAAC;GAAG,UAAU,CAAC;EAAE;EAC/C,KAAK;EACL,YAAY,CAAC;EACb,iBAAiB;CACnB;AACF;;;;;;;;AASA,SAAgB,gBAAgB,KAA0B;CACxD,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO,gBAAgB;CAC3C,MAAM,UAAU,IAAI;CACpB,IAAI,YAAA,KAAgC,YAAY,KAAK,YAAY,KAAA,GAC/D,OAAO,gBAAgB;CAEzB,OAAO,WAAW,GAAG;AACvB;AAEA,SAAS,WAAW,KAA0C;CAM5D,OAAO;EAAE,SAAA;EAA2B,MALvB,gBAAgB,IAAI,OAAO,KAAK;EAKH,OAJ5B,eAAe,IAAI,QAAQ,KAAK,gBAAgB,CAAC,CAAC;EAIf,KAHrC,SAAS,IAAI,MAAM,KAAK;EAGkB,YAFnC,gBAAgB,IAAI,aAAa,KAAK,CAAC;EAEQ,iBAD1C,IAAI,uBAAuB;CAC+B;AACpF;;;;;;;;AASA,SAAgB,WACd,SACA,OACsE;CACtE,IAAI,CAACA,WAAS,KAAK,GAAG,OAAO;EAAE,IAAI;EAAO,QAAQ,CAAC,eAAe;CAAE;CACpE,MAAM,UAAU;CAOhB,MAAM,SAAmB,CAAC;CAC1B,IAAI,OAAO,QAAQ;CACnB,IAAI,QAAQ,QAAQ;CACpB,IAAI,MAAM,QAAQ;CAClB,IAAI,aAAa,QAAQ;CACzB,IAAI,kBAAkB,QAAQ;CAE9B,IAAI,QAAQ,SAAS,KAAA,GAAW;EAC9B,MAAM,SAAS,UAAU,QAAQ,IAAI;EACrC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAK,cAAc;OAC/C,OAAO;CACd;CACA,IAAI,QAAQ,UAAU,KAAA,GAAW;EAC/B,MAAM,SAAS,oBAAoB,QAAQ,KAAK;EAChD,IAAI,OAAO,IAAI,QAAQ,OAAO;OACzB,OAAO,KAAK,OAAO,KAAK;CAC/B;CAEA,IAAI,QAAQ,QAAQ,KAAA,GAAW;EAC7B,MAAM,SAAS,SAAS,QAAQ,GAAG;EACnC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAK,aAAa;OAC9C,MAAM;CACb;CACA,IAAI,QAAQ,eAAe,KAAA,GAAW;EACpC,MAAM,SAAS,qBAAqB,QAAQ,UAAU;EACtD,IAAI,OAAO,IAAI,aAAa,OAAO;OAC9B,OAAO,KAAK,OAAO,KAAK;CAC/B;CACA,IAAI,QAAQ,oBAAoB,KAAA,GAAW;EACzC,IAAI,OAAO,QAAQ,oBAAoB,WAAW,OAAO,KAAK,yBAAyB;OAClF,kBAAkB,QAAQ;CACjC;CAEA,IAAI,OAAO,SAAS,GAAG,OAAO;EAAE,IAAI;EAAO;CAAO;CAClD,OAAO;EACL,IAAI;EACJ,UAAU;GAAE,SAAA;GAA2B;GAAM;GAAO;GAAK;GAAY;EAAgB;CACvF;AACF;;;;;;;;ACvQA,MAAa,sBACX;;;ACIF,MAAa,uBAAuB;;;;;;AAepC,SAAgB,gBAAgB,MAAc,KAAqB;CACjE,IAAI,KAAK,UAAU,KAAK,OAAO;CAC/B,MAAM,MAAM,KAAK,MAAM,GAAG,GAAG;CAC7B,MAAM,OAAO,IAAI,WAAW,IAAI,SAAS,CAAC;CAC1C,OAAO,QAAQ,SAAU,QAAQ,QAAS,IAAI,MAAM,GAAG,EAAE,IAAI;AAC/D;;;;;;AAOA,SAAgB,uBAAuB,OAA+C;CACpF,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,MAAM,SAAS;CACf,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,OAAO;CACxB,IAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG,OAAO,KAAA;CAC9D,IAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GAAG,OAAO,KAAA;CAClE,OAAO;EACL,QAAQ,gBAAgB,QAAA,GAAmC;EAC3D,UAAU,gBAAgB,UAAA,GAAqC;CACjE;AACF;;AAGA,SAAgB,iBAAiB,SAAoC;CACnE,OAAO,gBAAgB,GAAG,QAAQ,OAAO,IAAI,QAAQ,YAAA,GAAuC;AAC9F;;;;;;AAOA,MAAa,gCAA4D,CACvE,oBACA,gBACF;;ACrDA,SAAgB,YAAY,OAAe,OAAsB;CAC/D,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC,MAAM,GAAA,GAAmB;CACtD,QAAQ,MAAM,oBAAoB,MAAM,IAAI,QAAQ;AACtD;;ACJA,SAAgBC,SAAO,OAAkD;CACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,OAAsB;CACrC,MAAM,IAAI,MAAM,8BAA8B,OAAO;AACvD;AAEA,SAAS,UAAU,OAAgB,OAAqB;CACtD,IACE,CAACA,SAAO,KAAK,KACb,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC;EAAC;EAAc;EAAM;CAAS,CAAC,CAAC,SAAS,GAAG,CAAC,GAE/E,QAAQ,KAAK;CACf,KAAK,MAAM,OAAO,CAAC,cAAc,IAAI,GAAG;EACtC,MAAM,KAAK,MAAM;EACjB,IAAI,OAAO,OAAO,YAAY,GAAG,KAAK,MAAM,MAAM,GAAG,SAAS,KAAK,QAAQ,KAAK;CAClF;CACA,MAAM,UAAU,MAAM;CACtB,IACE,YAAY,KAAA,MACX,OAAO,YAAY,YAAY,QAAQ,KAAK,MAAM,MAAM,QAAQ,SAAS,MAE1E,QAAQ,KAAK;AACjB;;AAGA,SAAS,SAAS,KAA8B,SAAwB;CACtE,IACE,OAAO,KAAK,GAAG,CAAC,CAAC,MACd,QAAQ,CAAC;EAAC;EAAW;EAAQ;EAAS;EAAO;EAAc;CAAiB,CAAC,CAAC,SAAS,GAAG,CAC7F,GAEA,QAAQ,OAAO;CACjB,MAAM,UAAU,IAAI;CACpB,IAAI,YAAY,KAAA,KAAa,YAAY,KAAK,EAAE,WAAW,YAAY,IAAI,QAAQ,SAAS;CAC5F,MAAM,OAAO,IAAI;CACjB,IACE,SAAS,KAAA,KACT,EAAE,OAAO,SAAS,YAAY;EAAC;EAAO;EAAW;CAAQ,CAAC,CAAC,SAAS,IAAI,MACxE,EAAE,WAAW,SAAS,YAEtB,QAAQ,MAAM;CAChB,IAAI,IAAI,WAAW,KAAA,KAAa,IAAI,WAAW,MAAM,UAAU,IAAI,QAAQ,KAAK;CAChF,IAAI,IAAI,uBAAuB,KAAA,KAAa,OAAO,IAAI,uBAAuB,WAC5E,QAAQ,iBAAiB;CAC3B,MAAM,QAAQ,IAAI;CAClB,IAAI,UAAU,KAAA,GAAW;EACvB,IAAI,CAACA,SAAO,KAAK,KAAK,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC,WAAW,GAAG,CAAC,GAAG,QAAQ,OAAO;EACzF,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAgB,MAAM;GAC5B,IAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAA,IAA6B,QAAQ,SAAS,MAAM;GACrF,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,MAAM,SAAS,MAAM;IACxB,UAAU,OAAO,SAAS,MAAM;IAChC,MAAM,MAAM,KAAK,UAAU,OAAO;KAAC;KAAc;KAAM;IAAS,CAAC;IACjE,IAAI,KAAK,IAAI,GAAG,GAAG,QAAQ,SAAS,MAAM;IAC1C,KAAK,IAAI,GAAG;GACd;EACF;CACF;CACA,MAAM,SAAS,IAAI;CACnB,IAAI,WAAW,KAAA,GAAW;EACxB,IAAI,CAACA,SAAO,MAAM,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC,SAAA,IAA0B,QAAQ,YAAY;EACzF,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,MAAM,GAC/C,IAAI,MAAM,KAAK,MAAM,MAAM,OAAO,SAAS,YAAY,CAAC,WAAW,IAAI,GACrE,QAAQ,YAAY;CAC1B;AACF;AAEA,SAAgB,cAAc,KAA0B;CACtD,IAAI,QAAQ,KAAA,GAAW,OAAO,gBAAgB;CAC9C,IAAI,CAACA,SAAO,GAAG,GAAG,QAAQ,QAAQ;CAClC,SAAS,KAAK,IAAI;CAClB,OAAO,gBAAgB,GAAG;AAC5B;AAEA,eAAsB,aAAa,MAAmD;CACpF,OAAO,cAAc,MAAM,KAAK,KAAK,CAAC;AACxC;AAEA,SAAgB,eAAe,MAAgB,OAAsC;CACnF,OAAO,KAAK,QAAqB,QAAQ;EACvC,MAAM,UAAU,cAAc,GAAG;EACjC,IAAI;GACF,IAAI,CAACA,SAAO,KAAK,GAAG,QAAQ,OAAO;GACnC,SAAS,OAAO,KAAK;EACvB,SAAS,OAAO;GACd,OAAO;IACL,MAAM,KAAA;IACN,QAAQ;KAAE,IAAI;KAAO,QAAQ,CAAC,OAAO,KAAK,CAAC,CAAC,QAAQ,8BAA8B,EAAE,CAAC;IAAE;GACzF;EACF;EACA,MAAM,WAAW,gBAAgB;GAAE,GAAG;GAAS,GAAG;GAAO,SAAS;EAAE,CAAC;EACrE,OAAO;GAAE,MAAM;GAAU,QAAQ;IAAE,IAAI;IAAM;GAAS;EAAE;CAC1D,CAAC;AACH;;ACvGA,MAAa,mBAAmB;CAAC;CAAS;CAAW;AAAK;AAQ1D,SAAS,OAAO,KAAsC;CACpD,IAAI,CAACC,SAAO,GAAG,GAAG,MAAM,IAAI,MAAM,0CAA0C;CAC5E,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,MAAM,QAAQ,CAAC;EAAC;EAAW;EAAa;CAAoB,CAAC,CAAC,SAAS,GAAG,CAAC,GAC9F,MAAM,IAAI,MAAM,qCAAqC;CACvD,IAAI,IAAI,eAAe,KAAA,KAAa,IAAI,eAAe,GACrD,MAAM,IAAI,MAAM,0CAA0C;CAC5D,MAAM,YAAY,iBAAiB,MAAM,UAAU,UAAU,IAAI,YAAY;CAC7E,IAAI,IAAI,iBAAiB,KAAA,KAAa,cAAc,KAAA,GAClD,MAAM,IAAI,MAAM,iEAAiE;CACnF,MAAM,WAAW,IAAI;CACrB,IAAI,aAAa,KAAA,KAAa,OAAO,aAAa,WAChD,MAAM,IAAI,MAAM,6DAA6D;CAC/E,OAAO;EACL,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;EAC/C,GAAI,OAAO,aAAa,YAAY,EAAE,oBAAoB,SAAS,IAAI,CAAC;CAC1E;AACF;AAEA,SAAgB,iBAAiB,KAA6B;CAC5D,OAAO;EACL,SAAS;EACT,WAAW;EACX,oBAAoB;EACpB,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,OAAO,GAAG;CACzC;AACF;AAEA,eAAsB,gBAAgB,MAAsD;CAC1F,OAAO,iBAAiB,MAAM,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAgB,kBAAkB,MAAgB,OAAwC;CACxF,OAAO,KAAK,QAAQ,QAAQ;EAC1B,MAAM,OAAO;GAAE,GAAG,iBAAiB,GAAG;GAAG,GAAG,OAAO,KAAK;EAAE;EAC1D,OAAO;GAAE;GAAM,QAAQ;EAAK;CAC9B,CAAC;AACH;;;;;;;ACvBA,SAAgB,UAAU,KAAqB;CAC7C,OAAO,gBAAgB,KAAA,GAAqB;AAC9C;AAEA,SAAS,SAAS,KAAyB;CACzC,OAAO;EACL,YAAY,UAAU,IAAI,UAAU;EACpC,IAAI,UAAU,IAAI,EAAE;EACpB,GAAI,IAAI,YAAY,KAAA,IAAY,EAAE,SAAS,UAAU,IAAI,OAAO,EAAE,IAAI,CAAC;CACzE;AACF;AAEA,SAAS,WAAW,UAAwC;CAC1D,OAAO;EACL,MAAM;EACN,OAAO,SAAS,SAAS,KAAK;EAC9B,GAAI,SAAS,SAAS,KAAA,IAAY,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;EAC7D,QAAQ,SAAS;EACjB,UAAU;GACR,SAAS,SAAS,SAAS,QAAQ,KAAK,UAAU;IAChD,KAAK,SAAS,KAAK,GAAG;IACtB,KAAK,KAAK;GACZ,EAAE;GACF,GAAI,SAAS,SAAS,YAAY,KAAA,IAC9B,EAAE,SAAS,UAAU,SAAS,SAAS,OAAO,EAAE,IAChD,CAAC;EACP;CACF;AACF;AAEA,SAAS,WAAW,UAAwC;CAC1D,OAAO;EACL,MAAM;EACN,QAAQ,SAAS;EACjB,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,UAAU,SAAS,MAAM,EAAE,IAAI,CAAC;CAChF;AACF;AAEA,SAAS,UAAU,UAAsC;CACvD,OAAO;EACL,MAAM;EACN,QAAQ,SAAS;EACjB,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,UAAU,SAAS,MAAM,EAAE,IAAI,CAAC;CAChF;AACF;AAEA,SAAS,cAAc,UAA8C;CACnE,OAAO;EACL,MAAM;EACN,QAAQ,SAAS,SAAS,MAAM;EAChC,MAAM,SAAS;EACf,MAAM,SAAS;EACf,UAAU,SAAS,SAAS,KAAK,UAAU;GACzC,MAAM,KAAK;GACX,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,QAAQ,UAAU,KAAK,MAAM,EAAE,IAAI,CAAC;EACxE,EAAE;EACF,iBAAiB,SAAS;CAC5B;AACF;AAEA,SAAS,iBAAiB,UAA+B,OAAoC;CAC3F,OAAO;EAAE,MAAM;EAAgB,OAAO,cAAc,SAAS,OAAO,QAAQ,CAAC;CAAE;AACjF;;;;;AAMA,SAAgB,cAAc,UAAoB,QAAQ,GAAa;CACrE,QAAQ,SAAS,MAAjB;EACE,KAAK,SACH,OAAO,WAAW,QAAQ;EAC5B,KAAK,SACH,OAAO,WAAW,QAAQ;EAC5B,KAAK,QACH,OAAO,UAAU,QAAQ;EAC3B,KAAK,YACH,OAAO,cAAc,QAAQ;EAC/B,KAAK,gBACH,OAAO,QAAQ,IAAI,iBAAiB,UAAU,KAAK,IAAI;CAC3D;AACF;;;;;;;ACpGA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;AACF;;ACAA,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;ACcA,SAASC,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,YAAY,KAAkC;CACrD,OAAO,OAAO,QAAQ,WAAW,UAAU,GAAG,IAAI,KAAA;AACpD;AAEA,SAAS,oBAAoB,KAA6B;CACxD,OAAO,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,KAAK,OAAO;AACnE;AAEA,SAASC,aACP,KACA,YACuB;CACvB,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,WAAW,MAAM,UAAU,UAAU,GAAG;AACjD;AAEA,SAAS,UAAU,KAAoC;CACrD,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,MAAM,MAAM,SAAS,SAAS,GAAG;AAC1C;AAEA,SAAS,qBAAqB,KAAkC;CAC9D,MAAM,QAAQ,YAAY,GAAG;CAC7B,OAAO,UAAU,KAAK,KAAA,IAAY;AACpC;;AAGA,SAAS,mBAAmB,KAAkC;CAC5D,OAAO,YAAY,GAAG,KAAK,KAAA;AAC7B;AAEA,SAAS,mBAAmB,KAAqD;CAC/E,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,aAAa,IAAI;CACvB,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG,OAAO,KAAA;CACvC,MAAM,UAA8B,CAAC;CACrC,KAAK,MAAM,SAAS,WAAW,MAAM,GAAG,CAAC,GAAG;EAC1C,IAAI,CAACA,WAAS,KAAK,GAAG;EACtB,MAAM,MAAM,cAAc,MAAM,MAAM;EACtC,MAAM,MAAMC,aAAW,MAAM,QAAQ,YAAY;EACjD,IAAI,QAAQ,KAAA,KAAa,QAAQ,KAAA,GAAW;EAC5C,QAAQ,KAAK;GAAE;GAAK;EAAI,CAAC;CAC3B;CACA,MAAM,UAAU,mBAAmB,IAAI,UAAU;CACjD,OAAO;EAAE;EAAS,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;CAAG;AAClE;AAEA,SAAS,WAAW,KAAyD;CAC3E,MAAM,QAAQ,cAAc,IAAI,QAAQ;CACxC,MAAM,SAASA,aAAW,IAAI,WAAW,aAAa;CACtD,MAAM,WAAW,mBAAmB,IAAI,WAAW;CACnD,IAAI,UAAU,KAAA,KAAa,WAAW,KAAA,KAAa,aAAa,KAAA,GAC9D;CAEF,MAAM,OAAO,UAAU,IAAI,OAAO;CAClC,OAAO;EACL,MAAM;EACN;EACA,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACrC;EACA;CACF;AACF;AAEA,SAAS,WAAW,KAAyD;CAC3E,MAAM,SAASA,aAAW,IAAI,WAAW,uBAAuB;CAChE,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,MAAM,SAAS,mBAAmB,IAAI,SAAS;CAC/C,OAAO;EAAE,MAAM;EAAS;EAAQ,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;CAAG;AAC9E;AAEA,SAAS,UAAU,KAAwD;CACzE,MAAM,SAASA,aAAW,IAAI,WAAW,YAAY;CACrD,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,MAAM,SAAS,mBAAmB,IAAI,SAAS;CAC/C,OAAO;EAAE,MAAM;EAAQ;EAAQ,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;CAAG;AAC7E;AAEA,SAAS,cAAc,KAA4D;CACjF,MAAM,SAAS,cAAc,IAAI,SAAS;CAC1C,MAAM,OAAOA,aAAW,IAAI,SAAS,gBAAgB;CACrD,MAAM,OAAO,UAAU,IAAI,OAAO;CAClC,MAAM,qBAAqB,IAAI;CAC/B,IACE,WAAW,KAAA,KACX,SAAS,KAAA,KACT,SAAS,KAAA,KACT,CAAC,oBAAoB,kBAAkB,GAEvC;CAEF,MAAM,cAAc,IAAI;CACxB,IAAI,CAAC,MAAM,QAAQ,WAAW,GAAG,OAAO,KAAA;CACxC,MAAM,WAAiC,CAAC;CACxC,KAAK,MAAM,SAAS,YAAY,MAAM,GAAG,CAAC,GAAG;EAC3C,IAAI,CAACD,WAAS,KAAK,GAAG;EACtB,MAAM,OAAOC,aAAW,MAAM,SAAS,yBAAyB;EAChE,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,SAAS,mBAAmB,MAAM,SAAS;EACjD,SAAS,KAAK;GAAE;GAAM,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EAAG,CAAC;CACrE;CACA,OAAO;EACL,MAAM;EACN;EACA;EACA;EACA;EACA,iBAAiB;CACnB;AACF;;AAGA,MAAM,kBAAkB;AAExB,SAAS,iBACP,KACA,OACiC;CACjC,IAAI,SAAS,iBAAiB,OAAO,KAAA;CACrC,MAAM,QAAQ,cAAc,IAAI,UAAU,QAAQ,CAAC;CACnD,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY;EAAE,MAAM;EAAgB;CAAM;AACzE;AAEA,SAAS,cAAc,KAAc,QAAQ,GAAyB;CACpE,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,QAAQ,IAAI,SAAZ;EACE,KAAK,SACH,OAAO,WAAW,GAAG;EACvB,KAAK,SACH,OAAO,WAAW,GAAG;EACvB,KAAK,QACH,OAAO,UAAU,GAAG;EACtB,KAAK,YACH,OAAO,cAAc,GAAG;EAC1B,KAAK,gBACH,OAAO,iBAAiB,KAAK,KAAK;EACpC,SACE;CACJ;AACF;AAEA,SAAS,aAAa,KAA0C;CAC9D,IAAI,CAACA,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,QAAQ,IAAI,WAAZ;EACE,KAAK,aACH,OAAO,EAAE,QAAQ,YAAY;EAC/B,KAAK,UAAU;GACb,MAAM,WAAWC,aAAW,IAAI,aAAa,kBAAkB;GAC/D,OAAO,aAAa,KAAA,IAAY,KAAA,IAAY;IAAE,QAAQ;IAAU;GAAS;EAC3E;EACA,KAAK,eAAe;GAClB,MAAM,SAASA,aAAW,IAAI,WAAW,iBAAiB;GAC1D,OAAO,WAAW,KAAA,IAAY,KAAA,IAAY;IAAE,QAAQ;IAAe;GAAO;EAC5E;EACA,SACE;CACJ;AACF;AAEA,SAAS,aAAa,KAAmC;CACvD,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,KAAK,IAAI;CACf,MAAM,KAAK,IAAI;CACf,MAAM,YAAY,qBAAqB,IAAI,YAAY;CACvD,MAAM,WAAW,cAAc,IAAI,WAAW;CAC9C,IACE,EAAE,oBAAoB,EAAE,KAAK,OAAO,UAAU,EAAE,KAAK,oBAAoB,EAAE,MAC3E,cAAc,KAAA,KACd,aAAa,KAAA,GAEb;CAEF,MAAM,SAAS,qBAAqB,IAAI,SAAS;CACjD,MAAM,OAAO,UAAU,IAAI,OAAO;CAIlC,IAAI;CACJ,IAAI,IAAI,eAAe,KAAA,GAAW;EAChC,UAAU,aAAa,IAAI,UAAU;EACrC,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;CACpC;CACA,OAAO;EACL;EACA;EACA;EACA,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EACzC,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACrC;EACA,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;CAC7C;AACF;;;;;AAMA,SAAgB,qBAAqB,KAAyB;CAC5D,IAAI;CACJ,IAAIA,WAAS,GAAG,GAAG;EACjB,MAAM,UAAU,IAAI;EACpB,IAAI,YAAA,KAAgC,YAAY,KAAA,GAAW,OAAO,CAAC;EACnE,OAAO,IAAI;CACb,OAAO,IAAI,MAAM,QAAQ,GAAG,GAC1B,OAAO;CAET,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO,CAAC;CAClC,MAAM,SAAS,KACZ,IAAI,YAAY,CAAC,CACjB,QAAQ,YAAgC,YAAY,KAAA,CAAS;CAChE,OAAO,OAAO,SAAA,MAAwB,OAAO,MAAM,IAAa,IAAI;AACtE;;;;;;;;;;;;AChOA,IAAa,eAAb,MAA0B;CAKK;CAJ7B,YAAuB,CAAC;CACxB,WAAW;CACX,SAA2B,QAAQ,QAAQ;CAE3C,YAAY,SAA2C;EAA1B,KAAA,UAAA;CAA2B;;CAGxD,OAAsB;EACpB,OAAO,KAAK,iBAAiB,KAAK,MAAM,CAAC;CAC3C;CAEA,MAAM,QAAuB;EAC3B,IAAI;EACJ,IAAI;GACF,MAAM,MAAM,KAAK,QAAQ,KAAK;EAChC,QAAQ;GACN,KAAK,YAAY,CAAC;GAClB;EACF;EACA,MAAM,SAAS,qBAAqB,GAAG;EACvC,KAAK,YAAY;EACjB,KAAK,WAAW,OAAO,QAAQ,KAAK,YAAY,KAAK,IAAI,KAAK,QAAQ,EAAE,GAAG,CAAC;CAC9E;;CAGA,WAA+B;EAC7B,OAAO,KAAK;CACd;CAEA,OAAO,OAAuC;EAC5C,OAAO,KAAK,iBAAiB,KAAK,QAAQ,KAAK,CAAC;CAClD;CAEA,MAAM,QAAQ,OAAuC;EAInD,IAAI,MAAM,UAAU,KAAK,MAAM,IAC7B,MAAM,IAAI,MAAM,uDAAuD;EAEzE,MAAM,KAAK,KAAK,WAAW;EAC3B,MAAM,UAAmB;GACvB;GACA,IAAI,MAAM;GAGV,WAAW,UAAU,MAAM,SAAS;GACpC,GAAI,MAAM,WAAW,KAAA,IAAY,EAAE,QAAQ,UAAU,MAAM,MAAM,EAAE,IAAI,CAAC;GACxE,GAAI,MAAM,SAAS,KAAA,IAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GACvD,UAAU,cAAc,MAAM,QAAQ;EACxC;EACA,MAAM,OACJ,KAAK,UAAU,UAAA,MACX,CAAC,GAAG,KAAK,UAAU,MAAM,IAAgB,GAAG,OAAO,IACnD,CAAC,GAAG,KAAK,WAAW,OAAO;EAGjC,MAAM,KAAK,SAAS,IAAI;EACxB,KAAK,YAAY;EACjB,KAAK,WAAW;EAChB,OAAO;CACT;;;;;;CAOA,cAAc,KAAiB,SAA0C;EACvE,OAAO,KAAK,iBAAiB,KAAK,eAAe,KAAK,OAAO,CAAC;CAChE;CAEA,MAAM,eAAe,KAAiB,SAA0C;EAC9E,IAAI,UAAU;EACd,MAAM,OAAO,KAAK,UAAU,KAAK,YAAY;GAC3C,IAAI,QAAQ,YAAY,KAAA,GAAW,OAAO;GAC1C,IAAI,QAAQ,cAAc,IAAI,WAAW,OAAO;GAGhD,IAAI,EADF,IAAI,WAAW,KAAA,IAAY,QAAQ,WAAW,IAAI,SAAS,QAAQ,WAAW,KAAA,IAClE,OAAO;GACrB;GACA,OAAO;IAAE,GAAG;IAAS;GAAQ;EAC/B,CAAC;EACD,IAAI,YAAY,GAAG,OAAO;EAC1B,MAAM,KAAK,SAAS,IAAI;EACxB,KAAK,YAAY;EACjB,OAAO;CACT;;;;;;;;;;;;CAaA,UAAU,WAAmB,QAAiC;EAC5D,OAAO,KAAK,iBAAiB,KAAK,WAAW,WAAW,MAAM,CAAC;CACjE;CAEA,MAAM,WAAW,WAAmB,QAAiC;EACnE,IAAI;EACJ,KAAK,UAAU,SAAS,SAAS,UAAU;GACzC,IAAI,QAAQ,WAAW,KAAA,KAAa,QAAQ,YAAY,KAAA,GAAW;GACnE,IAAI,QAAQ,cAAc,WAAW;GACrC,SAAS;EACX,CAAC;EACD,IAAI,WAAW,KAAA,GAAW,OAAO;EACjC,MAAM,KAAK;EACX,MAAM,OAAO,KAAK,UAAU,KAAK,SAAS,UACxC,UAAU,KAAK;GAAE,GAAG;GAAS;EAAO,IAAI,OAC1C;EACA,MAAM,KAAK,SAAS,IAAI;EACxB,KAAK,YAAY;EACjB,OAAO;CACT;CAIA,WAAc,WAAyC;EACrD,MAAM,MAAM,KAAK,OAAO,KAAK,SAAS;EACtC,KAAK,SAAS,IAAI,YAAY,KAAA,CAAS;EACvC,OAAO;CACT;;CAGA,MAAM,SAAS,UAA6C;EAC1D,MAAM,UAA2B;GAC/B,SAAA;GACA;EACF;EACA,MAAM,KAAK,QAAQ,MAAM,OAAO;CAClC;AACF;;AC1JA,SAASE,QAAM,KAAkC;CAC/C,IAAI,QAAQ,KAAA,GAAW,OAAO,CAAC;CAC/B,MAAM,WAAW,qBAAqB,GAAG;CACzC,IAAI,CAAC,kBAAkB,KAAK;EAAE,SAAS;EAAG;CAAS,CAAC,GAClD,MAAM,IAAI,MAAM,kDAAkD;CACpE,OAAO;AACT;AAEA,eAAe,YACb,MACA,QACY;CACZ,OAAO,KAAK,YAAY,OAAO,YAAY;EACzC,MAAM,WAAWA,QAAM,OAAO;EAC9B,IAAI;EACJ,MAAM,QAAQ,IAAI,aAAa;GAC7B,YAAY,QAAQ,QAAQ;IAAE,SAAS;IAAG;GAAS,CAAC;GACpD,QAAQ,YAAY;IAClB,OAAO;IACP,OAAO,QAAQ,QAAQ;GACzB;EACF,CAAC;EACD,MAAM,MAAM,KAAK;EACjB,OAAO;GAAE,QAAQ,MAAM,OAAO,KAAK;GAAG;EAAK;CAC7C,CAAC;AACH;AAEA,SAAgB,cAAc,MAA2B,OAAuC;CAC9F,OAAO,YAAY,OAAO,UAAU,MAAM,OAAO,KAAK,CAAC;AACzD;AAEA,SAAgB,qBACd,MACA,KACA,SACiB;CACjB,OAAO,YAAY,OAAO,UAAU,MAAM,cAAc,KAAK,OAAO,CAAC;AACvE;;AAGA,eAAsB,aAAa,MAA6D;CAC9F,OAAO,CAAC,GAAGA,QAAM,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ;AAC/C;;;AClDA,SAAS,iBAAiB,OAA4C;CACpE,OAAO,UAAU,KAAA,KAAa,OAAO,SAAS,KAAK,KAAK,SAAS;AACnE;AAEA,SAAS,mBACP,WACA,UACS;CACT,IAAI,cAAc,KAAA,GAChB,OAAO;CAET,OAAO,SAAS,OAAO,aAAa,UAAU,SAAS,QAAQ,CAAC;AAClE;;;;;;AAOA,SAAgB,mBAAmB,WAA2B,QAAyB;CACrF,MAAM,UAAmC,CAAC;CAE1C,IAAI,UAAU,oBAAoB,MAChC,QAAQ,KAAK,sBAAsB;CAErC,IAAI,UAAU,YAAY,MACxB,QAAQ,KAAK,mBAAmB;CAElC,IAAI,UAAU,YAAY,KAAA,KAAa,UAAU,qBAAqB,MACpE,QAAQ,KAAK,qBAAqB;CAGpC,IAAI,OAAO,UAAU,QAAQ,UAAU,cAAc,UAAU,MAC7D,QAAQ,KAAK,sBAAsB;CAErC,IACE,OAAO,UAAU,KAAA,KACjB,OAAO,MAAM,SAAS,KACtB,CAAC,mBAAmB,UAAU,cAAc,OAAO,OAAO,KAAK,GAE/D,QAAQ,KAAK,4BAA4B;CAE3C,IACE,OAAO,WAAW,KAAA,KAClB,OAAO,OAAO,SAAS,KACvB,CAAC,mBAAmB,UAAU,cAAc,QAAQ,OAAO,MAAM,GAEjE,QAAQ,KAAK,6BAA6B;CAG5C,IAAI,iBAAiB,OAAO,aAAa,GAAG;EAC1C,MAAM,eAAe,UAAU,OAAO;EACtC,IAAI,CAAC,iBAAiB,YAAY,GAChC,QAAQ,KAAK,0BAA0B;OAClC,IAAI,eAAe,OAAO,eAC/B,QAAQ,KAAK,+BAA+B;CAEhD;CAEA,OAAO;EAAE,YAAY,QAAQ,WAAW;EAAG;CAAQ;AACrD;;;;;;;;;;;;;;AC5BA,SAAS,eAAe,WAAqC;CAC3D,OAAO;EACL,YAAY,UAAU;EACtB,IAAI,UAAU;EACd,SAAS,UAAU;CACrB;AACF;AAEA,SAAS,OAAO,WAAsC,KAA2C;CAC/F,OAAO,UAAU,MAAM,cAAc,aAAa,eAAe,SAAS,GAAG,GAAG,CAAC;AACnF;AAEA,SAAS,SACP,YACA,SACQ;CACR,IAAI,SAAS,cAAc,MACzB,OAAO;EAAE,MAAM;EAAQ,KAAK;CAAqB;CAEnD,IAAI,eAAe,KAAA,GACjB,OAAO,SAAS,aAAa,OAAO,EAAE,MAAM,WAAW,IAAI,EAAE,MAAM,QAAQ;CAE7E,IAAI,WAAW,SAAS,SACtB,OAAO;EAAE,MAAM;EAAS,SAAS,WAAW,OAAO;CAAG;CAExD,IAAI,WAAW,SAAS,aACtB,OAAO,SAAS,aAAa,OAAO,EAAE,MAAM,WAAW,IAAI,EAAE,MAAM,QAAQ;CAE7E,OAAO,WAAW,WAAW,aACzB,EAAE,MAAM,WAAW,IACnB;EAAE,MAAM;EAAQ,KAAK,WAAW;CAAO;AAC7C;AAEA,SAAS,MACP,OACA,MACA,QACA,SACA,SACe;CACf,OAAO;EACL,MAAM;EACN;EACA,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC;EACA,UAAU;GACR,SAAS,QAAQ,MAAM,GAAA,CAAuB;GAC9C,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;EAC7C;CACF;AACF;AAEA,SAAS,SAAS,OAAuB,KAAkC;CACzE,MAAM,QAAQ,OAAO,MAAM,WAAW,GAAG;CACzC,IAAI,UAAU,KAAA,GACZ,OAAO;EAAE,MAAM;EAAS,QAAQ;CAAmB;CAErD,MAAM,UAAU,mBAAmB,OAAO,MAAM,MAAM;CACtD,IAAI,CAAC,QAAQ,YACX,OAAO;EAAE,MAAM;EAAS,QAAQ;EAAoB,QAAQ,QAAQ,QAAQ,KAAK,GAAG;CAAE;CAExF,MAAM,MAAM,mBAAmB,GAAG;CAClC,MAAM,SAAS,SAAS,MAAM,OAAO,MAAM,MAAM,SAAS,IAAI;CAC9D,IAAI,OAAO,SAAS,QAClB,OAAO;EAAE,MAAM;EAAQ,QAAQ;EAAe,QAAQ,OAAO;CAAI;CAInE,OAAO,MAAM,KAAK,KAAA,GAAW,OAAO,CAAC,GAAG,OAAO,SAAS,UAAU,OAAO,UAAU,KAAA,CAAS;AAC9F;AAEA,SAAS,UAAU,OAAuB,MAAmC;CAC3E,IAAI,MAAM,eAAe,WAAW,GAGlC,OAAO;EAAE,MAAM;EAAQ,QAAQ;CAAgB;CAGjD,MAAM,OAAoF,CAAC;CAC3F,IAAI,cAAc;CAClB,MAAM,WAAqB,CAAC;CAC5B,IAAI;CACJ,KAAK,MAAM,OAAO,MAAM,gBAAgB;EACtC,MAAM,QAAQ,OAAO,MAAM,WAAW,GAAG;EACzC,IAAI,UAAU,KAAA,GAAW;GACvB,KAAK,KAAK;IAAE;IAAK,QAAQ;KAAE,MAAM;KAAQ,KAAK;IAAmB;GAAE,CAAC;GACpE,SAAS,KAAK,kBAAkB;GAChC,eAAe;GACf;EACF;EACA,MAAM,UAAU,mBAAmB,OAAO,MAAM,MAAM;EACtD,IAAI,CAAC,QAAQ,YAAY;GAIvB,MAAM,MAAM,QAAQ,QAAQ;GAC5B,KAAK,KAAK;IAAE;IAAK,QAAQ;KAAE,MAAM;KAAQ;IAAI;GAAE,CAAC;GAChD,SAAS,KAAK,GAAG;GACjB,eAAe;GACf;EACF;EACA,MAAM,MAAM,mBAAmB,GAAG;EAClC,MAAM,SAAS,SAAS,MAAM,OAAO,MAAM,MAAM,SAAS,IAAI;EAC9D,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS;GAItD,SAAS;IAAE;IAAK;GAAO;GACvB;EACF;EACA,KAAK,KAAK;GAAE;GAAK;EAAO,CAAC;EACzB,IAAI,OAAO,SAAS,QAClB,SAAS,KAAK,OAAO,GAAG;CAE5B;CACA,MAAM,QAAQ,MAAM,eAAe;CACnC,MAAM,kBAAkB,UACtB,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,OAAyB;EACjD,KAAK,EAAE;EACP,KAAK,EAAE,OAAO,SAAS,SAAS,EAAE,OAAO,MAAM;CACjD,EAAE;CACJ,IAAI,QAAQ,OAAO,SAAS,SAC1B,OAAO,MAAM,OAAO,KAAK,MAAM,SAAS,eAAe,KAAK,MAAM,GAAG,OAAO,OAAO,OAAO;CAE5F,IAAI,WAAW,KAAA,GACb,OAAO,MACL,OAAO,KACP,MACA,UAAU,KAAA,KAAa,aAAa,OAAO,KAAK,KAAK,IAAI,cAAc,YACvE,eAAe,KAAK,MAAM,GAC1B,KAAA,CACF;CAEF,MAAM,aAAa,KAAK,WAAW,MAAM,EAAE,OAAO,SAAS,UAAU;CACrE,MAAM,aAAa,cAAc,IAAI,KAAK,cAAc,KAAA;CACxD,IAAI,eAAe,KAAA,GACjB,OAAO,MAAM,WAAW,KAAK,MAAM,YAAY,eAAe,UAAU,GAAG,KAAA,CAAS;CAEtF,MAAM,UAAU,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG;CAC7C,OAAO;EACL,MAAM;EACN,QAAQ,gBAAgB,SAAS,SAAS,2BAA2B;EACrE,QAAQ;CACV;AACF;;;;;AAMA,SAAgB,MAAM,OAA0C;CAC9D,MAAM,UAA2B,MAAM;CACvC,IAAI,QAAQ,SAAS,SACnB,OAAO;EAAE,MAAM;EAAS,QAAQ;EAAiB,QAAQ,QAAQ;CAAO;CAE1E,IAAI,QAAQ,SAAS,OACnB,OAAO,SAAS,OAAO,QAAQ,KAAK;CAEtC,OAAO,UAAU,OAAO,QAAQ,IAAI;AACtC;;ACxLA,MAAa,cAAc;CAAC;CAAQ;CAAS;CAAY;AAAU;;AAkBnE,SAAgB,oBAAoB,UAAsB,MAAqC;CAC7F,OAAO,SAAS,QAAQ,OAAO,SAAS,MAAM,QAAQ,CAAC,SAAS,GAAG;AACrE;AAEA,SAAS,SAAS,SAA8B,KAAwB;CACtE,OAAO,QAAQ,MAAM,UAAU,MAAM,eAAe,IAAI,cAAc,MAAM,OAAO,IAAI,EAAE;AAC3F;;;;;;;AAQA,SAAgB,eAAe,OAAsC;CAEnE,MAAM,MAAM,MAAM,SAAS,MAAM,WAAW,MAAM,SAAS;CAC3D,MAAM,UAAU,YACd,MAAM;EACJ,SACE,QAAQ,KAAA,KAAa,QAAQ,OACzB;GAAE,MAAM;GAAQ,MAAM,MAAM;GAAM,QAAQ;EAAU,IACpD;GAAE,MAAM;GAAO,OAAO;EAAI;EAChC,WAAW,MAAM;EACjB,QAAQ,MAAM;EACd,gBAAgB,MAAM,SAAS,MAAM,MAAM,KAAK,CAAC,QAAQ,QAAQ,CAAC,SAAS,SAAS,GAAG,CAAC;EACxF,QAAQ,MAAM;EACd,UAAU,MAAM;CAClB,CAAC;CACH,MAAM,WAAW,OAAO,MAAM,OAAO;CACrC,OAAO,SAAS,SAAS,WAAW,MAAM,QAAQ,WAAW,IAAI,WAAW,OAAO,CAAC,CAAC;AACvF;;;;;;;ACpDA,MAAM,aAAa;AAInB,MAAM,uBACJ;AASF,MAAM,kBAAkB;;;;;;;;;;;;;AAcxB,MAAM,kBAEF;CACF,cAAc;EAAE,WAAW;EAAM,kBAAkB;CAAK;CACxD,iBAAiB;EAAE,WAAW;EAAO,kBAAkB;CAAK;CAC5D,QAAQ;EAAE,WAAW;EAAM,kBAAkB;CAAK;CAClD,UAAU;EAAE,WAAW;EAAM,kBAAkB;CAAK;CACpD,SAAS;EAAE,WAAW;EAAM,kBAAkB;CAAK;CACnD,cAAc;EAAE,WAAW;EAAO,kBAAkB;CAAM;CAC1D,eAAe;EAAE,WAAW;EAAO,kBAAkB;CAAM;CAC3D,kBAAkB;EAAE,WAAW;EAAO,kBAAkB;CAAM;CAC9D,gBAAgB;EAAE,WAAW;EAAO,kBAAkB;CAAM;CAC5D,gBAAgB;EAAE,WAAW;EAAO,kBAAkB;CAAM;CAC5D,SAAS;EAAE,WAAW;EAAO,kBAAkB;CAAM;AACvD;;;;;;;;AASA,MAAM,mCAAmB,IAAI,IAA6B;CACxD,CAAC,qBAAqB,cAAc;CACpC,CAAC,kBAAkB,cAAc;CACjC,CAAC,sBAAsB,eAAe;CACtC,CAAC,yBAAyB,eAAe;CACzC,CAAC,2BAA2B,QAAQ;AACtC,CAAC;;;;;;;AAQD,MAAM,mBAGA;CACJ;EACE,UAAU;EACV,SACE;CACJ;CACA;EAUE,UAAU;EACV,SACE;CACJ;CACA;EAAE,UAAU;EAAgB,SAAS;CAAe;CACpD;EAAE,UAAU;EAAW,SAAS;CAAuD;CACvF;EACE,UAAU;EACV,SACE;CACJ;CACA;EACE,UAAU;EACV,SAAS;CACX;CACA;EAGE,UAAU;EACV,SACE;CACJ;CACA;EAAE,UAAU;EAAY,SAAS;CAAwC;CACzE;EAAE,UAAU;EAAkB,SAAS;CAAmD;AAC5F;AAEA,SAAS,aAAa,QAA8C;CAClE,OAAO,OAAO,WAAW,YAAY,OAAO,UAAU,MAAM,KAAK,UAAU,OAAO,UAAU;AAC9F;;;;;;;;;AAUA,MAAM,qBAAqB;AAE3B,SAAS,oBAAoB,cAAsD;CACjF,IAAI,iBAAiB,KAAA,GACnB;CAEF,OAAO,KAAK,IAAI,cAAc,kBAAkB;AAClD;AAEA,SAAS,qBAAqB,OAA4C;CACxE,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS;AAC1E;AAEA,SAAS,kBACP,SAC6B;CAC7B,MAAM,0BAAU,IAAI,IAAoB;CACxC,IAAI,YAAY,KAAA,GACd,OAAO;CAET,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,GAChD,QAAQ,IAAI,KAAK,YAAY,GAAG,KAAK;CAEvC,OAAO;AACT;;;;;;;AAQA,SAAS,mBAAmB,SAA0D;CACpF,MAAM,MAAM,QAAQ,IAAI,aAAa;CACrC,IAAI,QAAQ,KAAA,KAAa,CAAC,QAAQ,KAAK,GAAG,GACxC;CAEF,OAAO,OAAO,GAAG,IAAI;AACvB;;;;;;AAOA,SAAS,qBAAqB,SAA+C;CAC3E,IAAI,eAAe;CACnB,KAAK,MAAM,CAAC,MAAM,UAAU,SAC1B,IAAI,KAAK,WAAW,uBAAuB,GAAG;EAC5C,eAAe;EACf,IAAI,UAAU,KACZ,OAAO;CAEX;CAEF,OAAO;AACT;AAEA,SAAS,YAAY,UAA2B,cAA+C;CAC7F,MAAM,SAAS,gBAAgB;CAC/B,MAAM,UAAU,oBAAoB,YAAY;CAChD,IAAI,YAAY,KAAA,GACd,OAAO,EAAE,WAAW,OAAO,UAAU;CAEvC,OAAO;EAAE,WAAW,OAAO;EAAW,cAAc;CAAQ;AAC9D;AAEA,SAAS,eACP,UACA,OACA,YACA,cACA,YACuB;CACvB,MAAM,SAAS,gBAAgB;CAC/B,OAAO;EACL;EACA;EACA;EACA,OAAO,YAAY,UAAU,YAAY;EACzC,kBAAkB,OAAO;EACzB,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;CACnD;AACF;;;;;;;AAQA,SAAS,eACP,QACA,SAC6B;CAC7B,IAAI,WAAW,KACb,OAAO,qBAAqB,OAAO,IAAI,oBAAoB;CAE7D,IAAI,WAAW,OAAO,WAAW,KAC/B,OAAO;CAET,IAAI,WAAW,KACb,OAAO;CAET,IAAI,WAAW,KACb,OAAO;CAET,IAAI,WAAW,KACb,OAAO;CAET,IAAI,WAAW,OAAO,WAAW,OAAO,WAAW,KACjD,OAAO;AAGX;AAEA,SAAS,aAAa,MAA2C;CAC/D,MAAM,UAAU,KAAK,SAAS,aAAa,KAAK,MAAM,GAAG,UAAU,IAAI;CACvE,KAAK,MAAM,EAAE,UAAU,aAAa,kBAClC,IAAI,QAAQ,KAAK,OAAO,GACtB,OAAO;AAIb;;;;;;;AAQA,SAAgB,gBAAgB,UAAgD;CAG9E,IAAI,SAAS,gBAAgB,QAC3B,OAAO,eAAe,kBAAkB,gBAAgB,MAAM,KAAA,CAAS;CAEzE,IAAI,SAAS,gBAAgB,KAAA,GAC3B,OAAO,eAAe,WAAW,gBAAgB,MAAM,KAAA,CAAS;CAIlE,MAAM,aAAa,SAAS;CAC5B,MAAM,yBAAyB,qBAAqB,YAAY,YAAY,IACxE,WAAW,eACX,KAAA;CACJ,IAAI,eAAe,KAAA,GAAW;EAC5B,MAAM,SAAS,iBAAiB,IAAI,WAAW,IAAI;EACnD,IAAI,WAAW,KAAA,GACb,OAAO,eAAe,QAAQ,cAAc,MAAM,sBAAsB;CAG5E;CAGA,MAAM,UAAU,kBAAkB,SAAS,OAAO;CAClD,IAAI,aAAa,SAAS,MAAM,GAAG;EACjC,MAAM,WAAW,eAAe,SAAS,QAAQ,OAAO;EACxD,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,eAAe,0BAA0B,mBAAmB,OAAO;GAIzE,IAAI,SAAS,WAAW,KACtB,OAAO,eAAe,UAAU,UAAU,MAAM,cAAc,UAAU;GAE1E,IAAI,aAAa,kBAAkB,SAAS,SAAS,KAAA,GAAW;IAC9D,MAAM,UAAU,SAAS,KAAK,MAAM,GAAG,UAAU;IACjD,IAAI,aAAa,OAAO,MAAM,qBAAqB,CAAC,gBAAgB,KAAK,OAAO,GAE9E,OAAO,eAAe,mBAAmB,UAAU,MAAM,cADtC,qBAAqB,KAAK,OAAO,IAAI,aAAa,KAAA,CACY;GAErF;GACA,OAAO,eAAe,UAAU,UAAU,MAAM,YAAY;EAC9D;CACF;CAGA,MAAM,qBAAqB,mBAAmB,OAAO;CACrD,IAAI,uBAAuB,KAAA,GACzB,OAAO,eAAe,gBAAgB,WAAW,OAAO,kBAAkB;CAK5E,IAAI,SAAS,kBAAkB,mBAAmB,MAChD,OAAO,eAAe,mBAAmB,qBAAqB,MAAM,KAAA,CAAS;CAE/E,IAAI,SAAS,kBAAkB,eAAe,MAC5C,OAAO,eAAe,YAAY,qBAAqB,MAAM,sBAAsB;CAIrF,MAAM,OAAO,SAAS;CACtB,IAAI,SAAS,KAAA,GAAW;EACtB,MAAM,WAAW,aAAa,IAAI;EAClC,IAAI,aAAa,KAAA,GAKf,OAAO,eAAe,UAAU,WAAW,OAAO,wBAHhD,aAAa,qBAAqB,qBAAqB,KAAK,KAAK,MAAM,GAAG,UAAU,CAAC,IACjF,aACA,KAAA,CAC8E;CAExF;CAEA,OAAO,eAAe,WAAW,QAAQ,OAAO,KAAA,CAAS;AAC3D;;;;;;;;;;;;;;;;;;;AC1TA,SAAS,cAAc,EAAE,MAAM,OAA2C;CACxE,OAAO,OAAO,cAAc,IAAI,KAAK,OAAO,cAAc,GAAG,KAAK,QAAQ,KAAK,OAAO;AACxF;AAEA,SAAS,SACP,OACA,QACA,MACA,MACkB;CAClB,OAAO;EACL,MAAM;EACN;EACA;EACA;EACA,UAAU,MAAM,SAAS,MAAM,EAAwB;EACvD,iBAAiB,MAAM,OAAO,MAAM,MAAM,OAAO,OAAO;CAC1D;AACF;;;;;AAMA,SAAgB,eAAe,OAA0D;CACvF,IAAI,MAAM,SAAS,WAAW,GAC5B,OAAO;EAAE,MAAM;EAAS,QAAQ;CAA2B;CAE7D,IAAI,CAAC,cAAc,MAAM,MAAM,GAC7B,OAAO;EAAE,MAAM;EAAS,QAAQ;CAA8B;CAEhE,MAAM,OAAO,SAAS,MAAM,WAAW;CACvC,IAAI,SAAS,KAAA,GACX,OAAO;EAAE,MAAM;EAAS,QAAQ;CAAqB;CAEvD,MAAM,SAAS,MAAM,kBAAkB;CACvC,IAAI,WAAW,KAAA,GACb,OAAO;EAAE,MAAM;EAAS,QAAQ;CAA0B;CAE5D,OAAO,SAAS,OAAO,QAAQ,QAAQ,IAAI;AAC7C;;AC3CA,MAAM,kBAAqC,CACzC,uBACA,kCACF;AAMA,MAAM,iBAAyD,CAC7D,CAAC,sBAAsB,GAAG,GAC1B,CAAC,yBAAyB,GAAG,CAC/B;AAEA,SAAS,SAAS,MAAkC;CAClD,KAAK,MAAM,WAAW,iBAAiB;EACrC,MAAM,SAAS,QAAQ,KAAK,IAAI,CAAC,GAAG;EACpC,IAAI,WAAW,KAAA,GACb,OAAO,OAAO,MAAM;CAExB;CACA,OAAO,eAAe,MAAM,CAAC,YAAY,KAAK,WAAW,MAAM,CAAC,CAAC,GAAG;AACtE;AAEA,SAAgB,gBAAgB,SAAuC;CAGrE,IAAI,QAAQ,eAAe,WACzB,OAAO,EAAE,aAAa,OAAO;CAE/B,MAAM,OAAO,QAAQ,cAAc,KAAK,KAAK;CAC7C,IAAI,SAAS,IACX,OAAO,CAAC;CAEV,MAAM,SAAS,SAAS,IAAI;CAC5B,OAAO,WAAW,KAAA,IAAY,EAAE,KAAK,IAAI;EAAE;EAAQ;CAAK;AAC1D;;;;;;;;AC/BA,MAAa,YAAY;AACzB,MAAa,oBAAoB;AAGjC,MAAM,qBAAqB;AAiE3B,SAASC,QAAM,OAAgB,KAAsB;CACnD,OAAO,OAAO,UAAU,YAAY,UAAU,OAC1C,OAAO,yBAAyB,OAAO,GAAG,CAAC,EAAE,QAC7C,KAAA;AACN;AAEA,SAAS,KAAK,OAAgB,KAAa,OAAuB;CAChE,MAAM,QAAQA,QAAM,OAAO,GAAG;CAC9B,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAI,MAAM,GAAG,MAAM,IAAI,IAAI,4BAA4B;CAC/D,OAAO;AACT;AAEA,SAAS,KAAK,OAAgB,OAAyB;CACrD,MAAM,QAAQA,QAAM,OAAO,MAAM;CACjC,IAAI,OAAO,UAAU,YAAY,CAAC,WAAW,KAAK,GAChD,MAAM,IAAI,MAAM,GAAG,MAAM,4CAA4C;CACvE,OAAO;AACT;AAEA,SAAS,MAAM,OAAgB,KAAa,OAAuB;CACjE,MAAM,QAAQA,QAAM,OAAO,GAAG;CAC9B,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GACvE,MAAM,IAAI,MAAM,GAAG,MAAM,IAAI,IAAI,gCAAgC;CACnE,OAAO;AACT;AAEA,SAAS,cACP,OACA,OACkF;CAClF,MAAM,QAAQA,QAAM,OAAO,WAAW;CACtC,IAAI,UAAU,KAAA,MAAc,OAAO,UAAU,YAAY,MAAM,WAAW,IACxE,MAAM,IAAI,MAAM,GAAG,MAAM,uCAAuC;CAClE,OAAO;EACL,GAAIA,QAAM,OAAO,OAAO,MAAM,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,OAAO,SAAS,KAAK,EAAE;EACrF,GAAIA,QAAM,OAAO,MAAM,MAAM,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,MAAM,OAAO,QAAQ,KAAK,EAAE;EAClF,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM;CACpD;AACF;AAEA,SAAS,KAAK,OAAgB,OAA2B;CACvD,MAAM,QAAQA,QAAM,OAAO,OAAO;CAClC,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,yBAAyB;CAC7E,OAAO,MAAM,KAAK,OAAgB,WAAW;EAC3C,YAAY,KAAK,OAAO,cAAc,GAAG,MAAM,UAAU,OAAO,KAAK,EAAE,EAAE;EACzE,IAAI,KAAK,OAAO,MAAM,GAAG,MAAM,UAAU,OAAO,KAAK,EAAE,EAAE;CAC3D,EAAE;AACJ;AAEA,SAAS,QAAQ,MAAgB,OAA0B;CACzD,OAAO,KAAK,eAAe,MAAM,cAAc,KAAK,OAAO,MAAM;AACnE;;AAGA,SAAgB,eAAe,OAAuC;CACpE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,MAAM,QAAQ;CACd,IAAIA,QAAM,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,oBAAoB;CAChF,MAAM,WAAWA,QAAM,OAAO,UAAU;CACxC,IAAI,aAAa,KAAA,MAAc,OAAO,aAAa,YAAY,SAAS,WAAW,IACjF,MAAM,IAAI,MAAM,GAAG,MAAM,sCAAsC;CACjE,OAAO;EACL,SAAS;EACT,MAAM,KAAK,OAAO,QAAQ,KAAK;EAC/B,MAAM,KAAK,OAAO,QAAQ,KAAK;EAC/B,MAAM,KAAK,OAAO,KAAK;EACvB,aAAa,MAAM,OAAO,eAAe,KAAK;EAC9C,UAAU,MAAM,OAAO,YAAY,KAAK;EACxC,GAAG,cAAc,OAAO,KAAK;EAC7B,OAAO,KAAK,OAAO,KAAK;EACxB,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;CAC/C;AACF;AAEA,SAAS,cAAc,OAA0B;CAC/C,MAAM,QAAQ;CACd,OAAO;EACL,MAAM,KAAK,OAAO,QAAQ,KAAK;EAC/B,OAAO,KAAK,OAAO,SAAS,KAAK;EACjC,MAAM,KAAK,OAAO,KAAK;EACvB,aAAa,MAAM,OAAO,eAAe,KAAK;EAC9C,UAAU,MAAM,OAAO,YAAY,KAAK;EACxC,GAAG,cAAc,OAAO,KAAK;EAC7B,OAAO,KAAK,OAAO,KAAK;CAC1B;AACF;;AAGA,SAAgB,YAAY,QAAgC,IAAsC;CAQhG,OAAO,eAAeA,QAPR,OAAO,UAClB,cACC,UAAU,SAAS,YACnB,UAAU,eAAe,sBACzBA,QAAM,UAAU,MAAM,UAAU,MAAM,cACtCA,QAAM,UAAU,MAAM,SAAS,MAAM,EAET,CAAC,EAAE,MAAM,OAAO,CAAC;AACnD;AAEA,SAAS,YAAY,QAAgC,MAAyB;CAC5E,OAAO,OAAO,SAAS,UACrB,MAAM,SAAS,SAAS,gBAAgB,MAAM,QAAQ,aAAa,OAC/D,CAAC,MAAM,QAAQ,OAAO,IACtB,CAAC,CACP;AACF;;AAGA,SAAgB,YAAY,QAAsD;CAChF,MAAM,WAAW,YAAY,QAAQ,SAAS,CAAC,CAC5C,KAAK,YAAYA,QAAM,SAAS,MAAM,CAAC,CAAC,CACxC,UAAU,UAAU,OAAO,UAAU,YAAY,WAAW,KAAK,CAAC;CACrE,OAAO,OAAO,aAAa,YAAY,WAAW,QAAQ,IAAI,WAAW,KAAA;AAC3E;AAEA,SAAS,YAAY,OAA6B;CAChD,OACE,MAAM,SAAS,SAAS,UACvB,MAAM,SAAS,oBAAoB,MAAM,eAAA;AAE9C;;AAGA,SAAS,YAAY,QAAwD;CAC3E,OAAO,OAAO,MAAM,OAAO,cAAc,WAAW,IAAI,CAAC;AAC3D;;;;;;;AAQA,SAAgB,gBACd,QACA,OACsB;CACtB,MAAM,SAAS,OAAO,UACnB,UAAU,MAAM,SAAS,aAAa,MAAM,SAAS,gBACxD;CACA,IACE,UAAU,KAAA,KACV,QAAQ,SAAS,oBACjB,OAAO,eAAA,yBAEP,OAAO,KAAA;CACT,MAAM,WAAW,cAAc,OAAO,OAAO;CAC7C,OAAO,SAAS,SAAS,MAAM,QAAQ,SAAS,UAAU,MAAM,WAAW,WAAW,KAAA;AACxF;AAmBA,SAAgB,UAAU,MAAgB,OAAgC;CACxE,OAAO;EAAE,SAAS;EAAG,MAAM,MAAM;EAAG,MAAM,MAAM;EAAG;EAAM,aAAa;EAAG,UAAU;EAAG,OAAO,CAAC;CAAE;AAClG;;AAGA,SAAgB,aAAa,SAA2D;CACtF,MAAM,iBAAiB,gBAAgB,gBAAgB,OAAO,CAAC;CAC/D,OAAO,eAAe,mBAAmB,iBAAiB,KAAA;AAC5D;;;;;;;;;AAUA,SAAgB,UAAU,OAAkC;CAC1D,MAAM,WAAqB,MAAM,OAAO,SAAS,aAAa,MAAM;CACpE,MAAM,EAAE,UAAU;CAClB,IAAI,MAAM,WAAW,UACnB,OAAO;EAAE,MAAM;EAAS,QAAQ;EAAO,SAAS,CAAC;EAAG,OAAO,MAAM;CAAM;CACzE,IAAI,MAAM,WAAW,QAAQ;EAC3B,MAAM,OACJ,MAAM,OAAO,SACR,MAAM,iBAAiB,YAAY,MAAM,MAAM,KAAK,WACrD;EACN,OAAO;GACL,MAAM;GACN,QAAQ;GACR,SAAS,CAAC;GACV,OAAO,UAAU,MAAM,MAAM,KAAK;EACpC;CACF;CACA,IAAI,MAAM,WAAW,WAAW,UAAU,KAAA,KAAa,MAAM,WAAW,KAAA,GAAW;EACjF,MAAM,SAAS,MAAM;EACrB,IAAI,aAAa,OAAO,OAAO,MAAM,KAAA,GAAW;GAC9C,MAAM,QAAQ,MAAM,MAAM,MAAM,QAAQ,QAAQ,KAAK,OAAO,KAAK,CAAC,IAC9D,MAAM,QACN,CAAC,GAAG,MAAM,OAAO,OAAO,KAAK;GACjC,OAAO;IACL,MAAM,MAAM;IACZ,QAAQ;IACR,SAAS;IACT,OAAO;KAAE,GAAG;KAAO;KAAO,OAAO,MAAM,QAAQ,KAAK;IAAE;GACxD;EACF;CACF;CACA,MAAM,WACJ,MAAM,WAAW,iBAAiB,gBAAgB,MAAM,QAAQ,KAAK,IAAI,KAAA;CAC3E,IAAI,aAAa,KAAA,GACf,OAAO;EAAE,MAAM,OAAO,QAAQ;EAAU,QAAQ;EAAM,SAAS,CAAC;EAAG;CAAM;CAC3E,OAAO;EACL,MAAM,SAAS;EACf,QAAQ;EACR,SAAS,SAAS;EAClB,OAAO;GACL,SAAS;GACT,MAAM,SAAS;GACf,MAAM,MAAM,MAAM;GAClB,MAAM,SAAS;GACf,aAAa,SAAS;GACtB,UAAU,SAAS;GACnB,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,SAAS,MAAM;GAChE,GAAI,SAAS,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,SAAS,UAAU;GAC5E,OAAO,SAAS;GAChB,UAAU,SAAS;EACrB;CACF;AACF;;AAGA,SAAgB,aAAa,QAAgC,MAAoC;CAC/F,OAAO,YAAY,YAAY,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,YAAY;EACjE,MAAM,UAAU,uBAAuB,OAAO;EAC9C,OAAO,YAAY,KAAA,IACf,CAAC,IACD,CAAC;GAAE,MAAM;GAAiB,QAAQ,iBAAiB,OAAO;EAAE,CAAC;CACnE,CAAC;AACH;;;;;;AAyBA,SAAS,UAAU,OAA6C;CAC9D,IAAI,MAAM,SAAS,SAAS,YAAY,MAAM,SAAS,QAAQ,MAAM,OAAO,KAAA;CAC5E,MAAM,QAAQ,YAAY,MAAM,QAAQ,MAAM,EAAE;CAEhD,MAAM,UADO,YAAY,MAAM,MAAM,CAAC,CAAC,UAAU,UAAU,MAAM,SAAS,SAAS,WAChE,CAAC,EAAE;CAGtB,IAAI,UAAU,KAAA,KAAa,SAAS,eAAe,WAAW,QAAQ,aAAa,YACjF,OAAO,KAAA;CACT,OAAO;EACL;EACA,OAAO;GAAE,YAAY,QAAQ,YAAY;GAAI,IAAI,QAAQ,SAAS;EAAG;EACrE,gBAAgB,gBACd,gBAAgB;GAAE,YAAY,QAAQ;GAAY,cAAc,QAAQ;EAAa,CAAC,CACxF;CACF;AACF;;;;;;;;AASA,SAAgB,mBAAmB,OAA4C;CAC7E,MAAM,MAAM,MAAM,OAAO,UAAU,MAAM,qBAAqB,UAAU,KAAK,IAAI,KAAA;CACjF,IAAI,QAAQ,KAAA,KAAa,CAAC,8BAA8B,SAAS,IAAI,eAAe,QAAQ,GAC1F,OAAO,KAAA;CACT,MAAM,EAAE,UAAU;CAClB,MAAM,OAAO,SAAS,MAAM,IAAI;CAChC,MAAM,OAAO,eAAe;EAC1B,cAAc,IAAI;EAClB,aAAa,MAAM;EACnB,oBAAoB,SAAS,KAAA,IAAY,CAAC,IAAI,MAAM,SAAS,MAAM,MAAA,CAAO,QAAQ,QAChF,MAAM,UAAU,MAAM,UAAU,QAAQ,OAAO,GAAG,CAAC,CACrD;EACA,UAAU,CACR,GAAG,aAAa,MAAM,QAAQ,MAAM,IAAI,GACxC;GAAE,MAAM;GAAoB,QAAQ,IAAI,eAAe;EAAS,CAClE;EACA,QAAQ;GAAE,MAAM,MAAM;GAAa,KAAA;EAA8B;CACnE,CAAC;CACD,IAAI,KAAK,SAAS,YAAY,OAAO,KAAA;CACrC,OAAO;EACL,MAAM,MAAM;EACZ,OAAO,MAAM,MAAM;EACnB,MAAM,KAAK;EACX,aAAa,MAAM,cAAc;EACjC,UAAU,MAAM;EAChB,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;EAC1D,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAU;EACtE,OAAO,CAAC;CACV;AACF;;;;;;;AAQA,SAAgB,gBAAgB,OAA4C;CAC1E,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,CAAC,KAAK,eAAe,kBAAkB,OAAO,KAAA;CAClD,MAAM,EAAE,UAAU;CAClB,IAAI,MAAM,YAAA,GAAmC,OAAO,KAAA;CACpD,OAAO;EACL,MAAM,MAAM;EACZ,OAAO,MAAM,MAAM;EACnB,MAAM,MAAM;EACZ,aAAa,MAAM;EACnB,UAAU,MAAM,WAAW;EAC3B,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;EAC1D,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAU;EAGtE,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,QAAQ,IAAI,eAAe,MAAM,IAAI,OAAO,EAAE;CAC3E;AACF;;;;;;AAOA,SAAgB,gBAAgB,OAA4C;CAC1E,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI,CAAC,KAAK,eAAe,oBAAoB,IAAI,MAAM,WAAA,GACrD,OAAO,KAAA;CACT,MAAM,EAAE,OAAO,cAAc,IAAI;CACjC,OAAO;EACL,MAAM,IAAI,MAAM;EAChB,OAAO,MAAM,MAAM;EACnB,MAAM,IAAI,MAAM;EAChB,aAAa,IAAI,MAAM;EACvB,UAAU,IAAI,MAAM;EACpB,QAAQ,SAAS,MAAM,cAAc,KAAA,IAAY,IAAI;EACrD,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;EAC/C,OAAO,CAAC;CACV;AACF;;;;;;;AAQA,SAAgB,WAAW,OAA0C;CAEnE,IADa,YAAY,MAAM,MAAM,CAAC,CAAC,UAAU,UAAU,MAAM,SAAS,SAAS,WAC5E,CAAC,EAAE,SAAS,eAAe,QAAQ,OAAO,KAAA;CACjD,OAAO,YAAY,MAAM,QAAQ,MAAM,EAAE,CAAC,EAAE;AAC9C;;ACxdA,MAAa,gBAAgB;AAO7B,SAASC,QAAM,KAA4B;CACzC,IAAI,CAACC,SAAO,GAAG,KAAK,IAAI,eAAe,GAAG,MAAM,IAAI,MAAM,sCAAsC;CAChG,MAAM,OAAO,IAAI;CACjB,MAAM,OAAO,IAAI;CACjB,IACE,SAAS,KAAA,KACT,SAAS,QACT,SAAS,SACT,SAAS,aACT,SAAS,UAET,MAAM,IAAI,MAAM,+DAA+D;CACjF,IAAI,SAAS,KAAA,KAAa,SAAS,SAAS,OAAO,SAAS,YAAY,CAAC,WAAW,IAAI,IACtF,MAAM,IAAI,MAAM,oEAAoE;CACtF,OAAO;EACL,SAAS;EACT,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;AACF;AAEA,SAAgB,oBAAoB,QAAsD;CACxF,IAAI,OAA6B;CACjC,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,MAAM,SAAS,YAAY,MAAM,eAAA,oBAA8B;EACnE,MAAM,QAAQD,QAAM,MAAM,IAAI;EAC9B,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,MAAM;CAC7C;CACA,OAAO;AACT;;AAGA,SAAgB,cACd,OACA,QACA,QACe;CACf,IAAI,OAAO,aAAa,cAAc,YAAY,MAAM,OAAO,OAAO,MAAM,EAAE,GAAG,OAAO;CAExF,QADiB,oBAAoB,MACtB,KAAK,YAAY,QAAQ,QAAQ;AAClD;;AAGA,SAAgB,cAAc,QAAiD;CAC7E,IAAI,OAAwB;CAC5B,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,MAAM,SAAS,YAAY,MAAM,eAAA,oBAA8B;GACjE,MAAM,QAAQA,QAAM,MAAM,IAAI;GAC9B,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,MAAM;EAC7C;EACA,IAAI,MAAM,SAAS,SAAS,gBAAgB,MAAM,QAAQ,aAAA,iBAAwB;GAChF,MAAM,UAAU,MAAM,QAAQ;GAC9B,IAAIC,SAAO,OAAO,GAAG;IACnB,MAAM,OAAO,QAAQ;IACrB,IAAI,SAAS,QAAS,OAAO,SAAS,YAAY,WAAW,IAAI,GAAI,OAAO;GAC9E;EACF;CACF;CACA,OAAO;AACT;;;AC5DA,SAAgB,cAAc,KAAuB;CACnD,MAAM,OAAO,GAAG,IAAI,WAAW,GAAG,IAAI;CACtC,OAAO,IAAI,YAAY,KAAA,IAAY,OAAO,GAAG,KAAK,GAAG,IAAI;AAC3D;;;;;AAMA,SAAgB,UAAU,QAAgD;CACxE,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,QAAkB,CAAC;CACzB,IAAI,OAAO,WAAW,WAAW,MAAM,KAAK,OAAO,MAAM;CACzD,IAAI,OAAO,YAAY,QAAQ,MAAM,KAAK,cAAc;MACnD,IAAI,OAAO,YAAY,aAAa,MAAM,KAAK,WAAW;CAC/D,IAAI,OAAO,UAAU,MAAM,KAAK,UAAU;CAC1C,OAAO,MAAM,WAAW,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACzD;AAGA,SAAgB,kBACd,UACA,MACA,QACA,wBACkC;CAClC,MAAM,UAA4C,CAChD;EAAE,OAAO;EAAc,OAAO,EAAE,MAAM,MAAM;EAAG,aAAa;CAAuB,CACrF;CACA,MAAM,aAAa,QAAQ,MAAM;CACjC,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU;EAC3C,QAAQ,KAAK;GACX,OAAO,GAAG,cAAc,GAAG,IAAI,UAAU,aAAa,MAAM;GAC5D,OAAO;IAAE,MAAM;IAAY;IAAO;GAAI;GACtC,aAAa;EACf,CAAC;CACH,CAAC;CAGD,OAAO;AACT;AAEA,SAAgB,gBAAgB,QAAkD;CAChF,OAAO,MAAM,KAAK,SAAS;EACzB,MAAM,YAAY,OAAO,MAAM;EAG/B,MAAM,cACJ,UAAU,WAAW,IACjB,2CACA,UAAU,KAAK,UAAU,cAAc,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK;EACnE,OAAO;GAAE,OAAO,GAAG,KAAK,IAAI,OAAO,UAAU,MAAM,EAAE;GAAI,OAAO;GAAM;EAAY;CACpF,CAAC;AACH;AAUA,SAAgB,mBAAmB,QAA+D;CAChG,OAAO,OAAO,KAAK,UAAU;EAC3B,OAAO,GAAG,KAAK,WAAW,GAAG,KAAK;EAClC,aAAa,KAAK;EAClB,OAAO;CACT,EAAE;AACJ;AAMA,SAAgB,eAAe,UAA4D;CACzF,MAAM,UAAyC,CAC7C;EAAE,OAAO;EAAmB,OAAO,EAAE,SAAS,KAAA,EAAU;CAAE,CAC5D;CACA,KAAK,MAAM,WAAW,UACpB,QAAQ,KAAK;EAAE,OAAO,IAAI;EAAW,OAAO,EAAE,QAAQ;CAAE,CAAC;CAE3D,OAAO;AACT;;AAGA,SAAgB,kBAAkB,WAAgC,OAA2B;CAC3F,OAAO,CAAC,GAAG,UAAU,QAAQ,GAAG,MAAM,MAAM,KAAK,GAAG,GAAG,UAAU,QAAQ,GAAG,MAAM,MAAM,KAAK,CAAC;AAChG;;AAGA,SAAgB,aACd,WACA,OACA,OACY;CACZ,MAAM,OAAO,CAAC,GAAG,SAAS;CAC1B,MAAM,SAAS,QAAQ;CACvB,MAAM,OAAO,KAAK;CAClB,MAAM,QAAQ,KAAK;CACnB,IAAI,SAAS,KAAA,KAAa,UAAU,KAAA,GAAW,OAAO;CACtD,KAAK,SAAS;CACd,KAAK,UAAU;CACf,OAAO;AACT;;AAGA,SAAgB,eAAe,WAAgC,OAA2B;CACxF,OAAO,UAAU,QAAQ,GAAG,MAAM,MAAM,KAAK;AAC/C;;AC7GA,SAAS,KAAK,UAA8B;CAC1C,OAAO,SAAS,SAAS,iBAAiB,KAAK,SAAS,KAAK,IAAI;AACnE;AAEA,SAAgB,gBACd,WACA,UACA,UACS;CACT,IAAI,cAAc,SAAS,OAAO;CAClC,IAAI,cAAc,SAAS,aAAa,KAAA,GAAW,OAAO;CAC1D,MAAM,UAAU,KAAK,QAAQ;CAC7B,MAAM,OAAO,KAAK,QAAQ;CAC1B,OACE,QAAQ,SAAS,WACjB,KAAK,SAAS,WACd,QAAQ,WAAW,cACnB,QAAQ,WAAW,WACnB,SAAS,SAAS,SAAS,QAC3B,CAAC,aAAa,QAAQ,OAAO,KAAK,KAAK;AAE3C;AAEA,MAAM,SAAqC;CACzC,eAAe;CACf,iBAAiB;CACjB,0BAA0B;CAC1B,eAAe;AACjB;AACA,MAAM,UAAmF;CACvF,UAAU;CACV,OAAO;AACT;;AAGA,SAAgB,WAAW,OAAmE;CAC5F,OAAO,uBAAuB,MAAM,SAAS,GAAG,MAAM;AACxD;AAEA,SAAgB,aAAa,UAAoB,MAAgB,QAAQ,OAAe;CACtF,QAAQ,SAAS,MAAjB;EACE,KAAK,gBACH,OAAO,qBAAqB,aAAa,SAAS,OAAO,MAAM,KAAK;EACtE,KAAK,SACH,OAAO,GAAG,KAAK,KAAK,cAAc,SAAS,KAAK,IAAI,QAAQ,aAAc,QAAQ,SAAS,WAAW;EACxG,KAAK,QACH,OAAO,GAAG,KAAK,aAAa,OAAO,SAAS;EAC9C,KAAK,SACH,OAAO,iBAAiB,SAAS,OAAO,WAAW,KAAK,GAAG,EAAE;EAC/D,KAAK,YACH,OAAO,gBAAgB,SAAS,KAAK,mBAAmB,cAAc,SAAS,MAAM;CACzF;AACF;;ACpDA,SAAgB,iBAAgC;CAC9C,OAAO;EAAE,OAAO;EAAU,UAAU;EAAG,WAAW;CAAE;AACtD;;;;;;AAOA,SAAS,UAAU,WAAmB,QAA+B;CACnE,OAAO,KAAK,IAAI,OAAO,aAAa,MAAM,YAAY,IAAI,OAAO,YAAY;AAC/E;AAEA,SAAS,YACP,QACA,WACA,KACA,QACe;CACf,OAAO;EACL,OAAO;EACP,UAAU,OAAO;EACjB;EACA,UAAU,MAAM,UAAU,WAAW,MAAM;CAC7C;AACF;;;;;;;;;AAgBA,SAAgB,qBACd,QACA,UACA,KACA,QACsB;CACtB,IAAI,0BAA0B,SAAS,QAAQ,KAAK,OAAO,UAAU,UACnE,OAAO;EAAE;EAAQ,QAAQ;CAAM;CAEjC,MAAM,WAAW,OAAO,WAAW;CACnC,IAAI,WAAW,OAAO,kBACpB,OAAO;EAAE,QAAQ;GAAE,GAAG;GAAQ;EAAS;EAAG,QAAQ;CAAM;CAE1D,OAAO;EACL,QAAQ,YAAY;GAAE,GAAG;GAAQ;EAAS,GAAG,OAAO,YAAY,GAAG,KAAK,MAAM;EAC9E,QAAQ;CACV;AACF;;;;;;AAOA,SAAgB,uBAAsC;CACpD,OAAO;EAAE,OAAO;EAAU,UAAU;EAAG,WAAW;CAAE;AACtD;;;;;;;;;;;AAkBA,SAAgB,YAAY,QAAuB,KAAiC;CAClF,IAAI,OAAO,UAAU,QAAQ,OAAO,KAAA;CACpC,MAAM,WAAW,OAAO;CACxB,IAAI,aAAa,KAAA,KAAa,MAAM,UAAU,OAAO,WAAW;AAElE;;;;;;;AAQA,SAAgB,iBAAiB,QAAuB,KAAiC;CACvF,IAAI,OAAO,UAAU,QAAQ,OAAO,KAAA;CACpC,OAAO,KAAK,IAAI,IAAI,OAAO,YAAY,KAAK,GAAG;AACjD;AAEA,SAAgB,WAAW,QAAuB,KAA6B;CAC7E,IAAI,OAAO,UAAU,UACnB,OAAO;EAAE,MAAM;EAAU;CAAO;CAElC,IAAI,OAAO,UAAU,aACnB,OAAO;EAAE,MAAM;EAAa;CAAO;CAErC,MAAM,OAAO,YAAY,QAAQ,GAAG;CACpC,IAAI,SAAS,KAAA,GACX,OAAO;EAAE,MAAM;EAAW;EAAQ,WAAW;CAAK;CAEpD,OAAO;EACL,MAAM;EACN,QAAQ;GAAE,OAAO;GAAa,UAAU,OAAO;GAAU,WAAW,OAAO;EAAU;CACvF;AACF;;AAGA,SAAgB,mBAAmB,QAAsC;CACvE,IAAI,OAAO,UAAU,aACnB,OAAO;CAET,OAAO;EAAE,OAAO;EAAU,UAAU;EAAG,WAAW;CAAE;AACtD;;;;;;;AAQA,SAAgB,YACd,QACA,KACA,QACe;CACf,IACE,OAAO,UAAU,eACjB,OAAO,YAAY,KAAA,KACnB,MAAM,OAAO,UAAU,OAAO,gBAE9B,OAAO;CAET,OAAO,YAAY,QAAQ,OAAO,WAAW,KAAK,MAAM;AAC1D;;;;;;;;AASA,SAAgB,aAAa,QAAsC;CACjE,IAAI,OAAO,UAAU,aACnB,OAAO;CAET,OAAO;EACL,OAAO;EACP,UAAU,OAAO;EACjB,WAAW,OAAO;EAClB,GAAI,OAAO,YAAY,KAAA,IAAY,EAAE,UAAU,OAAO,QAAQ,IAAI,CAAC;CACrE;AACF;;;;;;;;AASA,SAAgB,mBACd,QACA,UACA,KACA,QACe;CACf,IAAI,OAAO,UAAU,aACnB,OAAO;CAET,IAAI,0BAA0B,SAAS,QAAQ,GAC7C,OAAO,YAAY,QAAQ,OAAO,WAAW,KAAK,MAAM;CAE1D,OAAO,YAAY,QAAQ,OAAO,YAAY,GAAG,KAAK,MAAM;AAC9D;;AC3LA,MAAa,oBAAoB;CAAC;CAAO;CAAU;AAAM;AAgDzD,MAAa,0BAA0C;CACrD,UAAU;CACV,4BAA4B;AAC9B;AC5BA,SAAgB,eAAe,YAAgC;CAC7D,OAAO,kBAAkB,QAAQ,UAAU;AAC7C;AAEA,SAASC,iBAAe,OAAiC;CACvD,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC3D;AAEA,SAAS,aAAa,OAAiC;CACrD,OAAOA,iBAAe,KAAK,KAAK,SAAS,KAAK,SAAS;AACzD;;;;;;;AAQA,SAAgB,iBAAiB,SAA0C;CACzE,IAAI,OAAO,YAAY,YAAY,YAAY,MAC7C,OAAO;CAET,MAAM,YAAY;CAClB,IAAI,CAAC,kBAAkB,SAAS,UAAU,UAAU,GAClD,OAAO;CAET,IAAI,CAACA,iBAAe,UAAU,UAAU,KAAK,UAAU,aAAa,GAClE,OAAO;CAET,IACG,UAAU,cAAc,KAAA,KAAa,CAAC,aAAa,UAAU,SAAS,KACtE,UAAU,mBAAmB,KAAA,KAAa,CAAC,aAAa,UAAU,cAAc,GAEjF,OAAO;CAET,MAAM,eACJ,UAAU,iBAAiB,KAAA,KAC3BA,iBAAe,UAAU,YAAY,KACrC,OAAO,UAAU,UAAU,YAAY,KACvC,UAAU,gBAAgB,IACtB,UAAU,eACV,KAAA;CACN,MAAM,UACJA,iBAAe,UAAU,OAAO,KAAK,UAAU,WAAW,IAAI,UAAU,UAAU,KAAA;CACpF,MAAM,WACJ,OAAO,UAAU,aAAa,WAC1B,UAAU,SAAS,MAAM,GAAA,GAAsB,IAC/C,KAAA;CACN,IACE,UAAU,cAAc,KAAA,KACxB,UAAU,mBAAmB,KAAA,KAC7B,iBAAiB,KAAA,KACjB,YAAY,KAAA,GAEZ,OAAO;CAET,OAAO;EACL,GAAI,UAAU,cAAc,KAAA,IAAY,EAAE,WAAW,UAAU,UAAU,IAAI,CAAC;EAC9E,GAAI,UAAU,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,UAAU,eAAe,IAAI,CAAC;EAC7F,GAAI,iBAAiB,KAAA,IAAY,EAAE,aAAa,IAAI,CAAC;EACrD,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,YAAY,UAAU;EACtB,YAAY,UAAU;EACtB,GAAI,aAAa,KAAA,IAAY,EAAE,SAAS,IAAI,CAAC;CAC/C;AACF;AAEA,SAAS,QAAQ,SAA0B,KAAa,QAAiC;CACvF,OAAO,MAAM,QAAQ,cAAc,OAAO;AAC5C;;;;;;;AAQA,SAAS,uBAAuB,WAA4B,WAAqC;CAC/F,MAAM,eAAe,eAAe,UAAU,UAAU,IAAI,eAAe,UAAU,UAAU;CAC/F,IAAI,iBAAiB,GACnB,OAAO,eAAe;CAIxB,QAF2B,UAAU,kBAAkB,MAC5B,UAAU,kBAAkB;AAEzD;;;;;;;;AASA,SAAgB,cACd,UACA,KACA,SAAyB,yBACD;CACxB,MAAM,YAAY,SACf,IAAI,gBAAgB,CAAC,CACrB,QAAQ,YAAwC,YAAY,IAAI,CAAC,CACjE,QAAQ,YAAY,QAAQ,SAAS,KAAK,MAAM,CAAC;CACpD,IAAI,UAAU,WAAW,GACvB,OAAO;CAET,MAAM,OAAO,UAAU,QAAQ,MAAM,YACnC,uBAAuB,SAAS,IAAI,IAAI,UAAU,IACpD;CACA,MAAM,aAAgB,SAAqE;EACzF,IAAI;EACJ,IAAI;EACJ,KAAK,MAAM,WAAW,WAAW;GAC/B,MAAM,QAAQ,KAAK,OAAO;GAC1B,IAAI,UAAU,KAAA,GACZ;GAEF,IAAI,SAAS,KAAA,KAAa,uBAAuB,SAAS,IAAI,GAAG;IAC/D,OAAO;IACP,YAAY;GACd;EACF;EACA,OAAO;CACT;CACA,MAAM,YAAY,WAAW,YAAY,QAAQ,SAAS;CAC1D,MAAM,iBAAiB,WAAW,YAAY,QAAQ,cAAc;CACpE,MAAM,eAAe,WAAW,YAAY,QAAQ,YAAY;CAChE,MAAM,UAAU,WAAW,YAAY,QAAQ,OAAO;CACtD,MAAM,aAAa,UAAU,QAC1B,QAAQ,YACP,eAAe,QAAQ,UAAU,IAAI,eAAe,MAAM,IAAI,QAAQ,aAAa,QACrF,KAAK,UACP;CACA,MAAM,aAAa,KAAK,IAAI,GAAG,UAAU,KAAK,YAAY,QAAQ,UAAU,CAAC;CAC7E,OAAO;EACL,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;EAC/C,GAAI,mBAAmB,KAAA,IAAY,EAAE,eAAe,IAAI,CAAC;EACzD,GAAI,iBAAiB,KAAA,IAAY,EAAE,aAAa,IAAI,CAAC;EACrD,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C;EACA;EACA,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;CACnE;AACF;;;;;;;AAQA,SAAgB,gBACd,SACA,SAAyB,yBACR;CACjB,MAAM,YAAY,QAAQ,mBAAmB,KAAK,QAAQ,cAAc;CAQxE,OAAO;EAAE;EAAW,UANlB,CAAC,aACD,QAAQ,eAAe,WACrB,QAAQ,mBAAmB,KAAA,KAC3B,QAAQ,kBAAkB,OAAO,8BAChC,QAAQ,cAAc,KAAA,KACrB,QAAQ,aAAa,IAAI,OAAO;CACT;AAC/B;;;AClMA,SAAgB,WAAW,KAAkB,gBAAoD;CAC/F,IAAI,eAAe,eAAe,YAEhC,OAAO,EAAE,YAAY,IAAI,WAAW;CAEtC,IAAI,eAAe,aAAa,qBAAqB,IAAI,cAAc,KAAA,GACrE,OAAO;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;CAAQ;CAE5D,OAAO;AACT;;AAGA,SAAgBC,eAAa,KAAkB,gBAAoD;CACjG,OAAO;EACL,MAAM;EACN,KAAK,WAAW,KAAK,cAAc;EACnC,UAAU,eAAe;EACzB,YAAY,eAAe;EAC3B,GAAI,eAAe,MAAM,iBAAiB,KAAA,IACtC,EAAE,cAAc,eAAe,MAAM,aAAa,IAClD,CAAC;CACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACUA,SAAgB,cAAc,KAAkB,KAA6B;CAC3E,OAAO;EAAE;EAAK,QAAQ;EAAW,SAAS,eAAe;EAAG,WAAW;CAAI;AAC7E;;;;;;AAOA,SAAgB,YAAY,QAAwB,KAA6B;CAC/E,MAAM,SAAS,OAAO;CACtB,IAAI,WAAW,KAAA,KAAa,MAAM,OAAO,OACvC,OAAO;CAET,OAAO;EAAE,KAAK,OAAO;EAAK,QAAQ;EAAW,SAAS,OAAO;EAAS,WAAW;CAAI;AACvF;AAEA,SAAS,QAAQ,QAAwB,KAA6B;CACpE,OAAO;EAAE,GAAG;EAAQ,WAAW;CAAI;AACrC;;;;;;AAOA,SAAS,kBAAkB,OAA+C;CACxE,OAAO,UAAU,KAAA,KAAa,OAAO,UAAU,KAAK,KAAK,SAAS,IAAI,QAAQ,KAAA;AAChF;AAEA,SAAS,eACP,QACA,cACA,KACA,QACgB;CAChB,MAAM,QAAQ,OAAO,kBAAkB,YAAY,KAAK,OAAO;CAC/D,OAAO;EAAE,GAAG;EAAQ,QAAQ;EAAmB,QAAQ;GAAE,MAAM;GAAS;EAAM;EAAG,WAAW;CAAI;AAClG;AAEA,SAAS,aACP,QACA,OACA,KACA,QACgB;CAChB,QAAQ,MAAM,UAAd;EACE,KAAK,gBAAgB;GACnB,IAAI,OAAO,WAAW,qBAAqB,OAAO,WAAW,eAC3D,OAAO,QAAQ,QAAQ,GAAG;GAG5B,MAAM,QAAQ,OADO,kBAAkB,MAAM,YACb,KAAK,OAAO;GAC5C,OAAO;IACL,GAAG;IACH,QAAQ;IACR,QAAQ;KAAE,MAAM;KAAc;IAAM;IACpC,WAAW;GACb;EACF;EACA,KAAK;GACH,IAAI,OAAO,WAAW,eACpB,OAAO,QAAQ,QAAQ,GAAG;GAE5B,OAAO,eAAe,QAAQ,MAAM,cAAc,KAAK,MAAM;EAE/D,KAAK;EACL,KAAK;EACL,KAAK,WAAW;GACd,MAAM,UAAU,qBAAqB,OAAO,SAAS,MAAM,UAAU,KAAK,OAAO,OAAO;GACxF,MAAM,SACJ,OAAO,WAAW,aAAa,OAAO,WAAW,aAAa,aAAa,OAAO;GACpF,OAAO;IAAE,GAAG;IAAQ;IAAQ,SAAS,QAAQ;IAAQ,WAAW;GAAI;EACtE;EACA,KAAK;EACL,KAAK;GAGH,IAAI,MAAM,aAAa,iBAAiB;IACtC,MAAM,QAAQ,cAAc,OAAO,GAAG;IACtC,IAAI,UAAU,WAAW,UAAU,WACjC,OAAO,QAAQ,QAAQ,GAAG;GAE9B;GACA,IAAI,CAAC,MAAM,YAAY;IAIrB,MAAM,UAAU,qBAAqB,OAAO,SAAS,MAAM,UAAU,KAAK,OAAO,OAAO;IACxF,MAAM,SACJ,OAAO,WAAW,aAAa,OAAO,WAAW,aAAa,aAAa,OAAO;IACpF,OAAO;KAAE,GAAG;KAAQ;KAAQ,SAAS,QAAQ;KAAQ,WAAW;IAAI;GACtE;GACA,OAAO;IAAE,GAAG;IAAQ,QAAQ;IAAe,WAAW;GAAI;EAE5D,SAGE,OAAO,QAAQ,QAAQ,GAAG;CAC9B;AACF;AAEA,SAAgB,iBACd,QACA,OACA,KACA,QACgB;CAChB,QAAQ,MAAM,MAAd;EACE,KAAK,WACH,OAAO,aAAa,QAAQ,OAAO,KAAK,MAAM;EAChD,KAAK,WAAW;GACd,MAAM,UAAyB,qBAAqB;GACpD,MAAM,SACJ,OAAO,WAAW,cAAc,OAAO,WAAW,oBAC9C,OAAO,SACP;GACN,OAAO;IACL,GAAG;IACH;IACA;IACA,QAAQ,WAAW,OAAO,SAAS,OAAO,SAAS,KAAA;IACnD,WAAW;GACb;EACF;EACA,KAAK,SAAS;GACZ,MAAM,SACJ,OAAO,WAAW,aAAa,OAAO,WAAW,aAAa,aAAa,OAAO;GACpF,OAAO;IAAE,GAAG;IAAQ;IAAQ,WAAW;GAAI;EAC7C;EACA,KAAK,YAAY;GACf,IAAI,MAAM,WAAW;IACnB,IAAI,OAAO,WAAW,eACpB,OAAO,QAAQ,QAAQ,GAAG;IAE5B,OAAO,eAAe,QAAQ,MAAM,cAAc,KAAK,MAAM;GAC/D;GACA,MAAM,SAAS,OAAO,WAAW,oBAAoB,YAAY,OAAO;GACxE,OAAO;IACL,GAAG;IACH;IACA,QAAQ,WAAW,OAAO,SAAS,OAAO,SAAS,KAAA;IACnD,WAAW;GACb;EACF;EACA,KAAK,SACH,OAAO;GAAE,KAAK,OAAO;GAAK,QAAQ;GAAW,SAAS,eAAe;GAAG,WAAW;EAAI;CAC3F;AACF;;;;;;;;;;;;;;;;;;;;AClJA,MAAM,sBAAsB;CAC1B,aAAa;CACb,mBAAmB;CACnB,gBAAgB;AAClB;AAsBA,SAAS,QACP,QACA,KACA,WACY;CACZ,IAAI,cAAc,KAAA,GAChB,OAAO;EAAE,MAAM;EAAW;EAAQ;CAAI;CAExC,OAAO;EAAE,MAAM;EAAW;EAAQ;EAAK;CAAU;AACnD;AAEA,SAAS,YAAY,QAAwB,KAAoC;CAC/E,MAAM,YAAY,OAAO,WAAW,KAAA,IAAY,KAAA,IAAY,OAAO,OAAO,QAAQ;CAClF,QAAQ,OAAO,QAAf;EACE,KAAK,eACH,OAAO;GACL,QAAQ;GACR,KAAK,OAAO;GACZ,WAAW,KAAA;GACX,UAAU,oBAAoB;EAChC;EACF,KAAK,mBACH,OAAO;GACL,QAAQ;GACR,KAAK,OAAO;GACZ;GACA,UAAU,oBAAoB;EAChC;EACF,KAAK,gBACH,OAAO;GACL,QAAQ;GACR,KAAK,OAAO;GACZ;GACA,UAAU,oBAAoB;EAChC;EACF,SACE;CACJ;AACF;;AAGA,SAAS,QACP,SACA,KACuB;CACvB,IAAI;CACJ,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,WAAW,KAAA,GACb;EAEF,MAAM,YAAY,YAAY,QAAQ,GAAG;EACzC,IAAI,cAAc,KAAA,GAChB;EAEF,IAAI,SAAS,KAAA,KAAa,UAAU,YAAY,KAAK,UACnD,OAAO;CAEX;CACA,OAAO;AACT;AAEA,IAAa,yBAAb,MAAoC;CAClC,2BAAoB,IAAI,IAA4B;CACpD;CACA;CACA;;;;;CAMA,YACE,OACA,SAA+B,uBAC/B,YACA;EACA,KAAK,SAAS;EACd,KAAK,UAAU;EACf,IAAI,UAAU;EACd,KAAK,cACH,qBACO;GACL,WAAW;GACX,OAAO,OAAO,OAAO;EACvB;CACJ;;;;;;;CAQA,QAAQ,SAA0C;EAChD,MAAM,MAAM,KAAK,OAAO;EACxB,KAAK,SAAS,MAAM;EACpB,KAAK,MAAM,UAAU,SACnB,KAAK,SAAS,IAAI,cAAc,OAAO,GAAG,GAAG,YAAY,QAAQ,GAAG,CAAC;CAEzE;;;;;;;;;;CAWA,QAAQ,SAA0C;EAChD,MAAM,MAAM,KAAK,OAAO;EACxB,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,QAAQ,YAAY,QAAQ,GAAG;GACrC,MAAM,UACJ,MAAM,QAAQ,UAAU,cACpB;IACE,OAAO;IACP,UAAU,MAAM,QAAQ;IACxB,WAAW,MAAM,QAAQ;IACzB,UAAU;GACZ,IACA,MAAM;GACZ,KAAK,SAAS,IAAI,cAAc,MAAM,GAAG,GAAG;IAAE,GAAG;IAAO;IAAS,WAAW;GAAI,CAAC;EACnF;CACF;CAEA,QAAQ,OAAoC;EAC1C,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,KAAK,cAAc,MAAM,GAAG;EAClC,MAAM,WAAW,KAAK,SAAS,IAAI,EAAE;EAGrC,MAAM,UAAU,iBADd,aAAa,KAAA,IAAY,cAAc,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,GAAG,GAC5C,OAAO,KAAK,KAAK,OAAO;EAChE,KAAK,SAAS,IAAI,IAAI,OAAO;EAC7B,OAAO;CACT;CAEA,aAAa,KAAkB,KAAyC;EACtE,MAAM,KAAK,cAAc,GAAG;EAC5B,MAAM,SAAS,KAAK,SAAS,IAAI,EAAE;EACnC,IAAI,WAAW,KAAA,GACb;EAEF,MAAM,QAAQ,YAAY,QAAQ,GAAG;EACrC,IAAI,UAAU,QACZ,KAAK,SAAS,IAAI,IAAI,KAAK;EAE7B,OAAO;CACT;;;;;;;;CASA,OAAO,KAA8B;EACnC,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,UAAU,cAAc,GAAG,CAAC,CAAC,KAAK,aAAa,KAAK,aAAa,UAAU,GAAG,CAAC;EAErF,MAAM,OAAO,QAAQ,SAAS,GAAG;EACjC,IAAI,SAAS,KAAA,GACX,OAAO,QAAQ,KAAK,QAAQ,KAAK,KAAK,KAAK,SAAS;EAQtD,MAAM,MAA4D,CAAC;EACnE,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,WAAW,KAAA,GACb;GAKF,MAAM,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ,OAAO;GACrE,MAAM,UACJ,YAAY,OAAO,UAAU,SAAS;IAAE,GAAG;IAAQ,SAAS;IAAS,WAAW;GAAI;GACtF,IAAI,YAAY,QACd,KAAK,SAAS,IAAI,cAAc,OAAO,GAAG,GAAG,OAAO;GAEtD,MAAM,YAAY,WAAW,QAAQ,SAAS,GAAG;GACjD,IAAI,UAAU,SAAS,WACrB,OAAO,QAAQ,gBAAgB,OAAO,KAAK,UAAU,SAAS;GAEhE,IAAI,UAAU,SAAS,aACrB,OAAO,QAAQ,mBAAmB,OAAO,KAAK,KAAA,CAAS;GAEzD,IAAI,UAAU,SAAS,YACrB,IAAI,KAAK;IAAE;IAAQ,SAAS,UAAU;GAAO,CAAC;EAElD;EACA,MAAM,QAAQ,IAAI;EAClB,IAAI,UAAU,KAAA,GAAW;GACvB,MAAM,UAAU,KAAK,YAAY;GACjC,KAAK,SAAS,IAAI,cAAc,MAAM,OAAO,GAAG,GAAG;IACjD,GAAG,MAAM;IACT,SAAS;KAAE,GAAG,MAAM;KAAS;KAAS,SAAS;IAAI;IACnD,WAAW;GACb,CAAC;GACD,OAAO;IAAE,MAAM;IAAS,QAAQ;KAAE,IAAI;KAAS,KAAK,MAAM,OAAO;IAAI;GAAE;EACzE;EAGA,IAAI;EACJ,KAAK,MAAM,UAAU,SACnB,IAAI,QAAQ,WAAW,YACrB,WAAW;EAGf,IAAI,aAAa,KAAA,GACf,OAAO,QAAQ,YAAY,SAAS,KAAK,KAAA,CAAS;EAGpD,OAAO,EAAE,MAAM,YAAY;CAC7B;;;;;;CAOA,SAAS,KAA8B;EACrC,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,UAAU,cAAc,GAAG,CAAC,CAAC,KAAK,aAAa,KAAK,aAAa,UAAU,GAAG,CAAC;EACrF,MAAM,OAAO,QAAQ,SAAS,GAAG;EACjC,IAAI,SAAS,KAAA,GACX,OAAO,QAAQ,KAAK,QAAQ,KAAK,KAAK,KAAK,SAAS;EAEtD,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,WAAW,KAAA,GAAW;GAI1B,MAAM,OAAO,iBAAiB,OAAO,SAAS,GAAG;GACjD,IAAI,SAAS,KAAA,GACX,OAAO,QAAQ,gBAAgB,OAAO,KAAK,IAAI;GAEjD,IAAI,OAAO,QAAQ,UAAU,aAC3B,OAAO,QAAQ,mBAAmB,OAAO,KAAK,KAAA,CAAS;EAE3D;EACA,IAAI;EACJ,KAAK,MAAM,UAAU,SACnB,IAAI,QAAQ,WAAW,YACrB,WAAW;EAGf,IAAI,aAAa,KAAA,GACf,OAAO,QAAQ,YAAY,SAAS,KAAK,KAAA,CAAS;EAEpD,OAAO,EAAE,MAAM,YAAY;CAC7B;;;;;;CAOA,YAAY,QAAqB,SAAgC;EAC/D,MAAM,MAAM,KAAK,OAAO;EACxB,MAAM,KAAK,cAAc,OAAO,GAAG;EACnC,MAAM,SAAS,KAAK,SAAS,IAAI,EAAE;EACnC,IAAI,WAAW,KAAA,GACb,OAAO;EAET,MAAM,UAAU,OAAO;EACvB,IAAI,QAAQ,UAAU,eAAe,QAAQ,YAAY,OAAO,IAC9D,OAAO;EAET,MAAM,OAAO,QAAQ,UACjB,mBAAmB,OAAO,IAC1B,mBAAmB,SAAS,QAAQ,UAAU,KAAK,KAAK,QAAQ,OAAO;EAC3E,KAAK,SAAS,IAAI,IAAI;GAAE,GAAG;GAAQ,SAAS;GAAM,WAAW;EAAI,CAAC;EAClE,OAAO;CACT;;;;;;CAOA,aAAa,QAA8B;EACzC,MAAM,KAAK,cAAc,OAAO,GAAG;EACnC,MAAM,SAAS,KAAK,SAAS,IAAI,EAAE;EACnC,IAAI,QAAQ,QAAQ,UAAU,eAAe,OAAO,QAAQ,YAAY,OAAO,IAC7E,OAAO;EAET,KAAK,SAAS,IAAI,IAAI;GACpB,GAAG;GACH,SAAS,aAAa,OAAO,OAAO;GACpC,WAAW,KAAK,OAAO;EACzB,CAAC;EACD,OAAO;CACT;;CAGA,UAAU,KAA8C;EACtD,OAAO,KAAK,aAAa,KAAK,KAAK,OAAO,CAAC;CAC7C;;CAGA,WAA6B;EAC3B,MAAM,MAAM,KAAK,OAAO;EACxB,OAAO,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,YAAY,QAAQ,GAAG,CAAC;CAC7E;AACF;;;;;;;;;;;ACvWA,SAASC,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAASC,iBAAe,KAA6B;CACnD,OAAO,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG;AACvD;AAEA,SAAS,iBAAiB,KAA6B;CACrD,OAAOA,iBAAe,GAAG,KAAK,OAAO,UAAU,GAAG,KAAK,OAAO;AAChE;AAEA,SAAS,WACP,KACA,YACuB;CACvB,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,WAAW,MAAM,UAAU,UAAU,GAAG;AACjD;;;;;;AAOA,SAASC,kBAAgB,KAAkC;CACzD,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,IAAI,SAAS,KAAK,OAAO,KAAA;CACtE,OAAO;AACT;AAEA,SAASC,WAAS,KAAuC;CACvD,IAAI,CAACH,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,aAAaE,kBAAgB,IAAI,aAAa;CACpD,IAAI,eAAe,KAAA,GAAW,OAAO,KAAA;CACrC,MAAM,YAAYA,kBAAgB,IAAI,YAAY;CAClD,MAAM,UAAUA,kBAAgB,IAAI,UAAU;CAC9C,MAAM,YAAYA,kBAAgB,IAAI,YAAY;CAElD,IAAI,IAAI,iBAAiB,KAAA,KAAa,cAAc,KAAA,GAAW,OAAO,KAAA;CACtE,IAAI,IAAI,eAAe,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,KAAA;CAClE,IAAI,IAAI,iBAAiB,KAAA,KAAa,cAAc,KAAA,GAAW,OAAO,KAAA;CAGtE,IAAI,cAAc,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,KAAA;CAC7D,OAAO;EACL;EACA,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;EAC/C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CACjD;AACF;AAEA,SAAS,aAAa,KAAyC;CAC7D,IAAI,CAACF,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,QAAQ,WAAW,IAAI,UAAU,cAAc;CACrD,MAAM,WAAW,IAAI;CACrB,MAAM,YAAY,IAAI;CACtB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,EAAE,iBAAiB,QAAQ,KAAK,iBAAiB,SAAS,IAAI,OAAO,KAAA;CACzE,MAAM,WAAW,IAAI;CACrB,MAAM,UAAUE,kBAAgB,IAAI,UAAU;CAC9C,MAAM,UAAU,IAAI;CACpB,OAAO;EACL;EACA;EACA;EACA,GAAID,iBAAe,QAAQ,IAAI,EAAE,SAAS,IAAI,CAAC;EAC/C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAIA,iBAAe,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;CAC/C;AACF;AAEA,SAAS,YAAY,KAA0C;CAC7D,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,OAAO,WAAW,IAAI,SAAS,CAAC,cAAc,OAAO,CAAU;CACrE,MAAM,QAAQ,IAAI;CAClB,IAAI,SAAS,KAAA,KAAa,CAACC,iBAAe,KAAK,GAAG,OAAO,KAAA;CACzD,OAAO;EAAE;EAAM;CAAM;AACvB;AAEA,SAAS,YAAY,KAA0C;CAC7D,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,MAAMG,WAAS,IAAI,MAAM;CAC/B,MAAM,SAAS,WAAW,IAAI,WAAW,aAAa;CACtD,MAAM,UAAU,aAAa,IAAI,UAAU;CAC3C,MAAM,YAAY,IAAI;CACtB,IAAI,QAAQ,KAAA,KAAa,WAAW,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,KAAA;CAC/E,IAAI,CAACF,iBAAe,SAAS,GAAG,OAAO,KAAA;CACvC,MAAM,SAAS,YAAY,IAAI,SAAS;CAIxC,KAAK,WAAW,kBAAkB,WAAW,sBAAsB,WAAW,KAAA,GAC5E;CAEF,OAAO;EACL;EACA;EACA;EACA,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EACzC;CACF;AACF;AAEA,SAAgB,mBAAmB,KAAgC;CACjE,IAAI,CAACD,WAAS,GAAG,GAAG,OAAO,CAAC;CAC5B,IAAI,IAAI,eAAA,GAA+B,OAAO,CAAC;CAC/C,MAAM,OAAO,IAAI;CACjB,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO,CAAC;CAClC,MAAM,SAA2B,CAAC;CAClC,KAAK,MAAM,SAAS,KAAK,MAAM,GAAG,GAAG,GAAG;EACtC,MAAM,SAAS,YAAY,KAAK;EAChC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAK,MAAM;CAC9C;CACA,OAAO;AACT;;;;;;;ACnHA,SAAgB,sBAAsB,SAAsD;CAC1F,OAAO,QAAQ,SAAA,MACX,CAAC,GAAG,OAAO,CAAC,CACT,MAAM,MAAM,UAAU,MAAM,YAAY,KAAK,SAAS,CAAC,CACvD,MAAM,GAAA,GAAqB,IAC9B,CAAC,GAAG,OAAO;AACjB;;;;;;;;;;ACWA,SAAgB,WACd,QACA,QACY;CACZ,OAAO,OAAO,KAAK,QAAQ,YAAY;EACrC,MAAM,WAAW,IAAI,uBAAuB,OAAO,OAAO,uBAAuB,OAAO,KAAK;EAC7F,SAAS,QAAQ,mBAAmB,OAAO,CAAC;EAC5C,MAAM,SAAS,OAAO,QAAQ;EAC9B,OAAO;GACL,MAAM;IAAE,SAAA;IAAyB,SAAS,sBAAsB,SAAS,SAAS,CAAC;GAAE;GACrF;EACF;CACF,CAAC;AACH;AAEA,SAAS,MAAM,KAA4B;CACzC,OAAO;EAAE,YAAY,IAAI;EAAY,SAAS,IAAI;CAAG;AACvD;;;;;;;AAQA,SAAgB,iBACd,UACA,YAC2F;CAC3F,MAAM,SAAqC,CAAC;CAC5C,MAAM,UAAyB,CAAC;CAChC,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,aAAa,SAAS,OAAO,MAAM,GAAG,CAAC;EAC7C,OAAO,mBAAmB,GAAG,KAAK;EAClC,IAAI,WAAW,SAAS,SAAS,QAAQ,KAAK,WAAW,MAAM;CACjE;CACA,OAAO;EAAE;EAAQ;CAAQ;AAC3B;AAEA,SAAgB,kBACd,UACA,SACA,UACM;CACN,KAAK,MAAM,UAAU,SACnB,IAAI,OAAO,IAAI,eAAe,UAAU,cAAc,OAAO,IAAI,YAAY,SAAS,IACpF,SAAS,aAAa,MAAM;AAClC;;;;;;;;AASA,SAAgB,eACd,UACA,KACA,SACmC;CACnC,MAAM,MAAM,MAAM,GAAG;CACrB,IAAI,QAAQ,eAAe,WAAW,OAAO,KAAA;CAC7C,IAAI,QAAQ,eAAe,SAAS;EAClC,SAAS,QAAQ;GAAE,MAAM;GAAW;EAAI,CAAC;EACzC;CACF;CACA,MAAM,iBAAiB,gBAAgB,gBAAgB,OAAO,CAAC;CAC/D,MAAM,UAAU,SAAS,UAAU,GAAG,CAAC,EAAE;CACzC,IAAI,SAAS,UAAU,eAAe,QAAQ,YAAY,KAAA,GACxD,SAAS,YACP;EAAE,IAAI,QAAQ;EAAS;CAAI,GAC3B;EAAE,SAAS;EAAO,UAAU,eAAe;CAAS,CACtD;CACF,SAAS,QAAQI,eAAa,KAAK,cAAc,CAAC;CAClD,OAAO;AACT;;;;;;;;;;;;;;;;ACjGA,MAAa,kBAAkB;;AAG/B,MAAa,qBAAqB,CAAC,WAAW,WAAW;;;;;;;ACHzD,MAAa,oBAAoB;;;;;;;AAQjC,SAAgB,kBAAkB,eAAgC;CAChE,OAAO,cAAc,SAAS,iBAAiB;AACjD;AAUA,SAAS,cAAc,OAAe,KAAiC;CAErE,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,YAAY,IACd;CAEF,MAAM,SAAS,OAAO,OAAO;CAC7B,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,KACvC;CAEF,OAAO;AACT;AAEA,SAAS,mBAAsC;CAC7C,OAAO;EACL,aAAa,KAAA;EACb,WAAW,KAAA;EACX,mBAAmB,KAAA;EACnB,gBAAgB,KAAA;CAClB;AACF;AAEA,SAAS,WAAW,aAAgC,QAAoC;CACtF,QAAQ,QAAR;EACE,KAAK,gBACH,OAAO,YAAY;EACrB,KAAK,uBACH,OAAO,YAAY;EACrB,KAAK,YACH,OAAO,YAAY;EACrB,SACE;CACJ;AACF;AAEA,SAAS,WAAW,aAAgC,QAAgB,OAAqB;CAEvF,IAAI,WAAW,aAAa,MAAM,MAAM,KAAA,GACtC;CAEF,QAAQ,QAAR;EACE,KAAK,gBAAgB;GAGnB,MAAM,cAAc,cAAc,OAAO,CAAC;GAC1C,IAAI,gBAAgB,KAAA,GAClB;GAEF,IAAI,cAAc,KAAK;IACrB,YAAY,YAAY;IACxB;GACF;GACA,YAAY,cAAc;GAC1B;EACF;EACA,KAAK,uBAAuB;GAC1B,MAAM,oBAAoB,cAAc,OAAO,CAAC;GAChD,IAAI,sBAAsB,KAAA,GACxB,YAAY,oBAAoB;GAElC;EACF;EACA,KAAK,YAAY;GAIf,MAAM,iBAAiB,cAAc,OAAO,CAAC;GAC7C,IAAI,mBAAmB,KAAA,GACrB,YAAY,iBAAiB;GAE/B;EACF;EACA,SAEE;CACJ;AACF;AAEA,SAAS,SAAS,aAAyD;CACzE,MAAM,cAAc,YAAY;CAChC,IAAI,gBAAgB,KAAA,GAClB;CAEF,MAAM,EAAE,mBAAmB,mBAAmB;CAC9C,OAAO;EACL;EACA,GAAI,sBAAsB,KAAA,IAAY,EAAE,kBAAkB,IAAI,CAAC;EAC/D,GAAI,mBAAmB,KAAA,IAAY,EAAE,eAAe,IAAI,CAAC;CAC3D;AACF;;;;;;;AAQA,SAAgB,gBAAgB,UAA+D;CAC7F,MAAM,eAAuE;EAC3E,SAAS,KAAA;EACT,WAAW,KAAA;CACb;CACA,KAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,QAAQ,GAAG;EACvD,MAAM,OAAO,QAAQ,YAAY,CAAC,CAAC,QAAQ,iBAAiB;EAC5D,IAAI,OAAO,GACT;EAEF,MAAM,OAAO,QAAQ,MAAM,OAAO,CAAwB,CAAC,CAAC,YAAY;EACxE,MAAM,YAAY,KAAK,QAAQ,GAAG;EAClC,MAAM,OAAO,KAAK,MAAM,GAAG,SAAS;EACpC,IAAI,CAAE,mBAAyC,SAAS,IAAI,GAC1D;EAEF,MAAM,MAAM;EACZ,MAAM,cAAc,aAAa,QAAQ,iBAAiB;EAC1D,WAAW,aAAa,KAAK,MAAM,YAAY,CAAC,GAAG,KAAK;EACxD,aAAa,OAAO;CACtB;CAIA,IAAI,aAAa,SAAS,cAAc,QAAQ,aAAa,WAAW,cAAc,MACpF,OAAO;CAET,MAAM,UAAU,SAAS,aAAa,WAAW,iBAAiB,CAAC;CACnE,MAAM,YAAY,SAAS,aAAa,aAAa,iBAAiB,CAAC;CACvE,IAAI,YAAY,KAAA,KAAa,cAAc,KAAA,GACzC,OAAO;CAET,OAAO;EACL,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CACjD;AACF;;ACvJA,MAAa,iBAAiB;AAE9B,SAAS,SAAS,QAA8B;CAC9C,OAAO,OAAO,sBAAsB,KAAA,KAAa,OAAO,mBAAmB,KAAA;AAC7E;;;;;AAMA,SAAgB,cAAc,OAA4C;CACxE,MAAM,UAAU,MAAM;CACtB,MAAM,YAAY,MAAM;CACxB,IAAI,YAAY,KAAA,GACd,OAAO;CAET,IAAI,cAAc,KAAA,GAChB,OAAO;CAET,OAAO,UAAU,cAAc,QAAQ,cAAc,YAAY;AACnE;AAEA,SAAgB,iBAAiB,OAAmB,YAAqC;CACvF,MAAM,SAAS,cAAc,KAAK;CAClC,IAAI,WAAW,KAAA,GAEb,OAAO;EAAE,YAAY;EAAO;EAAY,UAAU;CAAe;CAEnE,MAAM,YAAY,OAAO,cAAc;CACvC,MAAM,iBAAiB,IAAI;CAC3B,IAAI;CACJ,IAAI,OAAO,sBAAsB,KAAA,GAC/B,UAAU,aAAa,OAAO,oBAAoB;MAC7C,IAAI,OAAO,mBAAmB,KAAA,GACnC,UAAU,OAAO,iBAAiB;CAEpC,MAAM,aAAyB,SAAS,MAAM,IAAI,SAAS;CAC3D,OAAO;EACL;EACA;EACA,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C;EACA;EACA,UAAU;CACZ;AACF;;AC9CA,IAAa,sBAAb,MAA2D;CACzD,KAAc;CACd;CACA,SAA4B;CAC5B,cAAc;CAEd,YAAY,UAAuB;EACjC,KAAK,WAAW;CAClB;;;;;CAMA,QAAQ,UAA4C,YAA0B;EAC5E,KAAK,SAAS,gBAAgB,QAAQ;EACtC,IAAI,KAAK,WAAW,MAClB,KAAK,cAAc;CAEvB;CAEA,OAAwC;EACtC,MAAM,QAAQ,KAAK;EACnB,IAAI,UAAU,MACZ,OAAO,QAAQ,QAAQ,IAAI;EAE7B,OAAO,QAAQ,QAAQ,iBAAiB,OAAO,KAAK,WAAW,CAAC;CAClE;AACF;;ACjCA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,eAAe,KAA6B;CACnD,OAAO,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG;AACvD;;;;;;AAOA,SAAS,gBAAgB,KAAkC;CACzD,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,IAAI,SAAS,KAAK,OAAO,KAAA;CACtE,OAAO;AACT;AAEA,SAASC,WAAS,KAAuC;CACvD,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,aAAa,gBAAgB,IAAI,aAAa;CACpD,IAAI,eAAe,KAAA,GAAW,OAAO,KAAA;CACrC,MAAM,YAAY,gBAAgB,IAAI,YAAY;CAClD,MAAM,UAAU,gBAAgB,IAAI,UAAU;CAC9C,MAAM,YAAY,gBAAgB,IAAI,YAAY;CAElD,IAAI,IAAI,iBAAiB,KAAA,KAAa,cAAc,KAAA,GAAW,OAAO,KAAA;CACtE,IAAI,IAAI,eAAe,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,KAAA;CAClE,IAAI,IAAI,iBAAiB,KAAA,KAAa,cAAc,KAAA,GAAW,OAAO,KAAA;CAGtE,IAAI,cAAc,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,KAAA;CAC7D,OAAO;EACL;EACA,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;EAC/C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CACjD;AACF;AAEA,SAAS,WAAW,KAAkC;CACpD,OAAO,eAAe,GAAG,KAAK,OAAO,KAAK,OAAO,IAAI,MAAM,KAAA;AAC7D;AAEA,SAAS,aAAa,KAA2C;CAC/D,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,aAAa,kBAAkB,MAAM,UAAU,UAAU,IAAI,aAAa;CAChF,IAAI,eAAe,KAAA,GAAW,OAAO,KAAA;CACrC,MAAM,aAAa,IAAI;CACvB,IAAI,CAAC,eAAe,UAAU,KAAK,aAAa,GAAG,OAAO,KAAA;CAC1D,MAAM,YAAY,WAAW,IAAI,YAAY;CAC7C,MAAM,iBAAiB,WAAW,IAAI,iBAAiB;CACvD,MAAM,eACJ,eAAe,IAAI,eAAe,KAAK,IAAI,mBAAmB,IAC1D,IAAI,kBACJ,KAAA;CACN,MAAM,UAAU,eAAe,IAAI,UAAU,KAAK,IAAI,cAAc,IAAI,IAAI,aAAa,KAAA;CAGzF,IACE,cAAc,KAAA,KACd,mBAAmB,KAAA,KACnB,iBAAiB,KAAA,KACjB,YAAY,KAAA,GAEZ;CAEF,MAAM,WAAW,IAAI;CACrB,OAAO;EACL,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;EAC/C,GAAI,mBAAmB,KAAA,IAAY,EAAE,eAAe,IAAI,CAAC;EACzD,GAAI,iBAAiB,KAAA,IAAY,EAAE,aAAa,IAAI,CAAC;EACrD,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C;EACA;EACA,GAAI,OAAO,aAAa,YAAY,SAAS,SAAS,IAClD,EAAE,UAAU,SAAS,MAAM,GAAG,GAAG,EAAE,IACnC,CAAC;CACP;AACF;AAEA,SAAS,WAAW,KAAoD;CACtE,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,KAAA;CAC3B,MAAM,MAAMA,WAAS,IAAI,MAAM;CAC/B,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAA;CAC9B,MAAM,UAAU,aAAa,IAAI,UAAU;CAC3C,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;CAClC,OAAO;EAAE;EAAK;CAAQ;AACxB;AAOA,SAAgB,qBAAqB,KAA0C;CAC7E,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,CAAC;CAC5B,IAAI,IAAI,eAAA,GAAiC,OAAO,CAAC;CACjD,IAAI,CAAC,MAAM,QAAQ,IAAI,WAAW,GAAG,OAAO,CAAC;CAC7C,MAAM,OAAO,IAAI;CACjB,MAAM,WAAuC,CAAC;CAC9C,KAAK,MAAM,SAAS,KAAK,MAAM,GAAA,EAAwB,GAAG;EACxD,MAAM,SAAS,WAAW,KAAK;EAC/B,IAAI,WAAW,KAAA,GAAW,SAAS,KAAK,MAAM;CAChD;CACA,OAAO;AACT;;AC/EA,SAASC,QAAM,KAA0C;CACvD,IAAI,QAAQ,KAAA,GAAW,OAAO,CAAC;CAC/B,MAAM,WAAW,qBAAqB,GAAG;CAGzC,IAAI,CAAC,kBAAkB,KAAK;EAAE,SAAA;EAA2B;CAAS,CAAC,GACjE,MAAM,IAAI,MAAM,kDAAkD;CACpE,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAsC;CAC7D,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAC9D,MAAM,IAAI,MAAM,8CAA8C;CAChE,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,GAAG,GAAG;EAC/C,IAAI,CAAC,kBAAkB,KAAK,YAAY,CAAC,GAAG;EAC5C,IAAI,OAAO,UAAU,UACnB,MAAM,IAAI,MAAM,wDAAwD;EAC1E,QAAQ,QAAQ;CAClB;CACA,OAAO;AACT;;;;;;;;AASA,eAAsB,oBACpB,QACA,YACA,SACe;CACf,IAAI;EACF,IAAI,OAAO,eAAe,YAAY,eAAe,MAAM,WAAW,SAAS,KAC7E,MAAM,IAAI,MAAM,iEAAiE;EACnF,MAAM,SAAS,IAAI,oBAAoB,EAAE,WAAW,CAAC;EACrD,OAAO,QAAQ,gBAAgB,OAAO,GAAG,OAAO,MAAM,CAAC;EACvD,MAAM,UAAU,iBAAiB,MAAM,OAAO,KAAK,CAAC;EACpD,IAAI,YAAY,MAAM;EACtB,MAAM,QAAQ;GAAE,KAAK,OAAO;GAAU;EAAQ;EAC9C,MAAM,OAAO,KAAK,QAAQ,YAAY;GAGpC,MAAM,QAAQ,IAAI,IAAIA,QAAM,OAAO,CAAC,CAAC,KAAK,SAAS,CAAC,cAAc,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC;GACnF,MAAM,KAAK,cAAc,MAAM,GAAG;GAClC,MAAM,WAAW,MAAM,IAAI,EAAE;GAC7B,IAAI,aAAa,KAAA,KAAa,QAAQ,aAAa,SAAS,QAAQ,YAClE,MAAM,IAAI,IAAI,KAAK;GAIrB,OAAO;IAAE,MAAM;KAAE,SAAA;KAA2B,UAH3B,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CACjC,MAAM,GAAG,MAAM,EAAE,QAAQ,aAAa,EAAE,QAAQ,UAAU,CAAC,CAC3D,MAAM,GAAA,EACmC;IAAS;IAAG,QAAQ,KAAA;GAAU;EAC5E,CAAC;CACH,QAAQ;EAEN,YAAY,oBAAoB,kCAAkC;CACpE;AACF;;AAGA,eAAsB,aACpB,QACA,YACuB;CACvB,MAAM,WAA+D,CAAC;CACtE,MAAM,WAAmD,CAAC;CAC1D,KAAK,MAAM,OAAO,YAAY,SAAS,mBAAmB,GAAG,KAAK;CAClE,IAAI;EACF,MAAM,UAAU,MAAM,OAAO,KAAK,QAAQ,aAAa;GACrD,MAAM,KAAA;GACN,QAAQA,QAAM,OAAO;EACvB,EAAE;EACF,MAAM,MAAM,OAAO,MAAM;EACzB,KAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,QAAQ,IAAI,IAChB,cAAc;IAAE,YAAY,IAAI;IAAY,SAAS,IAAI;IAAI,WAAW,IAAI;GAAQ,CAAC,CAAC,CAAC,IACrF,aACF,CACF;GACA,MAAM,UAAU,cACd,QACG,QAAQ,UAAU,MAAM,IAAI,cAAc,MAAM,GAAG,CAAC,CAAC,CAAC,CACtD,KAAK,UAAU,MAAM,OAAO,GAC/B,GACF;GACA,MAAM,KAAK,mBAAmB,GAAG;GACjC,SAAS,MAAM;GACf,IAAI,YAAY,MAAM,SAAS,MAAM,gBAAgB,OAAO;EAC9D;CACF,QAAQ;EACN,YAAY,iBAAiB,6BAA6B;CAC5D;CACA,OAAO;EAAE;EAAU;CAAS;AAC9B;;;ACnIA,SAAgB,iBAAiB,QAAwB;CACvD,IAAI;CACJ,IAAI,YAAY;CAChB,OAAO;EACL,SAAS,UAAkB;GACzB,IAAI,aAAa,KAAA,GAAW,YAAY;GACxC,WAAW;EACb;EACA,QAAQ;GACN,WAAW,KAAA;GACX,YAAY;EACd;EACA,MAAM,SAAS,SAAkB;GAC/B,IAAI,CAAC,aAAa,aAAa,KAAA,GAAW,MAAM,oBAAoB,QAAQ,UAAU,OAAO;EAC/F;CACF;AACF;;ACfA,MAAa,aAAa;;AAkB1B,SAAgB,QAAQ,MAAc,OAAuB;CAC3D,OAAO,gBAAgB,yBAAyB,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG;AAChF;AAEA,SAAgB,gBAAgB,IAAqB;CACnD,GAAG,sBAAsB,aAAa,OAAO,SAAS,UAAU;EAC9D,MAAM,OAAgB,MAAM;EAC5B,IAAI,CAACC,SAAO,IAAI,KAAK,KAAK,eAAe,KAAK,OAAO,KAAK,YAAY,UAAU,OAAO,KAAA;EACvF,MAAM,OAAO,KAAK;EAClB,MAAM,KAAK,KAAK;EAChB,MAAM,SACJ,QAAQ,YAAY,OAAO,OAAO,WAAW,eAAe,OAAO,EAAE,EAAE,oBAAoB;EAC7F,OAAO;GACL,SAAS,UAAU,CAAC,MAAM,GAAG,OAAO,QAAQ,cAAc,OAAO,UAAU,KAAK,CAAC,CAAC;GAClF,aAAa,CAEb;EACF;CACF,CAAC;AACH;AAEA,SAAgB,WACd,IACA,MACM;CACN,GAAG,YAAY,YAAY,IAAI;AACjC;;ACxCA,SAAgB,QAAQ,UAAoB,MAA+B;CACzE,IAAI,SAAS,WACX,OAAO;EAAE,MAAM;EAAgB,OAAO;CAAS;CAEjD,IAAI,SAAS,UACX,OAAO;CAET,OAAO;EAAE,MAAM;EAAS,QAAQ;CAAe;AACjD;;;;;;;;;;;ACFA,MAAa,gBAAgB;;AAE7B,MAAa,cAAc;;AAE3B,MAAa,kBAAkB;;;;;;AAM/B,MAAa,cAAc;;AAE3B,MAAa,oBAAoB;;;;;;AAOjC,SAAS,eAAe,QAAwB,KAAiC;CAC/E,IAAI,OAAO,WAAW,iBAAiB,OAAO,QAAQ,UAAU,aAC9D;CAEF,IAAI,KAAK;CACT,IAAI,OAAO,WAAW,qBAAqB,OAAO,WAAW,gBAAgB;EAC3E,IAAI,OAAO,WAAW,KAAA,GAAW,OAAO,KAAA;EACxC,KAAK,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK;CACvC;CACA,IAAI,OAAO,QAAQ,UAAU,QAC3B,KAAK,KAAK,IAAI,IAAI,OAAO,QAAQ,YAAY,GAAG;CAElD,OAAO;AACT;;;;;;;AAQA,SAAgB,iBACd,OACA,SACA,KACoB;CACpB,IAAI,KAAK;CACT,KAAK,MAAM,UAAU,OAAO;EAC1B,IAAI,WAAW,KAAA,GAAW;EAC1B,MAAM,SAAS,eAAe,QAAQ,GAAG;EACzC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,KAAK,KAAK,IAAI,IAAI,MAAM;CAC1B;CACA,IAAI,YAAY,QAAQ,gBAAgB,OAAO,CAAC,CAAC,WAAW;EAC1D,MAAM,QAAQ,QAAQ,aAAa,wBAAwB;EAC3D,MAAM,QAAQ,QAAQ,WAAW;EACjC,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC;CAC1C;CACA,OAAO;AACT;;AAGA,SAAgB,eAAe,OAA4D;CACzF,IAAI;CACJ,KAAK,MAAM,QAAQ,OACjB,IAAI,SAAS,KAAA,MAAc,aAAa,KAAA,KAAa,OAAO,WAAW,WAAW;CAEpF,OAAO;AACT;;;;;;;AAqBA,SAAgB,SACd,SACA,KACA,WACsB;CACtB,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;CACjC,MAAM,QAAQ,eAAe,OAAO;CACpC,IAAI,QAAQ,UAAU,KAAA,IAAY,OAAO,oBAAoB,QAAQ;CACrE,IAAI,QAAQ,SAAS,KAAA,CAAS,GAAG,QAAQ,KAAK,IAAI,OAAO,MAAM,eAAe;CAC9E,MAAM,QACJ,cAAc,IAAI,cAAc,KAAK,IAAI,aAAa,oBAAoB,MAAM,YAAY,EAAE;CAChG,QAAQ,KAAK,IAAI,OAAO,MAAM,KAAK;CACnC,MAAM,SAAS,QAAQ,MAAM;CAC7B,OAAO;EAAE;EAAO,SAAS,SAAS,cAAc,QAAQ;EAAK;CAAO;AACtE;;;;;;;;;ACxFA,MAAa,YAAA;AAEb,MAAa,aAAa;AAC1B,IAAa,gBAAb,cAAmC,MAAM;CACvC,cAAc;EACZ,MAAM,yBAAyB;CACjC;AACF;AAEA,SAASC,QAAM,OAAgB,KAAsB;CACnD,OAAO,OAAO,UAAU,YAAY,UAAU,OAC1C,OAAO,yBAAyB,OAAO,GAAG,CAAC,EAAE,QAC7C,KAAA;AACN;AAEA,SAAgB,YAAY,OAAwB;CAClD,MAAM,UAAUA,QAAM,OAAO,SAAS;CACtC,MAAM,QAAQA,QAAM,OAAO,OAAO;CAClC,MAAM,OAAOA,QAAM,OAAO,MAAM;CAChC,MAAM,MAAMA,QAAM,OAAO,KAAK;CAC9B,MAAM,QAAQA,QAAM,OAAO,OAAO;CAClC,MAAM,UAAUA,QAAM,OAAO,SAAS;CACtC,IAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,GACpD,MAAM,IAAI,MAAM,qDAAqD;CACvE,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAI,MAAM,mDAAmD;CACrE,IAAI,OAAO,SAAS,YAAY,CAAC,WAAW,IAAI,GAC9C,MAAM,IAAI,MAAM,4DAA4D;CAC9E,IAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,GAC5D,MAAM,IAAI,MAAM,iDAAiD;CAGnE,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GACvE,MAAM,IAAI,MAAM,uDAAuD;CACzE,IAAI,OAAO,YAAY,WAAW,MAAM,IAAI,MAAM,0CAA0C;CAC5F,OAAO;EAAE;EAAS;EAAO;EAAM;EAAK;EAAO;CAAQ;AACrD;AAEA,SAAS,QAAQ,OAA0B;CACzC,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,MAAM,OAAOA,QAAM,OAAO,SAAS;CACnC,IAAIA,QAAM,OAAO,SAAS,MAAM,KAAK,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,KACzE,MAAM,IAAI,MAAM,6DAA6D;CAC/E,OAAO,KAAK,IAAI,WAAW;AAC7B;AAEA,SAAgB,SAAS,MAAgB,QAA+B;CACtE,OAAO,KAAK,QAAQ,WAAW;EAC7B,MAAM;GACJ,SAAS;GACT,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,QAAQ,QAAQ,IAAI,YAAY,OAAO,OAAO,GAAG,MAAM,CAAC,CAAC,MACnF,IACF;EACF;EACA,QAAQ,KAAA;CACV,EAAE;AACJ;AAEA,SAAgB,SAAS,MAAgB,SAA8C;CACrF,OAAO,KAAK,QAAQ,WAAW;EAC7B,MAAM,KAAA;EACN,QAAQ,QAAQ,KAAK,CAAC,CAAC,MAAM,QAAQ,IAAI,YAAY,WAAW,CAAC,IAAI,OAAO;CAC9E,EAAE;AACJ;;;;;;;AAQA,SAAgB,UACd,MACA,QACA,KACA,SAAS,OACS;CAClB,OAAO,KAAK,QAAQ,UAAU;EAC5B,MAAM,OAAO,QAAQ,KAAK;EAC1B,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,YAAY,OAAO,WAAW,IAAI,UAAU,OAAO,KAAK;EAC7F,MAAM,UACJ,UAAU,KAAA,KACV,CAAC,MAAM,WACP,MAAM,OAAO,QACZ,UAAU,MAAM,QAAQ;EAC3B,OAAO;GACL,MAAM,UACF;IACE,SAAS;IACT,SAAS,KAAK,KAAK,QAAS,QAAQ,QAAQ;KAAE,GAAG;KAAK,SAAS;IAAK,IAAI,GAAI;GAC9E,IACA,KAAA;GACJ,QAAQ;EACV;CACF,CAAC;AACH;;AAGA,SAAgB,WAAW,MAAgB,SAAmC;CAC5E,OAAO,KAAK,QAAQ,UAAU;EAC5B,MAAM,OAAO,QAAQ,KAAK;EAC1B,OAAO;GACL,MAAM;IAAE,SAAS;IAAG,SAAS,KAAK,QAAQ,QAAQ,IAAI,YAAY,OAAO;GAAE;GAC3E,QAAQ,KAAK,MAAM,QAAQ,IAAI,YAAY,WAAW,CAAC,IAAI,OAAO;EACpE;CACF,CAAC;AACH;;AAGA,eAAsB,UACpB,SACA,KACA,QACA,MACe;CACf,OAAO,QAAQ,MAAM,IAAI,KAAK;EAC5B,IAAI,OAAO,SAAS,MAAM,IAAI,cAAc;EAC5C,MAAM,YAAY,MAAM,QAAQ,MAAM;EACtC,KAAK,SAAS;EACd,MAAM,IAAI,SAAe,SAAS,WAAW;GAC3C,MAAM,cAAc;IAClB,OAAO;IACP,OAAO,IAAI,cAAc,CAAC;GAC5B;GACA,MAAM,SAAS,QAAQ,YACf;IACJ,OAAO,oBAAoB,SAAS,KAAK;IACzC,QAAQ;GACV,GACA,KAAK,IAAI,WAAW,GAAK,CAC3B;GACA,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;EACxD,CAAC;CACH;CACA,IAAI,OAAO,SAAS,MAAM,IAAI,cAAc;AAC9C;;;AClKA,SAAgB,YAAY,SAAS,YAAY,MAAM;CACnD,IAAI,OAAO,YAAY,UACnB,OAAO;CACX,OAAO,QACF,QAAQ,UAAU,MAAM,SAAS,MAAM,CAAC,CACxC,KAAK,UAAU,MAAM,IAAI,CAAC,CAC1B,KAAK,SAAS;AACvB;;AAEA,SAAgB,qBAAqB,SAAS;CAC1C,MAAM,QAAQ,CAAC,YAAY,QAAQ,OAAO,CAAC;CAC3C,KAAK,MAAM,QAAQ,OAAO,OAAO,QAAQ,YAAY,CAAC,CAAC,GACnD,IAAI,SAAS,MACT,MAAM,KAAK,IAAI;CAEvB,OAAO,MAAM,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM;AAC9D;;AChBA,MAAM,kBAAkB;AACxB,MAAM,wBAAwB;AAC9B,SAAgB,uBAAuB,OAAO;CAC1C,OAAO,MAAM,eAAe,MAAM,QAAQ,MAAM,SAAS,MAAM,YAAY,MAAM;AACrF;AACA,SAAS,kBAAkB,OAAO;CAC9B,IAAI;EACA,OAAO,KAAK,UAAU,KAAK,KAAK;CACpC,QACM;EACF,OAAO;CACX;AACJ;AACA,SAAS,iCAAiC,SAAS;CAC/C,IAAI,OAAO,YAAY,UACnB,OAAO,QAAQ;CACnB,IAAI,QAAQ;CACZ,KAAK,MAAM,SAAS,SAChB,SAAS,MAAM,SAAS,SAAS,MAAM,KAAK,SAAS;CACzD,OAAO;AACX;AACA,SAAgB,mBAAmB,MAAM;CACrC,OAAO,KAAK,KAAK,KAAK,SAAS,eAAe;AAClD;AACA,SAAgB,kCAAkC,SAAS;CACvD,OAAO,KAAK,KAAK,iCAAiC,OAAO,IAAI,eAAe;AAChF;AACA,SAAgB,sBAAsB,SAAS;CAC3C,IAAI,QAAQ;CACZ,IAAI,QAAQ,SAAS,UACjB,OAAQ,mBAAmB,qBAAqB,OAAO,CAAC,IACpD,oBAAoB,QAAQ,UAAU,IACtC,oBAAoB,QAAQ,YAAY;CAEhD,IAAI,QAAQ,SAAS,QACjB,OAAO,kCAAkC,QAAQ,OAAO;CAC5D,IAAI,QAAQ,SAAS,cACjB,OAAO,kCAAkC,QAAQ,OAAO;CAC5D,KAAK,MAAM,SAAS,QAAQ,SACxB,IAAI,MAAM,SAAS,QACf,SAAS,MAAM,KAAK;MAEnB,IAAI,MAAM,SAAS,YACpB,SAAS,MAAM,SAAS;MAGxB,SAAS,MAAM,KAAK,SAAS,kBAAkB,MAAM,SAAS,CAAC,CAAC;CAGxE,OAAO,KAAK,KAAK,QAAQ,eAAe;AAC5C;AACA,SAAS,0BAA0B,UAAU;CACzC,IAAI,wBAAwB,OAAO;CACnC,IAAI;CACJ,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACtC,MAAM,UAAU,SAAS;EACzB,IAAI,QAAQ,SAAS,aAAa;GAC9B,MAAM,YAAY;GAIlB,IAD6B,UAAU,aAAa,yBAEhD,UAAU,eAAe,aACzB,UAAU,eAAe,WACzB,uBAAuB,UAAU,KAAK,IAAI,GAC1C,YAAY;IAAE,OAAO,UAAU;IAAO,OAAO;GAAE;EAEvD;EACA,wBAAwB,KAAK,IAAI,uBAAuB,QAAQ,SAAS;CAC7E;CACA,OAAO;AACX;AACA,SAAgB,sBAAsB,SAAS;CAC3C,MAAM,WAAW,cAAc,UAAU,QAAQ,WAAW;CAC5D,MAAM,YAAY,0BAA0B,QAAQ;CACpD,IAAI,WAAW;EACX,MAAM,cAAc,uBAAuB,UAAU,KAAK;EAC1D,IAAI,iBAAiB;EACrB,KAAK,IAAI,IAAI,UAAU,QAAQ,GAAG,IAAI,SAAS,QAAQ,KACnD,kBAAkB,sBAAsB,SAAS,EAAE;EAEvD,OAAO;GAAE,QAAQ,cAAc;GAAgB;GAAa;GAAgB,gBAAgB,UAAU;EAAM;CAChH;CACA,IAAI,SAAS;CACb,KAAK,MAAM,WAAW,UAClB,UAAU,sBAAsB,OAAO;CAC3C,OAAO;EAAE;EAAQ,aAAa;EAAG,gBAAgB;EAAQ,gBAAgB;CAAK;AAClF;AACA,SAAS,oBAAoB,OAAO;CAChC,IAAI,CAAC,SAAS,MAAM,WAAW,GAC3B,OAAO;CACX,OAAO,mBAAmB,kBAAkB,KAAK,CAAC;AACtD;;AC9EA,SAAgB,wBAAwB,UAA0D;CAChG,OAAO,SACJ,aAAa,CAAC,CACd,QAAQ,UAAU,MAAM,aAAa,cAAc,MAAM,QAAQ,YAAY;AAClF;;AAGA,SAAgB,eACd,QACA,cACkB;CAClB,OAAO,OAAO,SAAS,UAAU;EAC/B,MAAM,WAAW,aAAa,MAC3B,UAAU,MAAM,eAAe,MAAM,YAAY,MAAM,OAAO,MAAM,EACvE;EACA,MAAM,OAAuB;GAC3B,YAAY,MAAM;GAClB,SAAS,MAAM;GACf,SAAS;GACT,iBAAiB;GACjB,cAAc;IACZ,OAAO,MAAM;IACb,QAAQ,CAAC,MAAM;IACf,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,SAAS,MAAM;GAC5D;GACA,OAAO,EAAE,SAAS,MAAM,cAAc;EACxC;EACA,OAAO,CACL,MACA,GAAG,2BAA2B,KAAK,CAAC,CAAC,KAAK,aAAa;GACrD,GAAG;GACH;GACA,kBAAkB;EACpB,EAAE,CACJ;CACF,CAAC;AACH;AAEA,SAAgB,eAAe,QAA+C;CAC5E,OAAO,OAAO,KAAK,WAAW;EAC5B,YAAY,MAAM;EAClB,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,UAAU,2BAA2B,KAAK;CAC5C,EAAE;AACJ;AAEA,SAAgB,eAAe,QAAgD;CAC7E,OAAO,OAAO,KAAK,WAAW;EAC5B,KAAK;GAAE,YAAY,MAAM;GAAU,IAAI,MAAM;EAAG;EAChD,WAAW,MAAM,KAAK;EACtB,YAAY,MAAM,KAAK;EACvB,WAAW,MAAM;EACjB,eAAe,MAAM;EACrB,gBAAgB,2BAA2B,KAAK;CAClD,EAAE;AACJ;AAEA,SAAgB,cAAc,UAA8B,OAAkC;CAC5F,OAAO;EACL,OAAO,MAAM,SAAS;EACtB,eAAe,sBAAsB,QAAQ,CAAC,CAAC;EAC/C,OAAO,SAAS,MACb,YACC,OAAO,QAAQ,YAAY,YAC3B,QAAQ,QAAQ,MAAM,SAAS,KAAK,SAAS,OAAO,CACxD,IACI,CAAC,QAAQ,OAAO,IAChB,CAAC,MAAM;CACb;AACF;AAEA,SAAgB,iBACd,OACA,KACA,WACoB;CACpB,IAAI,IAAI,YAAY,KAAA,GAAW,OAAO,mBAAmB,OAAO,SAAS;CACzE,MAAM,QAAQ,2BAA2B,KAAK,CAAC,CAAC,MAAM,cAAc,cAAc,IAAI,OAAO;CAC7F,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,mEAAmE;CACrF,OAAO;AACT;;AC7CA,SAAgB,SAAS,UAAuD;CAC9E,OAAO,wBAAwB,QAAQ;AACzC;;AAQA,eAAsB,iBACpB,IACA,SACA,KACA,SACA,aACA,UAAU,OACV,cACA,UACA;CACA,MAAM,UAAU,MAAM,QAAQ,SAAS;CACvC,MAAM,eAAe,MAAM,QAAQ,aAAa;CAChD,MAAM,SAAS,SAAS,IAAI,aAAa;CACzC,MAAM,QAAQ,eAAe,QAAQ,KAAK;CAC1C,MAAM,WAAW,UAAU;EACzB;EACA,QAAQ,QAAQ;EAChB;EACA,QAAQ,IAAI,eAAe,UAAU;EACrC,eAAe,cAAc,IAAI,eAAe,UAAU,CAAC;EAC3D,QACE,QAAQ,WAAW,KAAA,IACf,KAAA,IACA;GACE,OAAO;IAAE,YAAY,QAAQ,OAAO,MAAM;IAAU,IAAI,QAAQ,OAAO,MAAM;GAAG;GAChF,SAAS,QAAQ,OAAO;EAC1B;EACN,OAAO,QAAQ;CACjB,CAAC;CACD,MAAM,OACJ,iBAAiB,KAAA,IACb,WACA;EAAE,GAAG;EAAU,MAAM,aAAa;EAAM,OAAO;CAAa;CAClE,MAAM,WAAW,QAAQ,UAAU;CACnC,MAAM,QAAQ;EACZ,MAAM,KAAK;EACX,QAAQ,KAAK;EACb,UAAU;EACV,UACE,aAAa,KAAA,IACT,KAAA,IACA;GACE,YAAY,SAAS;GACrB,IAAI,SAAS;GACb,GAAI,QAAQ,UAAU,kBAAkB,KAAA,IACpC,CAAC,IACD,EAAE,SAAS,QAAQ,SAAS,cAAc;EAChD;EACN,WAAW,eAAe,QAAQ,YAAY;EAC9C,QAAQ,cAAc,QAAQ,UAAU,YAAY,CAAC;CACvD;CACA,MAAM,UACJ,QACA,aACsB,eAAe;EAAE,GAAG;EAAO;EAAQ;EAAU,SAAS,KAAK;CAAQ,CAAC;;;;;CAK5F,MAAM,sBACJ,QAAQ,MAAM,KAAK,KAAK,CAAC,MAAM,QAC7B,MAAM,UAAU,MACb,UACC,MAAM,eAAe,IAAI,cACzB,MAAM,YAAY,IAAI,MACtB,MAAM,YAAY,IAAI,WACtB,mBAAmB,OAAO,MAAM,MAAM,CAAC,CAAC,UAC5C,CACF;CACF,MAAM,SAAS,OAAO,eAAe,UAA8B;EACjE,MAAM,MAAM,QAAQ,OAAO,MAAM;EACjC,MAAM,kBAAkB;GAAE,UAAU,OAAO,CAAC,GAAG,CAAC,CAAC;GAAG,KAAK;EAAI;EAC7D,IAAI,gBAAgB,KAAK,QAAQ,OAAO,SAAS;EACjD,MAAM,aAAa,oBAAoB,SAAS,KAAK,IAAI;EACzD,MAAM,OAAO,MAAM,aAAa,QAAQ,UAAU,UAAU;EAG5D,MAAM,WAAW,OAAO,YACtB,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS;GAC9C,MAAM,QAAQ,KAAK,SAAS,IAAI,EAAE;GAClC,OAAO,UAAU,KAAA,KAAa,QAAQ;EACxC,CAAC,CACH;EACA,IAAI;GACF,MAAM,UAAU,aAAqC;IACnD,MAAM,EAAE,QAAQ,YAAY,iBAAiB,UAAU,UAAU;IACjE,MAAM,WAAW,OAAO,QAAQ,QAAQ;IACxC,kBACE,UACA,SACA,CAAC,WAAW,SAAS,SAAS,UAAU,SAAS,QAAQ,KAAA,CAC3D;IAiBA,OAAO;KAAE;KAAU,KADN,SAfG,WAAW,SAAS,QAAQ;MAC1C,MAAM,QAAQ,MAAM,UAAU,MAC3B,cACC,UAAU,eAAe,IAAI,cAC7B,UAAU,YAAY,IAAI,MAC1B,UAAU,YAAY,IAAI,OAC9B;MACA,IAAI,UAAU,KAAA,KAAa,CAAC,mBAAmB,OAAO,MAAM,MAAM,CAAC,CAAC,YAAY,OAAO,CAAC;MAMxF,OAAO,CAAC,iBALM,cAAc;OAC1B,YAAY,IAAI;OAChB,SAAS,IAAI;OACb,WAAW,IAAI;MACjB,CAAC,CAAC,CAAC,KAAK,QAAQ,SAAS,UAAU,GAAG,CACb,GAAO,KAAK,SAAS,mBAAmB,GAAG,MAAM,MAAM,GAAG,CAAC;KACtF,CACsB,GAAS,KAAK,CACT,CAAC,EAAE,SAAS,MAAM;IAAQ;GACvD;GACA,IAAI,SAAS;IAEX,MAAM,WAAW,IAAI,uBAAuB,QAAQ,OAAO,KAAK;IAChE,SAAS,QAAQ,mBAAmB,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC;IACrE,OAAO,OAAO,QAAQ;GACxB;GACA,OAAO,MAAM,WAAW,QAAQ,QAAQ,MAAM;EAChD,SAAS,OAAO;GACd,WAAW;GACX,YAAY,UAAU,KAAK;GAC3B,OAAO,SAAS;EAClB;CACF;CACA,OAAO;EAAE;EAAQ;EAAM;EAAQ;EAAO;CAAc;AACtD;AAYA,SAAgB,cACd,SACA,aACA,SACA,YAWA,UACA;CACA,OAAO,YAAY,KAAK,QAAQ;EAC9B,UAAU;EACV;EACA,MAAM,YAAY,OAAO,SAAS,SAAS;EAC3C,MAAM,MAAM,SAA4B,KAAmB;GACzD,MAAM,SAAS,WAAW,GAAG;GAC7B,MAAM,WAAW,MAAM,iBACrB,IACA,SACA,KACA,SACA,aACA,OACA,QAAQ,WAAW,SAAS,SAAS,UAAU,IAAI,KAAA,SAC7C,QAAQ,KAAK,EAAE,MAAM,WAAW,CAAC,CACzC,CAAC,CAAC,OAAO,UAAmB;IAC1B,QAAQ,KAAK,EAAE,MAAM,WAAW,CAAC;IACjC,MAAM;GACR,CAAC;GACD,IAAI,OAAO,SAAS;GACpB,IAAI,aACD,KAAK,OAAO,QAAQ,MAAM,KAAK,QAAQ,WAAW,UAC/C;IACE,UAAU;KAAE,MAAM;KAAQ,QAAQ;KAAe,QAAQ;IAAqB;IAC9E,KAAK,QAAQ,OAAO,MAAM,IAAI;GAChC,IACA,MAAM,SAAS,OAAO;GAC5B,IAAI,UAAU,SAAS,SAAS,UAAU,UAAU,SAAS,WAAW,iBAAiB;IACvF,QAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC;IAC9B,MAAM,IAAI,MAAM,gEAAgE;GAClF;GACA,KACE,IAAI,UAAU,GACd,UAAU,SAAS,SAAS,UAAU,YAAY,KAAA,KAAa,UAAU,GACzE,WAAW,GAEX,IAAI;IACF,MAAM,UAAU,MAAM,QAAQ,QAAQ,MAAM,WAAW,SAAS,QAAQ,WAAW,GAAG;IACtF,IAAI,YAAY,KAAA,GAAW;IAC3B,OAAO;IACP,YAAY,MAAM,SAAS,OAAO;GACpC,SAAS,OAAO;IACd,IAAI,iBAAiB,eAAe,MAAM;IAC1C,QAAQ,KAAK,EAAE,MAAM,WAAW,CAAC;IACjC,YAAY,WAAW,KAAK;IAC5B,YAAY,MAAM,SAAS,OAAO,IAAI;IACtC;GACF;GAEF,MAAM,EAAE,aAAa;GACrB,IAAI;GACJ,IAAI,SAAS,SAAS,SAAS;IAC7B,MAAM,WAAW,SAAS,cAAc;IACxC,IAAI,aAAa,KAAA,GAAW;KAC1B,QAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC;KAC9B,MAAM,IAAI,MACR,2BAA2B,SAAS,OAAO,iCAC7C;IACF;IACA,cAAc;GAChB,OAAO;IACL,IAAI,SAAS,SAAS,SAAS;KAG7B,MAAM,aACJ,SAAS,WAAW,4BACpB,SAAS,QAAQ,SAAS,sBAAsB,MAAM;KACxD,MAAM,IAAI,MACR,aACI,yBAAyB,SAAS,OAAO,qEACzC,yBAAyB,SAAS,OAAO,4BAC/C;IACF;IACA,cAAc,SAAS;GACzB;GACA,MAAM,WAAW,SAAS,OAAO,MAC9B,UAAU,MAAM,aAAa,YAAY,cAAc,MAAM,OAAO,YAAY,EACnF;GACA,IAAI,aAAa,KAAA,GAAW;IAC1B,QAAQ,KAAK,EAAE,MAAM,WAAW,CAAC;IACjC,MAAM,IAAI,MAAM,wCAAwC;GAC1D;GACA,QAAQ,WAAW,UAAU;IAC3B,MAAM,KAAK;IACX,OAAO,QAAQ,WAAW;IAC1B,OAAO,KAAK;GACd,CAAC;GACD,aAAa,UAAU;IACrB;IACA,MAAM,KAAK,OAAO;IAClB,MAAM,KAAK;IACX,SAAS,IAAI,eAAe,eAAe;IAC3C,OAAO,QAAQ,WAAW;IAC1B,OAAO,KAAK;GACd,CAAC;GACD,OAAO;IACL,OAAO;IACP,eAAe,iBAAiB,UAAU,aAAa,QAAQ,aAAa;IAC5E,OAAO,KAAK,UAAU,SAAS,QAAQ,QAAQ,QAAQ,KAAK;GAC9D;EACF;CACF,EAAE;AACJ;;ACtSA,SAAS,MAAM,MAAc,UAAmC,CAAC,GAAe;CAC9E,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ;EAAK,CAAC;EAAG;CAAQ;AACtD;AAEA,SAAS,SAAS,MAA0B;CAC1C,OAAO;EAAE,GAAG,MAAM,IAAI;EAAG,SAAS;CAAK;AACzC;AAEA,SAASC,QAAM,OAAgB,KAAsB;CACnD,OAAO,OAAO,UAAU,YAAY,UAAU,OAC1C,OAAO,yBAAyB,OAAO,GAAG,CAAC,EAAE,QAC7C,KAAA;AACN;;AAGA,SAAgB,gBAAgB,OAAoD;CAClF,OAAO,OAAO,aAAa,aAAa,YAAY,MAAM,OAAO,OAAO,MAAM,EAAE,IAAI,KAAA;AACtF;;;;;AAMA,SAAS,QACP,UACA,OACA,oBAC2D;CAC3D,MAAM,KAAK,gBAAgB,KAAK;CAChC,IAAI,OAAO,KAAA,GACT,OAAO,EAAE,SAAS,iEAAiE;CACrF,IAAI,SAAS,QAAQ,MACnB,OAAO,EAAE,SAAS,mBAAmB,SAAS,IAAI,WAAW,GAAG,SAAS,IAAI,GAAG,GAAG;CACrF,IAAI,OAAO,UAAU,CAAC,oBAAoB,OAAO,EAAE,SAAS,4BAA4B,GAAG,GAAG;CAC9F,OAAO,EAAE,GAAG;AACd;AAEA,SAAgB,SAAS,UAAqC;CAC5D,OAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EACF,YAAY;GACV,MAAM;GACN,YAAY,EACV,MAAM;IACJ,MAAM;IACN,MAAM;KAAC;KAAS;KAAY;IAAU;IACtC,aAAa;GACf,EACF;GACA,UAAU,CAAC,MAAM;GACjB,sBAAsB;EACxB;EACA,MAAM,QACJ,aACA,QACA,SACA,WACA,KACqB;GACrB,MAAM,YAAYA,QAAM,QAAQ,MAAM;GACtC,IAAI,OAAO,cAAc,YAAY,CAAC,WAAW,SAAS,GACxD,OAAO,SAAS,oEAAoE;GAEtF,MAAM,QAAQ,QAAQ,MADA,SAAS,GACA,IAAI,OAAO,KAAK;GAC/C,IAAI,aAAa,OAAO,OAAO,MAAM,GAAG,MAAM,QAAQ,oCAAoC;GAE1F,OAAO,MAAM,0BAA0B,UAAU,0CAA0C,EACzF,MAAM,UACR,CAAC;EACH;CACF;AACF;AAEA,SAAgB,eACd,UACA,oBACA;CACA,OAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EACF,YAAY;GACV,MAAM;GACN,YAAY;IACV,QAAQ;KACN,MAAM;KACN,WAAW;KACX,aAAa;IACf;IACA,UAAU;KACR,MAAM;KACN,WAAW;KACX,aAAa;IACf;GACF;GACA,UAAU,CAAC,UAAU,UAAU;GAC/B,sBAAsB;EACxB;EACA,MAAM,QACJ,aACA,QACA,SACA,WACA,KACqB;GACrB,MAAM,UAAU,uBAAuB,MAAM;GAC7C,IAAI,YAAY,KAAA,GACd,OAAO,SACL,iFACF;GAEF,MAAM,QAAQ,QAAQ,MADA,SAAS,GACA,IAAI,OAAO,MAAM,mBAAmB,CAAC;GACpE,IAAI,aAAa,OACf,OAAO,MACL,GAAG,MAAM,QAAQ,yEACnB;GACF,MAAM,QAAQ,YAAY,IAAI,eAAe,UAAU,GAAG,MAAM,EAAE;GAClE,MAAM,OAAO,OAAO,SAAS,MAAM,OAAO,SAAS,aAAa,MAAM;GACtE,MAAM,OAAO,OAAO,eAAe;GACnC,MAAM,OAAO,SAAS,IAAI;GAC1B,MAAM,UAAU;IAAE,QAAQ,QAAQ;IAAQ,UAAU,QAAQ;GAAS;GACrE,IAAI,SAAS,KAAA,GACX,OAAO,MACL,iBAAiB,KAAK,8EACtB,OACF;GACF,IAAI,QAAA,GACF,OAAO,MACL,4CAA4C,OAAA,CAA+B,EAAE,gBAC7E,OACF;GACF,OAAO,MACL,0EAA0E,KAAK,IAAI,OAAO,IAAI,EAAE,MAAM,OAAA,CAA+B,EAAE,sBACvI,OACF;EACF;CACF;AACF;;;;;;;ACjIA,SAAgB,aACd,IACA,SACA,SACA,UACuE;CACvE,OAAO,OAAO,OAAO,QAAQ;EAC3B,IAAI,MAAM,WAAW,aAAa,OAAO,EAAE,QAAQ,WAAW;EAC9D,IAAI;EACJ,IAAI;GACF,MAAM,QAAQ,IAAI;GAClB,IAAI,UAAU,KAAA,KAAa,gBAAgB,KAAK,MAAM,KAAA,GAAW,OAAO,EAAE,QAAQ,WAAW;GAC7F,MAAM,WAAW,WAAW,GAAG;GAC/B,UAAU,UAAU;IAClB,IAAI;KACF,WAAW,KAAK;IAClB,SAAS,OAAO;KACd,YAAY,UAAU,KAAK;IAC7B;GACF;GAEA,IAAI,cAAc,QAAO,MADF,QAAQ,SAAS,EACf,CAAS,MAAM,IAAI,eAAe,UAAU,CAAC,MAAM,WAC1E,OAAO,EAAE,QAAQ,WAAW;GAC9B,IAAI,IAAI,eAAe,2BAA2B,KAAA,GAAW,OAAO,EAAE,QAAQ,WAAW;GACzF,MAAM,UAAU,aAAa,IAAI,eAAe,uBAAuB,CAAC,CAAC,QAAQ;GACjF,MAAM,SAAS,EAAE,UAAU,MAAM;GACjC,MAAM,WAAW,MAAM,iBACrB,QACA;IACE;IACA,QAAQ;IACR,eAAe;IACf,UAAU,CACR,GAAG,SACH;KACE,MAAM;KACN,WAAW,QAAQ,OAAO,MAAM;KAChC,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,MAAM;KAAK,GAAG,GAAI,MAAM,UAAU,CAAC,CAAE;IACvE,CACF;GACF,GACA,KACA,eACM,GAAG,eAAe,GACxB,MACA,KAAA,SACM;IACJ,OAAO,WAAW;GACpB,CACF;GACA,MAAM,SAAS,MAAM,SAAS,OAAO;GACrC,IAAI,OAAO,UAAU,OAAO,EAAE,MAAM,WAAW,CAAC;QAC3C,OAAO;IAAE,MAAM;IAAa,MAAM,SAAS,KAAK;GAAK,CAAC;GAC3D,MAAM,WAAW,QAAQ,OAAO,UAAU,SAAS;GACnD,MAAM,UAAU,IAAI,eAAe,eAAe;GAClD,IAAI,YAAY,KAAA,GAAW;IACzB,MAAM,UAAU,MAAM,cAAc,QAAQ,UAAU;KACpD,IAAI,QAAQ,OAAO,MAAM;KACzB,WAAW;KACX,MAAM,SAAS,KAAK;KACpB;IACF,CAAC;IACD,MAAM,EAAE,cAAc,MAAM,gBAAgB,QAAQ,WAAW;IAC/D,IAAI,gBAAgB,WAAW,UAAU,QAAQ,IAAI,GAAG;KAMtD,WAAW,IAAI;MAJb,SAAS;MACT,MAAM,aAAa,UAAU,SAAS,KAAK,IAAI;MAC/C,WAAW,QAAQ;KAEN,CAAI;KACnB,QAAQ,OAAO;IACjB;GACF;EACF,SAAS,OAAO;GACd,SAAS,EAAE,MAAM,WAAW,CAAC;GAC7B,YAAY,WAAW,KAAK;EAC9B;EACA,OAAO,EAAE,QAAQ,WAAW;CAC9B;AACF;;ACnGA,SAAS,MAAM,OAAgB,KAAsB;CACnD,OAAO,OAAO,UAAU,YAAY,UAAU,OAC1C,OAAO,yBAAyB,OAAO,GAAG,CAAC,EAAE,QAC7C,KAAA;AACN;;AAGA,SAAgB,cAAc,KAAmB,OAAwC;CACvF,MAAM,OAAO,IAAI,eACd,UAAU,CAAC,CACX,UACE,UACC,MAAM,SAAS,YACf,MAAM,eAAA,qBACN,MAAM,MAAM,MAAM,OAAO,MAAM,KACnC,CAAC,EAAE;CACL,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,MAAM,QAAQ,eAAe,MAAM,MAAM,OAAO,CAAC;CACjD,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,MAAM,gCAAgC;CACzE,MAAM,QAAQ,MAAM,MAAM,OAAO;CACjC,IAAI,UAAU,KAAA,GAAW,OAAO;EAAE;EAAO;CAAM;CAC/C,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,IAAI,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,8CAA8C;CAC5F,MAAM,SAAS,MAAM,OAAO,QAAQ;CACpC,IAAI,WAAW,KAAA,GAAW,OAAO;EAAE;EAAO;EAAO,OAAO,EAAE,KAAK;CAAE;CACjE,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,MAAM,IAAI,MAAM,gDAAgD;CAY5F,OAAO;EAAE;EAAO;EAAO,OAAO;GAAE;GAAM,QAXP,OAAO,KAAK,UAAmB;IAC5D,MAAM,OAAO,MAAM,OAAO,MAAM;IAChC,MAAM,WAAW,MAAM,OAAO,UAAU;IACxC,IACE,MAAM,OAAO,MAAM,MAAM,WACzB,OAAO,SAAS,YAChB,OAAO,aAAa,UAEpB,MAAM,IAAI,MAAM,sDAAsD;IACxE,OAAO;KAAE,MAAM;KAAS;KAAM;IAAS;GACzC,CACmD;EAAE;CAAE;AACzD;AAEA,SAAgB,YAAY,KAAyB;CACnD,IAAI,IAAI,UAAU,YAAY,KAAA,CAAS;CACvC,IAAI,IAAI,UAAU,YAAY,KAAA,CAAS;CACvC,IAAI,IAAI,kBAAkB;AAC5B;AAEA,SAAgB,WAAW,KAAmB,QAAsB;CAClE,IAAI,CAAC,IAAI,OAAO;CAChB,MAAM,OAAO,IAAI,KAAK,OAAO,GAAG,CAAC,CAAC,mBAAmB,CAAC,GAAG;EAAE,MAAM;EAAW,QAAQ;CAAU,CAAC;CAC/F,MAAM,YAAY,OAAO,SAAS;CAClC,IAAI,IAAI,UACN,YACA,GAAG,OAAO,KAAK,YAAY,YAAY,qBAAqB,WAAW,QACzE;CACA,IAAI,IAAI,UAAU,YAAY;EAC5B,wBAAwB,OAAO,KAAK;EACpC,YACI,2DACA,WAAW,KAAK;EACpB;CACF,CAAC;AACH;;;ACNA,SAAgB,gBACd,IACA,SACA,UAAuB,EAAE,MAAM,KAAA,EAAU,GACxB;CACjB,IAAI;CACJ,IAAI;CACJ,IAAI,aAAa;CACjB,IAAI;CACJ,MAAM,aAAa;EACjB,cAAc;EACd,eAAe,KAAA;EACf,QAAQ,MAAM;EACd,SAAS,KAAA;EACT,SAAS;EACT,SAAS,KAAA;CACX;;CAEA,MAAM,SAAS,OAAO,QAAwC;EAC5D,KAAK;EACL,YAAM,GAAG;EACT,MAAM,UAAU,IAAI,eAAe,eAAe;EAClD,OACE,YAAY,KAAA,KACZ,IAAI,eAAe,UAAU,CAAC,CAAC,MAAM,UAAU,MAAM,eAAA,iBAAyB,KAC9E,WAAW,QAAQ,QAAQ,MAAM,OAAO;CAE5C;CACA,MAAM,aAAa,OAAO,OAAe,SAA2C;EAClF,IAAI;GACF,MAAM,EAAE,cAAc,MAAM,gBAAgB,QAAQ,WAAW;GAC/D,IAAI,UAAU,cAAc,cAAc,SAAS;GACnD,WAAW,IAAI;IAAE,SAAS;IAAG,MAAM,GAAG,KAAK;GAAiC,CAAC;EAC/E,SAAS,OAAO;GACd,YAAY,SAAS,KAAK;EAC5B;CACF;CACA,MAAM,OAAO,OACX,KACA,QACA,OACA,MAAM,QAAQ,QAAQ,MAAM,GAC5B,SAAS,UACY;EACrB,MAAM,QAAQ;EACd,IAAI,CAAE,MAAM,UAAU,QAAQ,QAAQ,MAAM,QAAQ,KAAK,MAAM,GAAI;GACjE,YAAM,GAAG;GACT,OAAO;EACT;EAEA,IAAI,UAAU,YAAY,OAAO;EACjC,YAAM,GAAG;EACT,IAAI,MAAM,UAAU,KAAA,GAAW;GAC7B,eAAe;IAAE,GAAG,MAAM;IAAO,OAAO,OAAO;IAAO,WAAW,OAAO;GAAM;GAC9E,MAAM,UAAU,CACd;IAAE,MAAM;IAAiB,MAAM,MAAM,MAAM;GAAK,GAChD,GAAI,MAAM,MAAM,UAAU,CAAC,CAC7B;GACA,GAAG,gBAAgB,SAAS,EAAE,uBAAuB,MAAM,CAAC;EAC9D,OACE,GAAG,YACD;GACE,YAAY;GACZ,SAAS;GACT,SAAS;GACT,SAAS;IACP,MAAM,MAAM,MAAM;IAClB,OAAO,OAAO;IACd,MAAM,OAAO;IACb,aAAa,MAAM,MAAM;IACzB,UAAU,MAAM,MAAM;IACtB,OAAO,OAAO;IACd,WAAW,OAAO;IAClB,OAAO,CAAC;GACV;EACF,GACA,EAAE,aAAa,KAAK,CACtB;EAEF,MAAM,WAAW,OAAO,OAAO,IAAI;EACnC,OAAO;CACT;CACA,MAAM,OAAO,KAAmB,QAAgB,UAAmB;EACjE,WAAK,KAAK,MAAM;EAChB,IAAI,OAAO,SAAS,WAAW;EAC/B,MAAM,QAAQ;EACd,SAAS,QAAQ,QAAQ,YACjB;GACJ,IAAI,UAAU,YAAY;GAC1B,IAAI,QAAQ,QAAQ,MAAM,IAAI,OAAO,KAAK;IACxC,IAAI,KAAK,QAAQ,KAAK;IACtB;GACF;GACA,KAAU,KAAK,QAAQ,KAAK,CAAC,CAAC,OAAO,UAAmB;IACtD,YAAY,WAAW,KAAK;GAC9B,CAAC;EACH,GACA,KAAK,IAAI,GAAG,KAAK,IAAI,MAAW,OAAO,MAAM,QAAQ,QAAQ,MAAM,CAAC,CAAC,CACvE;CACF;CACA,MAAM,UAAU,OAAO,KAAmB,OAAkB,KAAa,UAAkB;EACzF,MAAM,UAAU,IAAI,eAAe,eAAe;EAClD,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,MAAM,qCAAqC;EAChF,MAAM,SAAiB;GACrB;GACA,OAAO,QAAQ,MAAM;GACrB,MAAM,MAAM;GACZ;GACA,OAAO,MAAM,SAAS;GACtB,SAAS;EACX;EACA,MAAM,QAAiB;GAAE,OAAO,OAAO;GAAO;GAAO,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EAAG;EAE/F,GAAG,YAAY,YAAY,KAAK;EAChC,MAAM,SAAS,QAAQ,QAAQ,MAAM,MAAM;EAC3C,WAAK,KAAK,MAAM;EAEhB,IAAI,OAAO,SAAS,WAClB,IAAI;GACF,WAAW,IAAI;IACb,SAAS;IACT,MAAM,iBAAiB,OAAO,OAAO,KAAK,EAAE;GAC9C,CAAC;EACH,SAAS,OAAO;GACd,YAAY,WAAW,KAAK;EAC9B;EAEF,OAAO;GAAE;GAAQ;EAAM;CACzB;CACA,MAAM,OAAO,OAAO,KAAmB,KAAa,WAAyB;EAC3E,MAAM,aAAa,IAAI,gBAAgB;EACvC,SAAS;EACT,MAAM,WACJ,WAAW,KAAA,IAAY,WAAW,SAAS,YAAY,IAAI,CAAC,QAAQ,WAAW,MAAM,CAAC;EACxF,IAAI;GACF,MAAM,UAAU,QAAQ,SAAS,KAAK,WAAW,cAAc;IAC7D,IAAI,CAAC,IAAI,OAAO;IAChB,MAAM,UAAU,KAAK,KAAK,YAAY,GAAK;IAE3C,MAAM,OAAO,yBAAyB,GADjB,OAAO,KAAK,MAAM,UAAU,EAAE,CAAC,EAAE,GAAG,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,IAC7C;IAChD,IAAI,IAAI,UAAU,YAAY,IAAI;IAClC,IAAI,IAAI,kBAAkB,IAAI;GAChC,CAAC;EACH,UAAU;GACR,IAAI,WAAW,YAAY,SAAS,KAAA;GACpC,YAAM,GAAG;EACX;CACF;;CAGA,MAAM,WAAW,OACf,SACA,MACA,UACA,SACkB;EAClB,IAAI;GACF,MAAM,UAAU,MAAM,cAAc,QAAQ,UAAU;IACpD,IAAI,QAAQ,QAAQ,MAAM;IAC1B,WAAW;IACX,QAAQ;IACR;IACA;GACF,CAAC;GACD,MAAM,EAAE,cAAc,MAAM,gBAAgB,QAAQ,WAAW;GAC/D,IAAI,CAAC,gBAAgB,WAAW,UAAU,QAAQ,IAAI,GAAG;GAMzD,WAAW,IAAI;IAJb,SAAS;IACT,MAAM,aAAa,UAAU,IAAI;IACjC,WAAW,QAAQ;GAEN,CAAI;GACnB,QAAQ,OAAO;EACjB,SAAS,OAAO;GACd,YAAY,YAAY,KAAK;EAC/B;CACF;CAEA,MAAM,QAAQ,OAAO,OAAmB,QAAmD;EACzF,IAAI,MAAM,WAAW,aAAa,OAAO,EAAE,QAAQ,WAAW;EAC9D,IAAI,SAAS;EACb,MAAM,QAAQ,aAAa;EAC3B,IAAI;GACF,MAAM,OAAO,GAAG;GAChB,IAAI,UAAU,YAAY,OAAO,EAAE,QAAQ,UAAU;GACrD,MAAM,QAAQ,IAAI;GAClB,IAAI,UAAU,KAAA,GAAW,OAAO,EAAE,QAAQ,WAAW;GACrD,MAAM,KAAK,gBAAgB,KAAK;GAEhC,IAAI,OAAO,KAAA,KAAa,MAAM,sBAAsB,KAAA,GAAW,OAAO,EAAE,QAAQ,WAAW;GAC3F,MAAM,WAAW,MAAM,iBACrB,IACA;IACE;IACA,QAAQ;IACR,eAAe;IACf,UAAU,CACR;KACE,MAAM;KACN,WAAW,QAAQ,QAAQ,MAAM;KACjC,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,MAAM;KAAK,GAAG,GAAI,MAAM,UAAU,CAAC,CAAE;IACvE,CACF;GACF,GACA,KACA,eACM,GAAG,eAAe,GACxB,IACF;GACA,MAAM,YAAY,MAAM,SAAS,OAAO;GACxC,IAAI,UAAU,YAAY,OAAO,EAAE,QAAQ,UAAU;GACrD,IACE,UAAU,SAAS,SAAS,UAC5B,UAAU,SAAS,WAAW,mBAC9B,UAAU,MAAM,QAAQ,QAAQ,MAAM,KAAA,MAEtC,OAAO,EAAE,QAAQ,WAAW;GAG9B,IACE,CAAC,IAAI,eACF,UAAU,CAAC,CACX,MACE,UACC,MAAM,SAAS,cACd,MAAM,SAAS,SAAS,UAAU,MAAM,SAAS,SAAS,YAC/D,GAEF,OAAO,EAAE,QAAQ,WAAW;GAC9B,MAAM,QAAQ,UAAU,SAAS,KAAK,MAAM,QAAQ,KAAK;GACzD,MAAM,EAAE,QAAQ,UAAU,MAAM,QAAQ,KAAK,OAAO,UAAU,KAAK;IACjE,MAAM,MAAM;IACZ,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;GAC/D,CAAC;GACD,MAAM,SAAS,OAAO,SAAS,SAAS,KAAK,MAAM,UAAU,UAAU,MAAM,IAAI;GACjF,SAAS;GACT,IAAI,UAAU,YAAY,OAAO,EAAE,QAAQ,UAAU;GACrD,IAAI,IAAI,SAAS,OAAO,IAAI,KAAK,QAAQ,KAAK;QACzC;IACH,MAAM,KAAK,KAAK,OAAO,KAAK,IAAI,MAAM;IACtC,MAAM,KAAK,KAAK,QAAQ,KAAK;GAC/B;GACA,OAAO,EAAE,QAAQ,UAAU;EAC7B,SAAS,OAAO;GACd,IAAI,iBAAiB,eACf;QAAA,UAAU,YAAY,MAAM,OAAO,GAAG;GAAA,OACrC,YAAY,WAAW,KAAK;GACnC,OAAO,EACL,QACE,UAAU,iBAAiB,iBAAiB,UAAU,aAAa,YAAY,WACnF;EACF;CACF;CACA,MAAM,cAA8C,OAAO,OAAO,QAAQ;EACxE,IAAI,gBAAgB,KAAK,MAAM,KAAA,GAAW;EAC1C,IAAI;GACF,MAAM,OAAO,GAAG;EAClB,SAAS,OAAO;GACd,YAAY,WAAW,KAAK;EAC9B;CACF;CACA,MAAM,eAAgD,OAAO,QAAQ;EACnE,KAAK;EACL,IAAI,IAAI,SAAS,SAAS,gBAAgB,IAAI,KAAK,MAAM,KAAA,GAAW;EACpE,IAAI;GACF,MAAM,UAAU,IAAI,eAAe,eAAe;GAClD,IAAI,YAAY,KAAA,GAAW;GAC3B,MAAM,SAAS,MAAM,SAAS,QAAQ,QAAQ,MAAM,OAAO;GAC3D,IAAI,WAAW,KAAA,GAAW;GAC1B,MAAM,QAAQC,cAAQ,KAAK,OAAO,KAAK;GACvC,IAAI,UAAU,KAAA,GAAW;GACzB,IAAI,OAAO,OAAO,QAAQ,QAAQ,MAAM,KAAK,OAAO,QAAQ,WAAW;IACrE,IAAI,MAAM,IAAI,IAAI,QAAQ,eAAe,6BAA6B,GAGpE,MAAM,KAAK,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI;SAC1C,MAAM,OAAO,GAAG;GACzB,OAAO,IAAI,KAAK,QAAQ,KAAK;EAC/B,SAAS,OAAO;GACd,YAAY,WAAW,KAAK;EAC9B;CACF;CACA,MAAM,SAAoC,OAAO,QAAQ;EACvD,MAAM,UAAU,IAAI,eAAe,eAAe;EAClD,MAAM,SAAS,YAAY,KAAA,IAAY,KAAA,IAAY,MAAM,SAAS,QAAQ,QAAQ,MAAM,OAAO;EAC/F,MAAM,QAAQ,WAAW,KAAA,IAAY,KAAA,IAAYA,cAAQ,KAAK,OAAO,KAAK;EAC1E,IAAI,WAAW,KAAA,KAAa,UAAU,KAAA,GAAW,OAAO;EACxD,KAAK;EAGL,OAAQ,MAAM,KAAK,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI,IAAK,YAAY;CAC1E;CACA,MAAM,cAAc,OAClB,MACA,QACkB;EAClB,IAAI;GACF,MAAM,UAAU,IAAI,eAAe,eAAe;GAClD,IAAI,YAAY,KAAA,GAAW;GAC3B,MAAM,SAAS,MAAM,SAAS,QAAQ,QAAQ,MAAM,OAAO;GAC3D,IAAI,WAAW,KAAA,GAAW;GAG1B,IAFcA,cAAQ,KAAK,OAAO,KAE1B,CAAC,EAAE,MAAM,SAAS,MAAM;GAChC,KAAK;GACL,YAAM,GAAG;GACT,MAAM,WAAW,QAAQ,QAAQ,MAAM,OAAO;EAChD,SAAS,OAAO;GACd,YAAY,WAAW,KAAK;EAC9B;CACF;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,QAAQ,OAAO,QAAU,MAAM,OAAO,GAAG,IAAK,cAAc;EAC5D,UAAU;EACV,MAAM,QAAQ,UAAU,KAAK;GAC3B,MAAM,KAAK,gBAAgB,IAAI,KAAK;GACpC,MAAM,QAAQ,IAAI,cAAc,aAAa,CAAC,CAAC;GAC/C,IAAI,OAAO,KAAA,KAAa,UAAU,KAAA,GAAW,OAAO;GACpD,IAAI,SAAS;GACb,MAAM,QAAQ;GACd,IAAI;IACF,MAAM,QAAmB;KACvB,SAAS;KACT,MAAM,SAAS;KACf,MAAM,QAAQ,MAAM;KACpB,MAAM,SAAS;KACf,aAAa,SAAS;KACtB,UAAU,SAAS;KACnB,OAAO,SAAS,SAAS;KACzB,GAAI,SAAS,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,SAAS,UAAU;KAC5E,OAAO,SAAS;IAClB;IACA,MAAM,WAAW,MAAM,iBACrB,IACA;KAAE;KAAO,QAAQ;KAAQ,eAAe;KAAO,UAAU,CAAC;IAAE,GAC5D,KACA,eACM,GAAG,eAAe,GACxB,MACA,KACF;IACA,MAAM,YAAY,MAAM,SAAS,OAAO;IACxC,IAAI,UAAU,YAAY,OAAO;IACjC,IACE,UAAU,SAAS,SAAS,UAC5B,UAAU,SAAS,WAAW,mBAC9B,UAAU,MAAM,QAAQ,QAAQ,MAAM,KAAA,MAEtC,OAAO;IACT,MAAM,EAAE,QAAQ,UAAU,MAAM,QAAQ,KAAK,OAAO,UAAU,GAAG;IACjE,MAAM,SAAS,OAAO,SAAS,SAAS,KAAK,MAAM,UAAU,UAAU,MAAM,IAAI;IACjF,SAAS;IACT,IAAI,UAAU,YAAY,OAAO;IACjC,IAAI,IAAI,SAAS,SAAS,OAAO,SAAS,WAAW,IAAI,KAAK,QAAQ,KAAK;SACtE;KACH,MAAM,KAAK,KAAK,OAAO,KAAK,IAAI,MAAM;KACtC,MAAM,KAAK,KAAK,QAAQ,KAAK;IAC/B;IACA,OAAO;GACT,SAAS,OAAO;IACd,IAAI,iBAAiB,eACf;SAAA,UAAU,YAAY,MAAM,OAAO,GAAG;IAAA,OACrC,YAAY,WAAW,KAAK;IACnC,OAAO,UAAU,UAAU;GAC7B;EACF;EACA,YAAY;GACV,MAAM,QAAQ;GACd,eAAe,KAAA;GACf,OAAO;EACT;EACA,MAAM,QAAQ,MAAM,WAAW,SAAS,KAAqC;GAC3E,MAAM,QAAQ,KAAK;GACnB,IAAI,QAAQ,WAAW,YAAY,UAAU,KAAA,GAAW,OAAO,KAAA;GAC/D,MAAM,QAAQ;GACd,IAAI;IACF,IAAI,UAAU,MAAM,QAAQ,QAAQ,MAAM,KAAA,MAAoB;KAC5D,MAAM,KAAK,KAAK,UAAU,KAAK,QAAQ,MAAM;KAC7C,OAAO;IACT;IACA,MAAM,EAAE,QAAQ,UAAU,MAAM,QAAQ,KAAK,OAAO,UAAU,GAAG;IACjE,IAAI,UAAU,YAAY,OAAO,KAAA;IAGjC,GAAG,YAAY,0BAA0B;KACvC,UAAU;KACV,SAAS,QAAQ,MAAM;KACvB;IACF,CAAC;IACD,MAAM,SAAS,OAAO,SAAS,KAAK,MAAM,UAAU,UAAU,MAAM,IAAI;IACxE,IAAI,IAAI,SAAS,SAAS,OAAO,SAAS,WAAW;KACnD,IAAI,KAAK,QAAQ,KAAK;KACtB;IACF;IACA,MAAM,KAAK,KAAK,OAAO,KAAK,QAAQ,MAAM;IAC1C,IAAI,CAAE,MAAM,UAAU,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,MAAM,CAAC,GACzE,OAAO,KAAA;IACT,MAAM,WAAW,OAAO,OAAO,IAAI;IACnC,IAAI,UAAU,YAAY,OAAO,KAAA;IACjC,OAAO;KACL,GAAG;KACH,OAAO;MACL,GAAG;MACH,MAAM,QAAQ,MAAM;MACpB,OAAO,OAAO;MACd,WAAW,OAAO;MAClB,MAAM;MACN,OAAO,CAAC;KACV;IACF;GACF,SAAS,OAAO;IACd,IAAI,iBAAiB,iBAAiB,UAAU,YAAY,MAAM,OAAO,GAAG;IAC5E,MAAM;GACR;EACF;CACF;AACF;;ACpeA,SAAgB,kBAAkB,KAAgC;CAChE,IAAI,QAAQ,KAAA,GAAW,OAAO,CAAC;CAC/B,MAAM,UAAU,mBAAmB,GAAG;CACtC,IAAI,CAAC,kBAAkB,KAAK;EAAE,SAAS;EAAG;CAAQ,CAAC,GACjD,MAAM,IAAI,MAAM,8CAA8C;CAChE,OAAO;AACT;AAEA,eAAsB,iBAAiB,MAAyD;CAC9F,OAAO,kBAAkB,MAAM,KAAK,KAAK,CAAC;AAC5C;;AAGA,SAAgB,oBAAoB,MAAgB,KAA8B;CAChF,OAAO,KAAK,QAAQ,YAAY;EAC9B,MAAM,QAAQ,IAAI,IAChB,cAAc;GAAE,YAAY,IAAI;GAAY,SAAS,IAAI;GAAI,WAAW,IAAI;EAAQ,CAAC,CAAC,CAAC,IACrF,aACF,CACF;EAIA,OAAO;GAAE,MAAM;IAAE,SAAS;IAAG,SAHb,kBAAkB,OAAO,CAAC,CAAC,QACxC,WAAW,CAAC,MAAM,IAAI,cAAc,OAAO,GAAG,CAAC,CAEf;GAAE;GAAG,QAAQ,KAAA;EAAU;CAC5D,CAAC;AACH;;AC7BA,MAAM,QAAyC;CAC7C,iBACE;CACF,gBAAgB;CAChB,oBACE;CACF,oBACE;AACJ;AACA,MAAM,OAAmC;CACvC,eACE;CACF,iBAAiB;CACjB,0BACE;CACF,eACE;AACJ;AAEA,MAAa,UAAoB;CAC/B,aAAa;CACb,wBAAwB;CACxB,qBAAqB,WAAW,MAAM;CACtC,kBAAkB,WAAW,KAAK;AACpC;;;;;;;;;ACfA,SAAgB,cACd,UACkD;CAClD,MAAM,UAA4D,CAAC;CACnE,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,UAAU,SAAS,MAAM,OAAO,QAAQ,KAAK;EAAE;EAAM;CAAO,CAAC;CAE1E,OAAO;AACT;;AAGA,SAAgB,UAAU,OAAuB;CAC/C,MAAM,KAAK,IAAI,KAAK,KAAK;CACzB,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CACnD,MAAM,UAAU,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CACvD,MAAM,QAAQ,OAAO,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CACvD,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CAChD,OAAO,GAAG,OAAO,GAAG,YAAY,CAAC,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG;AACjE;AAEA,SAAS,SAAS,KAAgC,KAAqC;CACrF,IAAI,QAAQ,MAAM,OAAO;CACzB,OAAO,IAAI,eAAe,IAAI,cAAc,IAAI,OAAO,IAAI,MAAM,IAAI,YAAY,IAAI;AACvF;;AAGA,SAAS,YAAY,QAA4B,KAAoC;CACnF,IAAI,SAAS;CACb,IAAI,OAAO,UACT,UACE,OAAO,gBAAgB,OACnB,kCACA,oBAAoB,UAAU,OAAO,WAAW;CAExD,IAAI,OAAO,gBAAgB,MAAM;EAC/B,UAAU,UAAU,OAAO,OAAO,WAAW,EAAE;EAC/C,IAAI,OAAO,YAAY,MAAM,UAAU,YAAY,UAAU,OAAO,OAAO;CAC7E;CACA,IAAI,OAAO,YAAY,QAAQ,UAAU;MACpC,IAAI,OAAO,YAAY,aAAa,UAAU;CACnD,IAAI,SAAS,OAAO,KAAK,GAAG,GAAG,UAAU;CACzC,OAAO;AACT;;AAGA,SAAgB,UAAU,QAA4B,KAAoC;CACxF,OAAO,YAAY,QAAQ,GAAG,CAAC,CAAC,QAAQ,UAAU,EAAE,KAAK;AAC3D;;;;;;;AAQA,SAAgB,YAAY,UAAoC;CAC9D,MAAM,SAAS;EAAC;EAAS;EAAQ;EAAU;CAAO;CAClD,MAAM,OAAO,cAAc,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,aAAa;EAC7D,cAAc,OAAO,GAAG;EACxB;EACA,OAAO;EACP,UAAU,QAAQ,SAAS,GAAG;CAChC,CAAC;CAGD,MAAM,SAAS,OAAO,KAAK,MAAM,WAE/B,KAAK,IAAI,KAAK,QAAQ,GAAG,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAE,MAAM,CAAC,CACjE;CACA,MAAM,UAAU,UACd,MAEG,KAAK,MAAM,WAAW,KAAK,OAAO,OAAO,OAAQ,CAAC,CAAC,CACnD,KAAK,IAAI,CAAC,CACV,QAAQ;CACb,OAAO,CAAC,OAAO,MAAM,GAAG,GAAG,KAAK,IAAI,MAAM,CAAC;AAC7C;;AAGA,SAAgB,cAAc,UAAoC;CAChE,OAAO,cAAc,QAAQ,CAAC,CAAC,SAAS,EAAE,MAAM,aAAa;EAC3D,cAAc,OAAO,GAAG;EACxB,GAAG,KAAK,KAAK,OAAO;EACpB,GAAG,UAAU,QAAQ,SAAS,GAAG,CAAC,CAC/B,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,MAAM;EAC5B;CACF,CAAC;AACH;;AAGA,MAAa,uBAAuB;;ACjGpC,SAAS,OAAO,OAAkD;CAChE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,eAAsB,qBACpB,MACA,MACoC;CACpC,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,KAAK,IAAI;CACxB,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAAU,OAAO,CAAC;EAClF,MAAM;CACR;CACA,IAAI;CACJ,IAAI;EACF,MAAM,KAAK,MAAM,IAAI;CACvB,QAAQ;EACN,MAAM,IAAI,MAAM,qCAAqC;CACvD;CACA,OAAO,sBAAsB,GAAG;AAClC;AAEA,SAAgB,sBAAsB,KAAyC;CAC7E,IACE,EAAE,OAAO,GAAG,KAAK,MAAM,QAAQ,IAAI,SAAS,MAC5C,OAAO,KAAK,GAAG,CAAC,CAAC,MAAM,QAAQ,QAAQ,QAAQ,GAE/C,MAAM,IAAI,MAAM,yEAAyE;CAC3F,MAAM,uBAAO,IAAI,IAAY;CAC7B,OAAO,IAAI,SAAS,CAAC,KAAK,OAAgB,UAAkB;EAC1D,MAAM,QAAQ,gCAAgC,OAAO,KAAK,EAAE;EAC5D,IAAI,CAAC,OAAO,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,qBAAqB;EAClE,MAAM,aAAa,MAAM;EACzB,MAAM,KAAK,MAAM;EACjB,MAAM,QAAQ,MAAM;EACpB,IAAI,OAAO,eAAe,YAAY,WAAW,KAAK,CAAC,CAAC,WAAW,GACjE,MAAM,IAAI,MAAM,GAAG,MAAM,yCAAyC;EACpE,IAAI,OAAO,OAAO,YAAY,GAAG,KAAK,CAAC,CAAC,WAAW,GACjD,MAAM,IAAI,MAAM,GAAG,MAAM,iCAAiC;EAC5D,IAAI,OAAO,UAAU,WAAW,MAAM,IAAI,MAAM,GAAG,MAAM,2BAA2B;EACpF,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC;GAAC;GAAc;GAAM;EAAO,CAAC,CAAC,SAAS,GAAG,CAAC,GAC/E,MAAM,IAAI,MAAM,GAAG,MAAM,gBAAgB;EAC3C,MAAM,MAAM,KAAK,UAAU,CAAC,YAAY,EAAE,CAAC;EAC3C,IAAI,KAAK,IAAI,GAAG,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB;EAC9D,KAAK,IAAI,GAAG;EACZ,OAAO;GAAE;GAAY;GAAI;EAAM;CACjC,CAAC;AACH;AAEA,SAAgB,qBAAqB,MAAgB,KAAe,OAA+B;CACjG,OAAO,KAAK,QAAQ,YAAY;EAC9B,MAAM,UAAU,YAAY,KAAA,IAAY,CAAC,IAAI,sBAAsB,OAAO;EAC1E,MAAM,QAAQ;GAAE,YAAY,IAAI;GAAY,IAAI,IAAI;GAAI;EAAM;EAC9D,MAAM,SAAS,CACb,GAAG,QAAQ,QAAQ,UAAU,MAAM,eAAe,IAAI,cAAc,MAAM,OAAO,IAAI,EAAE,GACvF,KACF;EACA,sBAAsB,EAAE,OAAO,CAAC;EAChC,OAAO;GAAE,MAAM,EAAE,OAAO;GAAG,QAAQ,KAAA;EAAU;CAC/C,CAAC;AACH;;AC7DA,MAAa,qBACX;AAEF,eAAsB,kBAAkB,MAAoB,MAA+B;CACzF,MAAM,UAAU,MAAM,gBAAgB,IAAI;CAC1C,MAAM,SAAS,MAAM,KAAK,OAAO;EAC/B,OAAO;EACP,SAAS,CACP;GAAE,OAAO,qBAAqB,QAAQ;GAAa,OAAO;EAAQ,GAClE;GACE,OAAO,gCAAgC,QAAQ,qBAAqB,OAAO;GAC3E,OAAO;EACT,CACF;CACF,CAAC;CACD,IAAI,WAAW,SAAS;EACtB,MAAM,YAAY,MAAM,KAAK,OAAO;GAClC,OAAO;GACP,SAAS,iBAAiB,KAAK,WAAW;IAAE,OAAO;IAAO;GAAM,EAAE;EACpE,CAAC;EACD,IAAI,cAAc,KAAA,GAAW;EAC7B,MAAM,kBAAkB,MAAM,EAAE,UAAU,CAAC;CAC7C,OAAO,IAAI,WAAW,YAAY;EAOhC,IAAI,MANoB,KAAK,QAAQ;GACnC,OAAO;GACP,SAAS,QAAQ,qBACb,4DACA;EACN,CAAC,MACiB,MAAM;EACxB,MAAM,kBAAkB,MAAM,EAAE,oBAAoB,CAAC,QAAQ,mBAAmB,CAAC;CACnF,OAAO;CACP,KAAK,MAAM,qBAAqB,SAAS;AAC3C;AAEA,SAAS,cAAc,UAAqC,KAAuB;CACjF,MAAM,QAAQ,SAAS,MAAM,UAAU,MAAM,eAAe,IAAI,cAAc,MAAM,OAAO,IAAI,EAAE;CACjG,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,OAAO,MAAM,QAAQ,gBAAgB;AACvC;;;;;AAMA,eAAsB,kBACpB,MACA,MACA,QACA,UACe;CAEf,MAAM,SAAS,CACb,GAAG,IAAI,IACL,OAAO,KAAK,UAAU,CACpB,GAAG,MAAM,WAAW,GAAG,MAAM,MAC7B;EAAE,YAAY,MAAM;EAAY,IAAI,MAAM;CAAG,CAC/C,CAAC,CACH,CACF;CACA,IAAI,OAAO,WAAW,GAAG;EACvB,MAAM,KAAK,MAAM;GAAE,OAAO;GAAgB,SAAS;EAAqB,CAAC;EACzE;CACF;CACA,MAAM,MAAM,MAAM,KAAK,OAAO;EAC5B,OAAO;EACP,SAAS,OAAO,KAAK,CAAC,OAAO,YAAY;GACvC,OAAO;GACP,OAAO;GACP,aAAa,cAAc,UAAU,KAAK;EAC5C,EAAE;CACJ,CAAC;CACD,IAAI,QAAQ,KAAA,GAAW;CACvB,MAAM,QAAQ,MAAM,KAAK,OAAO;EAC9B,OAAO,GAAG,IAAI,WAAW,GAAG,IAAI;EAChC,SAAS,CACP;GAAE,OAAO;GAAe,OAAO;GAAM,aAAa;EAA0B,GAC5E;GAAE,OAAO;GAAiB,OAAO;GAAO,aAAa;EAAgC,CACvF;CACF,CAAC;CACD,IAAI,UAAU,KAAA,GAAW;CACzB,IACE,CAAE,MAAM,KAAK,QAAQ;EACnB,OAAO;EACP,SAAS,GAAG,IAAI,WAAW,GAAG,IAAI,GAAG,2BAA2B,QAAQ,cAAc,cAAc;CACtG,CAAC,GAED;CACF,MAAM,qBAAqB,MAAM,KAAK,KAAK;CAC3C,KAAK,MAAM,yBAAyB,SAAS;AAC/C;;;;;;;AChFA,SAAS,OAAO,OAAe,MAAsB;CACnD,OAAO,GAAG,OAAO,KAAK,EAAE,GAAG,OAAO,UAAU,IAAI,KAAK;AACvD;;AAGA,SAAgB,aAAa,UAAyC;CACpE,MAAM,QAAuB,MAAM,QAAQ,SAAS,SAAS,MAAM,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KACpF,UAAU;EACT,OAAO;EACP,SAAS,GAAG,KAAK;EACjB,QAAQ;CACV,EACF;CAEA,MAAM,UAAU,IAAI,IAClB,cAAc,QAAQ,CAAC,CACpB,QAAQ,EAAE,aAAa,OAAO,WAAW,SAAS,CAAC,CACnD,KAAK,EAAE,aAAa,cAAc,OAAO,GAAG,CAAC,CAClD,CAAC,CAAC;CACF,OAAO;EACL,GAAG;EACH,YAAY,IACR;GAAE,OAAO;GAAM,SAAS;EAA4B,IACpD;GACE,OAAO;GACP,SAAS,WAAW,OAAO,SAAS,OAAO,EAAE;GAC7C,QAAQ;EACV;EACJ,SAAS,WAAW,IAChB;GAAE,OAAO;GAAM,SAAS;EAAiB,IACzC;GACE,OAAO;GACP,SAAS,OAAO,SAAS,QAAQ,aAAa;GAC9C,QAAQ;EACV;CACN;AACF;AAEA,MAAM,SAA+C;CAAE,IAAI;CAAM,SAAS;CAAS,OAAO;AAAM;AAEhG,MAAM,WAA4C;CAAC;CAAS;CAAW;AAAI;;AAG3E,SAAgB,YAAY,QAA0C;CACpE,MAAM,SAAS,UACb,OAAO,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC,CAAC;CAElD,OAAO,CADU,MAAM,OAAO,IAAI,MAAM,SAAS,MAElC,IACT,OAAO,OAAO,OAAO,MAAM,EAAE,cAC7B,GAAG,OAAO,MAAM,OAAO,CAAC,EAAE,YAAY,OAAO,MAAM,SAAS,CAAC,EAAE,cAAc,OAAO,MAAM,IAAI,CAAC,EAAE,MACrG,GAAG,SAAS,SAAS,UAAU,OAAO,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC,CAAC,CAAC,SAC7E,UAAU,CACT,GAAG,OAAO,MAAM,OAAO,GAAG,MAAM,WAChC,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,MAAM,QAAQ,CAC5D,CACF,CACF;AACF;;ACtEA,MAAM,SAAS;AACf,MAAM,YAAY;AASlB,SAAS,WAAW,IAAoB;CACtC,MAAM,OAAO,IAAI,KAAK,EAAE;CACxB,OAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ;AAC/E;AAEA,SAAS,MAAM,MAAoB;CACjC,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;AACjG;;;;;;AAOA,SAAgB,aAAa,UAAyB,KAAqB;CACzE,IAAI,aAAa,MAAM,OAAO;CAC9B,IAAI,YAAY,KAAK,OAAO;CAC5B,MAAM,OAAO,IAAI,KAAK,QAAQ;CAE9B,MAAM,OAAO,KAAK,OAAO,WAAW,QAAQ,IAAI,WAAW,GAAG,KAAK,MAAM;CACzE,IAAI,SAAS,GAAG,OAAO,qBAAqB,MAAM,IAAI;CAEtD,MAAM,MAAM,KAAK,aAAa;CAC9B,IAAI,QAAQ,WAAW,OAAO,qBAAqB,IAAI,MAAM,GAAG,CAAC,EAAE,GAAG,MAAM,IAAI;CAChF,OAAO,qBAAqB,IAAI,MAAM,GAAG,CAAC,EAAE,GAAG,OAAO,KAAK,QAAQ,CAAC,EAAE,GAAG,MAAM,IAAI;AACrF;;ACTA,MAAM,eAAe;AACrB,MAAM,iBAAiB;AACvB,MAAM,eAAe;;AAGrB,eAAsB,eACpB,KACA,OACe;CACf,MAAM,WAAW,MAAM,IAAI,IAAI,OAAO;CACtC,MAAM,yBAAS,IAAI,IAAgC;CACnD,KAAK,MAAM,EAAE,YAAY,cAAc,QAAQ,GAAG,OAAO,IAAI,cAAc,OAAO,GAAG,GAAG,MAAM;CAC9F,IAAI,OAAO,SAAS,GAAG;EACrB,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAU,SAAS;EAAqB,CAAC;EACvE;CACF;CACA,MAAM,QAAQ,MAAM,IAAI,KAAK,OAAO;EAClC,OAAO;EACP,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY;GAC5C,MAAM,QAAQ,UAAU,QAAQ,SAAS,GAAG;GAC5C,OAAO;IACL,OAAO;IACP,OAAO,OAAO;IACd,aAAa,UAAU,MAAM,OAAO,SAAS,GAAG,OAAO,OAAO,KAAK;GACrE;EACF,CAAC;CACH,CAAC;CACD,IAAI,UAAU,KAAA,GAAW;CACzB,MAAM,QAAQ,cAAc,KAAK;CAKjC,IAAI,MAJoB,IAAI,KAAK,QAAQ;EACvC,OAAO;EACP,SAAS,SAAS,MAAM;CAC1B,CAAC,MACiB,MAAM;CACxB,MAAM,MAAM,KAAK;CACjB,IAAI,KAAK,MAAM,gBAAgB,SAAS;AAC1C;;AAGA,eAAsB,WACpB,KACA,QACkB;CAClB,IAAI,IAAI,cAAc,KAAA,GAAW;EAC/B,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAc,SAAS;EAAa,CAAC;EACnE,OAAO;CACT;CAEA,QAAQ,MADc,OAAO,IAAI,SAAS,GAC1C;EACE,KAAK;GACH,IAAI,KAAK,MAAM,wBAAwB,SAAS;GAChD,OAAO;EACT,KAAK;GACH,MAAM,IAAI,KAAK,MAAM;IACnB,OAAO;IACP,SAAS;GACX,CAAC;GACD,OAAO;EACT,KAAK;GACH,MAAM,IAAI,KAAK,MAAM;IAAE,OAAO;IAAc,SAAS;GAAe,CAAC;GACrE,OAAO;CACX;AACF;;AAGA,eAAsB,WACpB,KACA,QACe;CACf,IAAI,IAAI,cAAc,KAAA,GAAW;EAC/B,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAc,SAAS;EAAa,CAAC;EACnE;CACF;CACA,IAAK,MAAM,OAAO,IAAI,SAAS,MAAO,aACpC,IAAI,KAAK,MAAM,yBAAyB,SAAS;MAC9C,MAAM,IAAI,KAAK,MAAM;EAAE,OAAO;EAAc,SAAS;CAAe,CAAC;AAC5E;;;;;;AAOA,eAAsB,cAAc,KAAkB,SAA4C;CAChG,MAAM,EAAE,YAAY,MAAM,IAAI,IAAI,OAAO;CACzC,IAAI,QAAQ,WAAW,GAAG;EACxB,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAc,SAAS;EAAkB,CAAC;EACxE,OAAO;CACT;CACA,MAAM,OAAO,IAAI,SAAS,KAAK,IAAA,CAAK;CACpC,MAAM,SAAS,MAAM,IAAI,KAAK,OAAO;EACnC,OAAO;EACP,SAAS,QAAQ,KAAK,WAAW;GAC/B,OAAO,MAAM,cAAc,IAAI,YAAY,iBAAiB,MAAM;GAClE,OAAO,MAAM;GACb,aAAa,GAAG,MAAM,KAAK,KAAK,aAAa,MAAM,UAAU,GAAG;EAClE,EAAE;CACJ,CAAC;CACD,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,WAAW,IAAI,WAAW;EAC5B,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAc,SAAS;EAAa,CAAC;EACnE,OAAO;CACT;CACA,MAAM,EAAE,QAAQ,WAAW;CAC3B,MAAM,MAAM,MAAM,IAAI,KAAK,OAA+B;EACxD,OAAO;EACP,SAAS,CACP,GAAI,WAAW,KAAA,IACX,CAAC,IACD,CACE;GACE,OAAO;GACP,aAAa,WAAW,KAAK,MAAM;GACnC,aAAa;EACf,CACF,GACJ,GAAI,WAAW,KAAA,IACX,CAAC,IACD,CACE;GACE,OAAO;GACP,OAAO,YAAY;IACjB,MAAM,WAAW,KAAK,MAAM;IAC5B,OAAO;GACT;GACA,aAAa;EACf,CACF,CACN;CACF,CAAC;CACD,OAAO,QAAQ,KAAA,IAAY,QAAQ,IAAI;AACzC;AAEA,eAAsB,UACpB,KACA,QACe;CACf,MAAM,IAAI,KAAK,MAAM;EAAE,OAAO;EAAmB,OAAO,YAAY,MAAM,OAAO,CAAC;CAAE,CAAC;AACvF;;;;;;;AC3JA,MAAa,kBAAkB;CAAC;CAAU;CAAU;CAAQ;CAAQ;CAAO;AAAU;;AAIrF,SAAgB,cAAc,QAA4C;CACxE,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,QAAQ,MAAM,QAAQ,KAAK,SAAS,MAAM,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC;CAC5E,IAAI,UAAU,GAAG,OAAO;CACxB,MAAM,WAAW,MAAM,QACpB,KAAK,SAAS,MAAM,OAAO,MAAM,KAAK,CAAC,QAAQ,UAAU,MAAM,QAAQ,CAAC,CAAC,QAC1E,CACF;CACA,MAAM,eAAe,aAAa,IAAI,KAAK,MAAM,OAAO,QAAQ,EAAE;CAClE,OAAO,GAAG,OAAO,KAAK,EAAE,WAAW,UAAU,IAAI,KAAK,MAAM;AAC9D;;AAGA,SAAgB,cAAc,UAA8B;CAE1D,OADc,MAAM,KAAK,SAAmB,GAAG,KAAK,IAAI,OAAO,SAAS,MAAM,KAAK,CAAC,MAAM,GAC/E,CAAC,CAAC,KAAK,KAAK;AACzB;AAEA,SAAS,uBAAuB,aAAkD;CAChF,IAAI,gBAAgB,KAAA,GAAW,OAAO;CACtC,IAAI,gBAAgB,MAAM,OAAO;CACjC,OAAO,aAAa,YAAY;AAClC;AAEA,SAAS,WACP,MACA,OACoC;CACpC,IAAI,SAAS,MAAM,UAAU,OAAO;CACpC,IAAI,SAAS,MAAM,WAAW,OAAO;AAEvC;AAEA,SAAgB,gBACd,UACA,QACA,aACA,gBAA+B,SAAS,MACR;CAChC,MAAM,aAAa,SAAuD;EACxE,QAAQ,MAAR;GACE,KAAK,UACH,OAAO;IACL,OAAO;IACP,OAAO;IACP,aAAa,cAAc,MAAM;GACnC;GACF,KAAK,UACH,OAAO;IACL,OAAO;IACP,OAAO;IACP,aAAa,cAAc,QAAQ;GACrC;GACF,KAAK,QACH,OAAO;IACL,OAAO;IACP,OAAO;IACP,aAAa,aAAa;GAC5B;GACF,KAAK,QACH,OAAO;IACL,OAAO;IACP,OAAO;IACP,aAAa,uBAAuB,WAAW;GACjD;GACF,KAAK,OACH,OAAO;IACL,OAAO;IACP,OAAO;IACP,aACE,SAAS,QAAQ,OACb,uBACA,aAAa,cAAc,SAAS,GAAG;GAC/C;GACF,KAAK,YACH,OAAO;IAAE,OAAO;IAAY,OAAO;IAAM,aAAa;GAAqC;EAC/F;CACF;CACA,OAAO,gBAAgB,IAAI,SAAS;AACtC;AAEA,SAAgB,YAAY,SAAuD;CACjF,OAAO,gBAAgB,KAAK,UAAU;EACpC,OAAO,SAAS,UAAU,GAAG,KAAK,cAAc;EAChD,OAAO;EACP,aAAa,gBAAgB,IAAI;CACnC,EAAE;AACJ;;AAGA,SAAgB,gBAAgB,MAA6B;CAC3D,QAAQ,MAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,UACH,OAAO;CACX;AACF;;;;;;;AAcA,SAAgB,kBACd,QACA,WAC4B;CAC5B,OAAO,CACL;EACE,OAAO;EACP,aAAa,qDAAqD,OAAO;EACzE,OAAO;CACT,GACA;EACE,OAAO;EACP,aAAa,uCAAuC,UAAU;EAC9D,OAAO;CACT,CACF;AACF;;;;;;;AAQA,SAAgB,mBAAmB,OAIG;CACpC,MAAM,UAA6C,CACjD;EACE,OAAO,kBAAkB,MAAM,OAAO;EACtC,aAAa;EACb,OAAO,EAAE,MAAM,SAAS;CAC1B,CACF;CACA,KAAK,MAAM,QAAQ,iBAAiB;EAClC,MAAM,SAAS,WAAW,MAAM,KAAK;EACrC,QAAQ,KAAK;GACX,OAAO,WAAW,KAAA,IAAY,OAAO,GAAG,KAAK,IAAI,OAAO;GACxD,OAAO;IAAE,MAAM;IAAQ;GAAK;GAC5B,aAAa,gBAAgB,IAAI;EACnC,CAAC;CACH;CACA,OAAO;AACT;;AAGA,SAAS,gBAAgB,MAAwB;CAC/C,QAAQ,MAAR;EACE,KAAK,SACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,YACH,OAAO;CACX;AACF;;;;;;AAUA,SAAgB,mBAAmB,OAEG;CACpC,MAAM,UAA6C,CACjD;EACE,OAAO;EACP,aAAa;EACb,OAAO,EAAE,MAAM,SAAS;CAC1B,CACF;CACA,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK;EACX,OAAO,SAAS,MAAM,SAAS,GAAG,KAAK,aAAa;EACpD,OAAO;GAAE,MAAM;GAAQ;EAAK;EAC5B,aAAa,gBAAgB,IAAI;CACnC,CAAC;CAEH,OAAO;AACT;;;AC5MA,SAAgB,UAAU,OAAwB;CAChD,IAAI,iBAAiB,OAAO,OAAO,MAAM;CAGzC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,UAAW,MAAgC;EACjD,IAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,GAAG,OAAO;EAG9D,OAAO,KAAK,UAAU,QAAQ,GAAG,UAC/B,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI,KAC9C;CACF;CACA,OAAO,OAAO,KAAK;AACrB;;ACXA,SAAgB,kBAAkB,UAA4B;CAC5D,QAAQ,SAAS,MAAjB;EACE,KAAK,SAAS;GACZ,MAAM,OAAO,SAAS,SAAS,KAAA,IAAY,KAAK,KAAK,SAAS,KAAK;GACnE,OAAO,SAAS,cAAc,SAAS,KAAK,IAAI,KAAK,IAAI,SAAS,OAAO;EAC3E;EACA,KAAK,SAAS;GACZ,MAAM,SAAS,SAAS,WAAW,KAAA,IAAY,KAAK,MAAM,SAAS;GACnE,OAAO,UAAU,SAAS,SAAS;EACrC;EACA,KAAK,QAAQ;GACX,MAAM,SAAS,SAAS,WAAW,KAAA,IAAY,KAAK,MAAM,SAAS;GACnE,OAAO,SAAS,SAAS,SAAS;EACpC;EACA,KAAK,YACH,OAAO,YAAY,SAAS,KAAK,KAAK,cAAc,SAAS,MAAM,EAAE,IAAI,SAAS,KAAK;EAEzF,KAAK,gBACH,OAAO,YAAY,kBAAkB,SAAS,KAAK;CAEvD;AACF;AAEA,SAAgB,YAAY,SAA6C;CACvE,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,IAAI,QAAQ,WAAW,aAAa,OAAO;CAC3C,IAAI,QAAQ,WAAW,UAAU,OAAO,WAAW,QAAQ,SAAS;CACpE,OAAO,gBAAgB,QAAQ,OAAO;AACxC;AAEA,SAAgB,YAAY,SAA0B;CACpD,OAAO,IAAI,OAAO,QAAQ,EAAE,EAAE,GAAG,kBAAkB,QAAQ,QAAQ,EAAE,KAAK,YAAY,QAAQ,OAAO;AACvG;AAEA,SAAgB,cAAc,SAAkB,MAAgB,MAAc,KAAK,IAAI,GAAW;CAChG,OAAO;EACL,OAAO,OAAO,QAAQ,EAAE;EACxB,SAAS,aAAa,QAAQ,IAAI,GAAG,EAAE,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC,CAAC,YAAY,EAAE;EAC9E,YAAY,QAAQ;EACpB,SAAS,QAAQ,UAAU;EAC3B,SAAS,QAAQ,QAAQ;EACzB,aAAa,kBAAkB,QAAQ,QAAQ;EAC/C,YAAY,YAAY,QAAQ,OAAO;EACvC;EACA,kBAAkB,aAAa,SAAS,IAAI;CAC9C,CAAC,CAAC,KAAK,IAAI;AACb;;AAGA,SAAgB,aAAa,IAAY,KAAqB;CAC5D,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,MAAM,MAAM,GAAI,CAAC;CACzD,IAAI,UAAU,IAAI,OAAO;CACzB,MAAM,UAAU,KAAK,MAAM,UAAU,EAAE;CACvC,IAAI,UAAU,IAAI,OAAO,GAAG,OAAO,OAAO,EAAE;CAC5C,MAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;CACrC,IAAI,QAAQ,IAAI,OAAO,GAAG,OAAO,KAAK,EAAE;CACxC,OAAO,GAAG,OAAO,KAAK,MAAM,QAAQ,EAAE,CAAC,EAAE;AAC3C;;;;;AAMA,SAAgB,aAAa,SAAkB,MAAwB;CACrE,MAAM,WAAW,QAAQ;CACzB,QAAQ,SAAS,MAAjB;EACE,KAAK,SACH,OAAO,iBAAiB,SAAS;EACnC,KAAK;GACH,IACE,SAAS,WAAW,mBACpB,SAAS,WAAW,kBACpB,SAAS,WAAW,sBACpB,SAAS,WAAW,oBAEpB,OAAO,KAAK,mBAAmB,SAAS,MAAM;GAChD,OAAO,iBAAiB,SAAS;EACnC,KAAK,QACH,OAAO,KAAK,kBAAkB,SAAS,MAAM,KAAK,gBAAgB,SAAS;EAC7E,KAAK,YACH,OAAO,iEAAiE,cAAc,SAAS,MAAM,EAAE;EACzG,KAAK,gBACH,OAAO;CACX;AACF;AAEA,MAAM,mBAAgD;CACpD,KAAK;CACL,WACE;CACF,UACE;CACF,OACE;CACF,UAAU;AACZ;AAEA,MAAM,mBAAmF;CACvF,4BACE;CACF,+BACE;CACF,sBACE;CACF,2BACE;AACJ;AAEA,MAAM,kBAA8C;CAClD,eACE;CACF,iBACE;CACF,0BACE;CACF,eAAe;AACjB;AAKA,SAAgB,YAAY,UAAyC;CACnE,OAAO,SAAS,MAAM,GAAA,EAAqB;AAC7C;;ACzCA,MAAa,iBACX;;AASF,eAAe,OAAU,KAAkB,KAA+C;CACxF,IAAI;EACF,OAAO,MAAM,IAAI;CACnB,SAAS,OAAO;EACd,IAAI,KAAK,MAAM,UAAU,KAAK,GAAG,OAAO;EACxC;CACF;AACF;;;;;;;AAQA,eAAe,cACb,KACA,OACA,UACiC;CACjC,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,YAAY,KAAK,CAAC;CACjE,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAoB,SAAS,OAAO,OAAO,KAAK,IAAI;EAAE,CAAC;EACrF;CACF;CACA,IAAI,CAAC,SAAS,MAAM;EAClB,IAAI,KAAK,MAAM,kBAAkB,SAAS;EAC1C,SAAS,OAAO;CAClB;CACA,OAAO,OAAO;AAChB;;;;;;AAOA,eAAe,iBACb,KACA,WACA,MACA,UAC2C;CAC3C,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,eAAe,WAAW,IAAI,CAAC;CAC9E,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAoB,SAAS,OAAO,OAAO,KAAK,IAAI;EAAE,CAAC;EACrF;CACF;CACA,IAAI,CAAC,SAAS,MAAM;EAClB,IAAI,KAAK,MAAM,kBAAkB,SAAS;EAC1C,SAAS,OAAO;CAClB;CACA,OAAO;AACT;;;;;;AAOA,eAAe,iBACb,KACA,WACA,MACA,UAC2C;CAC3C,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,eAAe,WAAW,IAAI,CAAC;CAC9E,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAwB,SAAS,OAAO,OAAO,KAAK,IAAI;EAAE,CAAC;EACzF;CACF;CACA,IAAI,CAAC,SAAS,MAAM;EAClB,IAAI,KAAK,MAAM,kBAAkB,SAAS;EAC1C,SAAS,OAAO;CAClB;CACA,OAAO;AACT;AAKA,SAAS,cAAc,KAA6C;CAClE,MAAM,UAAU,IAAI,WAAW,CAAC;CAChC,MAAM,EAAE,aAAa,QAAQ,QAAQ,OAAO,QAAQ,aAAa,aAAa;CAC9E,MAAM,QACH,QACD,YAAY;EACV,MAAM,IAAI;EACV,OAAO;CACT;CAiCF,OAAO;EA/BL,gBAAgB,KAAA,KAAa;GAC3B,OAAO;GACP,OAAO,WAAW,eAAe,KAAK,WAAW,CAAC;GAClD,aAAa;EACf;GACC,WAAW,KAAA,KAAa,WAAW,KAAA,MAAc;GAChD,OAAO;GACP,aAAa,cAAc,KAAK,OAAO;GACvC,aAAa;EACf;EACA,UAAU,KAAA,KAAa;GACrB,OAAO;GACP,OAAO,KAAK,KAAK;GACjB,aAAa;EACf;EACA,WAAW,KAAA,KAAa;GACtB,OAAO;GACP,OAAO,WAAW,UAAU,KAAK,MAAM,CAAC;GACxC,aAAa;EACf;EACA,gBAAgB,KAAA,KAAa;GAC3B,OAAO;GACP,OAAO,KAAK,WAAW;GACvB,aAAa;EACf;EACA,aAAa,KAAA,KAAa;GACxB,OAAO;GACP,OAAO,KAAK,QAAQ;GACpB,aAAa;EACf;CAEQ,CAAC,CAAC,QAAQ,QAAQ,QAAQ,KAAK;AAC3C;AAEA,eAAsB,YAAY,KAAkB,SAAyC;CAC3F,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,SAAS,CAAC;CACzD,IAAI,WAAW,KAAA,GAAW;CAC1B,IAAI,WAAW;CACf,MAAM,WAAyB,EAAE,MAAM,MAAM;CAC7C,MAAM,YAAY,IAAI;CAGtB,IAAI,WACF,cAAc,KAAA,IACV,OACE,MAAM,OAAO,WAAW,IAAI,IAAI,YAAY,SAAS,CAAC,KAAM;CACpE,IAAI,CAAC,SAAS,iBAAiB;EAC7B,MAAM,IAAI,KAAK,QAAQ;GAAE,OAAO,IAAI,KAAK;GAAa,SAAS;EAAe,CAAC;EAC/E,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;GACjC,OAAO,IAAI,KAAK;GAChB,SAAS,CACP;IAAE,OAAO;IAAqB,OAAO;GAAK,GAC1C;IAAE,OAAO;IAAS,OAAO;GAAM,CACjC;EACF,CAAC;EACD,MAAM,YAAY,MAAM,cAAc,KAAK,EAAE,iBAAiB,KAAK,GAAG,QAAQ;EAC9E,IAAI,cAAc,KAAA,GAAW,WAAW;EACxC,IAAI,SAAS,MAAM;CACrB;CACA,IAAI,OAAO;CACX,SAAS;EAMP,MAAM,CAAC,eAAe,UAAU,MAAM,QAAQ,IAAI,CAChD,IAAI,IAAI,SAAS,CAAC,CAAC,YAAY,KAAA,CAAS,GACxC,IAAI,IAAI,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS,CACxC,CAAC;EACD,IAAI,kBAAkB,KAAA,GAAW,WAAW;EAI5C,MAAM,aACJ,cAAc,KAAA,IACV,KAAA,IACA,MAAM,IAAI,IAAI,YAAY,SAAS,CAAC,CAAC,YAAY,KAAA,CAAS;EAChE,MAAM,SACJ,QACC,MAAM,IAAI,KAAK,OAAmC;GACjD,OAAO,aAAa,YAAY,SAAS,KAAK;GAC9C,SAAS,CACP,GAAG,gBAAgB,UAAU,QAAQ,YAAY,YAAY,SAAS,IAAI,GAC1E,GAAG,cAAc,GAAG,CACtB;EACF,CAAC;EACH,OAAO,KAAA;EACP,IAAI,WAAW,KAAA,GAAW;EAC1B,IAAI,OAAO,WAAW,YAAY;GAEhC,IAAK,MAAM,OAAO,KAAK,MAAM,MAAO,MAAM;GAC1C;EACF;EACA,IAAI,WAAW,UAAU;GACvB,MAAM,cAAc,GAAG;GACvB;EACF;EACA,IAAI,WAAW,UAAU;GACvB,WAAY,MAAM,cAAc,KAAK,QAAQ,KAAM;GACnD;EACF;EACA,IAAI,WAAW,QAAQ;GACrB,MAAM,OAAO,MAAM,YAAY,KAAK,UAAU,UAAU,WAAW,QAAQ;GAC3E,IAAI,SAAS,KAAA,GAAW;IACtB,WAAW,KAAK;IAChB,WAAW,KAAK;GAClB;GACA;EACF;EACA,IAAI,WAAW,QAAQ;GACrB,IAAI,cAAc,KAAA,GAAW;IAG3B,MAAM,IAAI,KAAK,MAAM;KACnB,OAAO;KACP,SACE;IACJ,CAAC;IACD;GACF;GACA,MAAM,mBAAmB,KAAK,WAAW,QAAQ;GACjD;EACF;EACA,IAAI,WAAW,OAAO;GACpB,WAAY,MAAM,WAAW,KAAK,UAAU,QAAQ,KAAM;GAC1D;EACF;EACA,MAAM,gBAAgB,GAAG;CAC3B;AACF;AAQA,eAAe,YACb,KACA,UACA,UACA,WACA,UACsC;CAItC,SAAS;EACP,MAAM,SAAS,MAAM,IAAI,KAAK,OAAO;GACnC,OAAO;GACP,SAAS,kBAAkB,SAAS,MAAM,YAAY,SAAS,IAAI;EACrE,CAAC;EACD,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,IAAI,WAAW,UAAU;GACvB,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;IACjC,OAAO;IACP,SAAS,YAAY,SAAS,IAAI;GACpC,CAAC;GACD,IAAI,SAAS,KAAA,KAAa,SAAS,SAAS,MAAM,OAAO,KAAA;GACzD,MAAM,UAAU,MAAM,cAAc,KAAK,EAAE,MAAM,KAAK,GAAG,QAAQ;GAGjE,OAAO,YAAY,KAAA,IAAY,KAAA,IAAY;IAAE,UAAU;IAAS;GAAS;EAC3E;EACA,IAAI,cAAc,KAAA,GAAW;GAG3B,MAAM,IAAI,KAAK,MAAM;IACnB,OAAO;IACP,SACE;GACJ,CAAC;GACD;EACF;EACA,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;GACjC,OAAO;GACP,SAAS,mBAAmB;IAC1B,QAAQ,SAAS;IACjB;IACA,WAAW,YAAY,SAAS;GAClC,CAAC;EACH,CAAC;EACD,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;EAC/B,IAAI,KAAK,SAAS,UAAU;GAC1B,IAAI,aAAa,MAAM,OAAO,KAAA;GAE9B,OAAO,MADa,iBAAiB,KAAK,WAAW,MAAM,QAAQ,MAClD,KAAA,IAAY,KAAA,IAAY;IAAE;IAAU,UAAU;GAAK;EACtE;EACA,IAAI,KAAK,UAAU,YAAY,SAAS,OAAO,OAAO,KAAA;EAEtD,OAAO,MADa,iBAAiB,KAAK,WAAW,KAAK,MAAM,QAAQ,MACvD,KAAA,IAAY,KAAA,IAAY;GAAE;GAAU,UAAU,KAAK;EAAK;CAC3E;AACF;;AAGA,eAAe,mBACb,KACA,WACA,UACe;CACf,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,YAAY,SAAS,CAAC;CACrE,IAAI,WAAW,KAAA,GAAW;CAC1B,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;EACjC,OAAO;EACP,SAAS,mBAAmB,EAAE,OAAO,CAAC;CACxC,CAAC;CACD,IAAI,SAAS,KAAA,GAAW;CACxB,MAAM,OAAO,KAAK,SAAS,WAAW,OAAO,KAAK;CAClD,IAAI,SAAS,QAAQ;CACrB,MAAM,iBAAiB,KAAK,WAAW,MAAM,QAAQ;AACvD;;;;;;;AAQA,eAAe,cAAc,KAAiC;CAC5D,MAAM,WAAW,MAAM,OAAO,WAAW,IAAI,IAAI,OAAO,CAAC;CACzD,IAAI,aAAa,KAAA,GAAW;CAE5B,IAAI,CADe,MAAM,MAAM,SAAS,SAAS,MAAM,KAAK,CAAC,SAAS,CACxD,GAAG;EACf,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAU,SAAS;EAAqB,CAAC;EACvE;CACF;CACA,MAAM,IAAI,KAAK,MAAM;EACnB,OAAO;EACP,OAAO,YAAY,QAAQ;EAC3B,cAAc,cAAc,QAAQ;CACtC,CAAC;AACH;AAIA,eAAe,cAAc,KAAkB,UAAoD;CAGjG,IAAI;CACJ,SAAS;EAOP,MAAM,WAAW,MAAM,OAAO,WAAW,IAAI,IAAI,SAAS,CAAC;EAC3D,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,SAAS,MAAM,OAAO,WAAW,IAAI,IAAI,OAAO,CAAC;EACvD,IAAI,WAAW,KAAA,GAAW,OAAO;EACjC,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;GAAE,OAAO;GAAQ,SAAS,gBAAgB,MAAM;EAAE,CAAC;EACtF,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,IAAI,aAAa;EACjB,IAAI,eAAe;EAMnB,SAAS;GACP,MAAM,SAAS,MAAM,IAAI,KAAK,OAAO;IACnC,OAAO,SAAS;IAChB,SAAS,kBAAkB,cAAc,MAAM,YAAY,IAAI,KAAK,sBAAsB;GAC5F,CAAC;GACD,IAAI,WAAW,KAAA,GAAW;GAC1B,IAAI,OAAO,SAAS,OAAO;IACzB,MAAM,OAAO,MAAM,YAAY,KAAK,cAAc,MAAM,QAAQ;IAChE,IAAI,SAAS,KAAA,GAAW;KACtB,QAAQ;KACR,eAAe;IACjB;GACF,OAAO;IACL,MAAM,OAAO,MAAM,gBAAgB,KAAK,cAAc,MAAM,QAAQ,QAAQ;IAC5E,IAAI,SAAS,KAAA,GAAW;KACtB,QAAQ;KACR,eAAe;IACjB;GACF;GAKA,MAAM,CAAC,eAAe,eAAe,MAAM,QAAQ,IAAI,CACrD,IAAI,IAAI,SAAS,CAAC,CAAC,YAAY,KAAA,CAAS,GACxC,IAAI,IAAI,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS,CACxC,CAAC;GACD,IAAI,kBAAkB,KAAA,GAAW;IAC/B,QAAQ;IACR,eAAe;GACjB;GACA,IAAI,gBAAgB,KAAA,GAAW,aAAa;EAC9C;CACF;AACF;AAEA,eAAe,YACb,KACA,UACA,MACA,UACiC;CACjC,MAAM,SAAS,IAAI,OAAO;CAC1B,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;EACjC,OAAO;EACP,aAAa;EACb,SAAS,mBAAmB,MAAM;CACpC,CAAC;CACD,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,MAAM,WAAW,KAAK;CACtB,IAAI;CACJ,IAAI,SAAS,SAAS,GAAG;EACvB,MAAM,SAAS,MAAM,IAAI,KAAK,OAAO;GACnC,OAAO,YAAY,KAAK,WAAW,GAAG,KAAK;GAC3C,SAAS,eAAe,QAAQ;EAClC,CAAC;EACD,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,UAAU,OAAO;CACnB;CACA,MAAM,MACJ,YAAY,KAAA,IACR;EAAE,YAAY,KAAK;EAAY,IAAI,KAAK;CAAQ,IAChD;EAAE,YAAY,KAAK;EAAY,IAAI,KAAK;EAAS;CAAQ;CAC/D,MAAM,OAAO,CAAC,GAAG,SAAS,MAAM,OAAO,GAAG;CAC1C,OAAO,cAAc,KAAK,EAAE,OAAO;EAAE,GAAG,SAAS;GAAQ,OAAO;CAAK,EAAE,GAAG,QAAQ;AACpF;AAIA,SAAS,sBAA0D;CACjE,OAAO;EACL;GAAE,OAAO;GAAe,OAAO;GAAO,aAAa;EAAiC;EACpF;GAAE,OAAO;GAAW,OAAO;GAAM,aAAa;EAAkC;EAChF;GAAE,OAAO;GAAa,OAAO;GAAQ,aAAa;EAAiC;EACnF;GAAE,OAAO;GAAU,OAAO;EAAS;CACrC;AACF;AAEA,eAAe,gBACb,KACA,UACA,MACA,EAAE,OAAO,OACT,UACiC;CACjC,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;EACjC,OAAO,aAAa,cAAc,GAAG;EACrC,SAAS,oBAAoB;CAC/B,CAAC;CACD,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,IAAI,SAAS,UAAU;EAKrB,IAAI,MAJoB,IAAI,KAAK,QAAQ;GACvC,OAAO;GACP,SAAS,UAAU,cAAc,GAAG,EAAE,QAAQ,KAAK;EACrD,CAAC,MACiB,MAAM,OAAO,KAAA;EAC/B,OAAO,cACL,KACA,EAAE,OAAO;GAAE,GAAG,SAAS;IAAQ,OAAO,eAAe,SAAS,MAAM,OAAO,KAAK;EAAE,EAAE,GACpF,QACF;CACF;CACA,MAAM,OACJ,SAAS,QACL,kBAAkB,SAAS,MAAM,OAAO,KAAK,IAC7C,aAAa,SAAS,MAAM,OAAO,OAAO,SAAS,OAAO,KAAK,CAAC;CACtE,OAAO,cAAc,KAAK,EAAE,OAAO;EAAE,GAAG,SAAS;GAAQ,OAAO;CAAK,EAAE,GAAG,QAAQ;AACpF;AAIA,SAAS,WAAW,UAAiD;CACnE,MAAM,UAAqC,CACzC;EAAE,OAAO;EAAU,OAAO,EAAE,MAAM,QAAQ;EAAG,aAAa;CAAgB,CAC5E;CACA,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,SAAS,MAAM,OAC/B,QAAQ,KAAK;EACX,OAAO,GAAG,cAAc,GAAG,EAAE,IAAI,KAAK;EACtC,aAAa;EACb,OAAO;GAAE,MAAM;GAAO;EAAI;CAC5B,CAAC;CAGL,OAAO;AACT;AAEA,eAAe,WACb,KACA,UACA,UACiC;CAEjC,IAAI,CADe,MAAM,MAAM,SAAS,SAAS,MAAM,KAAK,CAAC,SAAS,CACxD,GAAG;EACf,MAAM,IAAI,KAAK,MAAM;GAAE,OAAO;GAAO,SAAS;EAAmC,CAAC;EAClF;CACF;CACA,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO;EAAE,OAAO;EAAO,SAAS,WAAW,QAAQ;CAAE,CAAC;CAClF,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,OAAO,cAAc,KAAK,EAAE,KAAK,KAAK,SAAS,UAAU,OAAO,KAAK,IAAI,GAAG,QAAQ;AACtF;AAEA,eAAe,gBAAgB,KAAiC;CAC9D,MAAM,MAAM,MAAM,OAAO,WAAW,IAAI,IAAI,SAAS,CAAC;CACtD,IAAI,QAAQ,KAAA,GAAW;CACvB,IAAI,IAAI,WAAW,GAAG;EACpB,MAAM,IAAI,KAAK,MAAM;GACnB,OAAO;GACP,SAAS;EACX,CAAC;EACD;CACF;CAKA,KAAK,IAAI,SAAS,KAAM;EACtB,MAAM,OAAO,YAAY,IAAI,MAAM,MAAM,CAAC;EAC1C,MAAM,UAAU,SAAA,KAA8B,IAAI;EAClD,MAAM,SAAS,MAAM,IAAI,KAAK,YAAY;GACxC,OAAO,aAAa,OAAO,IAAI,MAAM,EAAE;GACvC,SAAS,KAAK,KAAK,aAAa;IAAE,OAAO,YAAY,OAAO;IAAG,OAAO;GAAQ,EAAE;GAChF,SAAS,CACP,GAAI,SAAS,IAAI,CAAC;IAAE,OAAO;IAAiB,OAAO;IAAQ,MAAM;GAAS,CAAC,IAAI,CAAC,GAChF,GAAI,UAAU,CAAC;IAAE,OAAO;IAAa,OAAO;IAAQ,MAAM;GAAS,CAAC,IAAI,CAAC,CAC3E;EACF,CAAC;EACD,IAAI,OAAO,WAAW,QAAQ;GAC5B,UAAA;GACA;EACF;EACA,IAAI,OAAO,WAAW,QAAQ;GAC5B,SAAS,KAAK,IAAI,GAAG,SAAA,EAA2B;GAChD;EACF;EACA,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,IAAI,KAAK,MAAM;GACnB,OAAO,YAAY,OAAO,KAAK,EAAE;GACjC,SAAS,cAAc,MAAM,IAAI,IAAI;EACvC,CAAC;CACH;AACF;;;;;;;ACpnBA,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,MAAM,WAAuE;CAC3E,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;AACV;;AAGA,SAAgB,oBAAoB,SAA4D;CAC9F,OAAO,qBAAqB,QAAQ,YAAY;EAC9C,MAAM,QAAQ,SAAS;EACvB,OAAO,UAAU,KAAA,KAAa,UAAU,WAAW,KAAA;CACrD,CAAC;AACH;;AAGA,eAAsB,mBAAmB,KAAkB,OAA8B;CACvF,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC,QAAQ,QAAQ,GAAG;CAChD,MAAM,EAAE,aAAa,QAAQ,QAAQ,OAAO,WAAW,IAAI,WAAW,CAAC;CACvE,QAAQ,SAAR;EACE,KAAK;GACH,MAAM,YAAY,GAAG;GACrB;EACF,KAAK;GACH,MAAM,YAAY,KAAK,QAAQ;GAC/B;EACF,KAAK;GACH,MAAM,YAAY,KAAK,QAAQ;GAC/B;EACF,KAAK,OAAO;GACV,MAAM,UAAU,MAAM,IAAI,IAAI,SAAS,EAAA,CAAG,MACvC,YAAY,QAAQ,cAAc,IAAI,SACzC;GACA,MAAM,IAAI,KAAK,MAAM;IACnB,OAAO;IACP,SACE,WAAW,KAAA,IACP,+CACA,cAAc,QAAQ,IAAI,OAAO,IAAI,SAAS,KAAK,IAAA,CAAK,CAAC;GACjE,CAAC;GACD;EACF;EACA,KAAK;EACL,KAAK,eAAe;GAClB,MAAM,SAAS,MAAM,IAAI,IAAI,YAAY,EACvC,MAAM,YAAY,eAAe,YAAY,MAC/C,CAAC;GACD,IAAI,KAAK,MACP,OAAO,KACH,iEACA,OAAO,OAAO,KAAK,IAAI,GAC3B,OAAO,KAAK,YAAY,OAC1B;GACA;EACF;EACA,KAAK;GACH,IAAI,UAAU,KAAA,GAAW;GACzB,MAAM,MAAM;GACZ;EACF,KAAK;GACH,IAAI,gBAAgB,KAAA,GAAW;GAC/B,MAAM,eAAe,KAAK,WAAW;GACrC;EACF,KAAK;GACH,IAAI,WAAW,KAAA,GAAW;GAC1B,MAAM,WAAW,KAAK,MAAM;GAC5B;EACF,KAAK;GACH,IAAI,WAAW,KAAA,GAAW;GAC1B,MAAM,WAAW,KAAK,MAAM;GAC5B;EACF,KAAK;GACH,IAAI,WAAW,KAAA,GAAW;GAC1B,MAAM,UAAU,KAAK,MAAM;GAC3B;CACJ;CACA,IAAI,KAAK,MACP,kCAAkC,oBAAoB,IAAI,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,IAC9E,OACF;AACF;;AClFA,eAAsB,WACpB,MACA,KACA,SACe;CACf,IAAI,CAAC,IAAI,OAAO;EACd,IAAI,GAAG,OAAO,oDAAoD,SAAS;EAC3E;CACF;CACA,MAAM,mBAAmB,MAAM,QAAQ,IAAI,GAAG,GAAG,IAAI;AACvD;AAEA,SAAgB,iBACd,IACA,SACM;CACN,GAAG,gBAAgB,YAAY;EAC7B,aAAa;EACb,yBAAyB,WACvB,qBAAqB,QAAQ,YAAY,QAAQ,WAAW,MAAM,CAAC,CAAC,CAAC,KAAK,aAAa;GACrF,OAAO;GACP,OAAO;EACT,EAAE;EACJ,MAAM,QAAQ,MAAM,KAAK;GACvB,MAAM,IAAI,YAAY;GACtB,IAAI;IACF,MAAM,WAAW,MAAM,KAAK,OAAO;GACrC,QAAQ;IACN,IAAI,GAAG,OACL,2EACA,OACF;GACF;EACF;CACF,CAAC;CACD,GAAG,iBAAiB,cAAc;EAChC,aAAa;EACb,MAAM,QAAQ,KAAK;GACjB,IAAI,CAAC,IAAI,OAAO,GAAG;IACjB,IAAI,GAAG,OAAO,qDAAqD,MAAM;IACzE;GACF;GACA,IAAI;IACF,MAAM,WAAW,IAAI,KAAK,OAAO;GACnC,QAAQ;IACN,IAAI,GAAG,OACL,2EACA,OACF;GACF;EACF;CACF,CAAC;AACH;;;ACvDA,SAAgB,WAAW,SAAsC;CAC/D,MAAM,gBAAgB,OAAe,OAAO,QAAQ,aAAa,GAAG,KAAK,MAAM;CAC/E,OAAO;EACL,gBAAgB,aAAa,QAAQ,QAAQ;EAC7C,cAAc,UAAU,eAAe,QAAQ,UAAU,KAAK;EAC9D,QAAQ,QAAQ;EAChB,gBAAgB,aAAa,QAAQ,QAAQ;EAC7C,MAAM,YAAY,IAAI;GACpB,IAAI,CAAC,aAAa,EAAE,GAClB,MAAM,IAAI,MAAM,6DAA6D;GAC/E,MAAM,WAAW,MAAM,aAAa,QAAQ,QAAQ;GACpD,OAAO,QAAQ,MAAM,CAAC,EAAE,aAAa,aACjC,cAAc,QAAQ,MAAM,GAAG,SAAS,MAAM,QAAQ,OAAO,CAAC,IAC9D,oBAAoB,QAAQ,OAAO,CAAC;EAC1C;EACA,MAAM,eAAe,IAAI,MAAM;GAC7B,IAAI,CAAC,aAAa,EAAE,GAAG,OAAO;IAAE,IAAI;IAAO,QAAQ,CAAC,mBAAmB;GAAE;GACzE,IAAI,CAAC,QAAQ,KAAK,GAChB,OAAO;IAAE,IAAI;IAAO,QAAQ,CAAC,oDAAoD;GAAE;GACrF,MAAM,WAAW,MAAM,aAAa,QAAQ,QAAQ;GACpD,MAAM,OAAsB,QAAQ,SAAS;GAC7C,MAAM,WAAW,QAAQ,MAAM;GAC/B,IAAI;GACJ,IAAI,SAAS,UAAU,SAAS;IAAE,YAAY;IAAY,IAAI;GAAO;QAChE,IAAI,UAAU,aAAa,YAAY,SAAS,QAAQ,YAAY;GACzE,IAAI,SAAS,YAAY,UAAU,aAAa,cAAc,WAAW,KAAA,GACvE,OAAO;IACL,IAAI;IACJ,QAAQ,CAAC,6DAA6D;GACxE;GACF,IAAI,WAAW,KAAA,KAAa,CAAE,MAAM,QAAQ,YAAY,MAAM,GAC5D,OAAO;IACL,IAAI;IACJ,QAAQ,CAAC,uEAAuE;GAClF;GACF,QAAQ,OAAO,eAAe;IAAE,SAAS;IAAG;GAAK,CAAC;GAClD,OAAO,EAAE,IAAI,KAAK;EACpB;EACA,YAAY,IAAI;GACd,IAAI,CAAC,aAAa,EAAE,GAClB,OAAO,QAAQ,uBACb,IAAI,MAAM,6DAA6D,CACzE;GACF,OAAO,QAAQ,QAAQ,cAAc,QAAQ,OAAO,CAAC,CAAC;EACxD;EACA,eAAe,IAAI,MAAM;GACvB,IAAI,CAAC,aAAa,EAAE,GAAG,OAAO,QAAQ,QAAQ;IAAE,IAAI;IAAO,QAAQ,CAAC,mBAAmB;GAAE,CAAC;GAC1F,IAAI,SAAS,QAAQ,CAAC,WAAW,IAAI,GACnC,OAAO,QAAQ,QAAQ;IACrB,IAAI;IACJ,QAAQ,CAAC,2DAA2D;GACtE,CAAC;GACH,QAAQ,OAAO,eAAe;IAAE,SAAS;IAAG;GAAK,CAAC;GAClD,OAAO,QAAQ,QAAQ,EAAE,IAAI,KAAK,CAAC;EACrC;CACF;AACF;;AC/EA,SAAS,MAAM,SAAgE;CAC7E,IAAI,CAAC,kBAAkB,KAAK,OAAO,GAAG,OAAO,KAAA;CAC7C,MAAM,CAAC,OAAO,OAAO,SAAS,QAAQ,MAAM,GAAG;CAC/C,OAAO;EAAC,OAAO,KAAK;EAAG,OAAO,KAAK;EAAG,OAAO,KAAK;CAAC;AACrD;AAEA,SAAS,QACP,GACA,GACQ;CACR,KAAK,MAAM,SAAS;EAAC;EAAG;EAAG;CAAC,GAAY;EACtC,MAAM,aAAa,EAAE,SAAS,EAAE;EAChC,IAAI,eAAe,GAAG,OAAO;CAC/B;CACA,OAAO;AACT;AAEA,SAAgB,cACd,SACA,SACA,YACe;CACf,MAAM,SAAS,MAAM,OAAO;CAC5B,MAAM,QAAQ,MAAM,OAAO;CAC3B,MAAM,SAAS,eAAe,KAAA,IAAY,KAAA,IAAY,MAAM,UAAU;CACtE,IAAI,WAAW,KAAA,KAAa,UAAU,KAAA,GACpC,OAAO,CACL;EACE,OAAO;EACP,SAAS,MAAM,QAAQ;EACvB,QAAQ;CACV,CACF;CACF,IAAI,OAAO,OAAO,KAAK,QAAQ,QAAQ,KAAK,IAAI,GAC9C,OAAO,CACL;EACE,OAAO;EACP,SAAS,MAAM,QAAQ,6BAA6B,QAAQ;EAC5D,QAAQ;CACV,CACF;CACF,MAAM,SAAwB,CAC5B;EAAE,OAAO;EAAM,SAAS,MAAM,QAAQ,gBAAgB,QAAQ;CAAM,CACtE;CACA,IAAI,WAAW,KAAA,GACb,OAAO,KAAK;EACV,OAAO;EACP,SAAS;EACT,QAAQ;CACV,CAAC;MACE,IAAI,QAAQ,QAAQ,MAAM,IAAI,GACjC,OAAO,KAAK;EACV,OAAO;EACP,SAAS,MAAM,QAAQ,6BAA6B,OAAO,UAAU;EACrE,QAAQ;CACV,CAAC;MACE,OAAO,KAAK;EAAE,OAAO;EAAM,SAAS,6BAA6B,OAAO,UAAU;CAAI,CAAC;CAC5F,OAAO;AACT;;;ACnCA,eAAsB,aAAa,SAAgD;CACjF,MAAM,SAAS,cAAc,QAAQ,SAAS,QAAQ,SAAS,QAAQ,UAAU;CACjF,MAAM,UAAU,YAAY,QAAQ,OAAO,QAAQ,SAAS,KAAK,YAAY,EAAE,MAAM,KAAA,CAAS;CAC9F,OAAO,KACL,QAAQ,WAAW,IACf;EAAE,OAAO;EAAM,SAAS;CAAsC,IAC9D;EACE,OAAO;EACP,SAAS,4BAA4B,QAAQ,KAAK,IAAI;EACtD,QAAQ;CACV,CACN;CACA,IAAI;EACF,MAAM,WAAW,MAAM,QAAQ,SAAS;EACxC,MAAM,eAAe,MAAM,QAAQ,aAAa;EAChD,MAAM,eAAyB,CAAC;EAChC,MAAM,6BAAa,IAAI,IAAY;EACnC,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,SAAS,MAAM,OAAO;GACtC,MAAM,QAAQ,QAAQ,SAAS,KAAK,IAAI,YAAY,IAAI,EAAE;GAC1D,IAAI,UAAU,KAAA,GACZ,OAAO,KAAK;IACV,OAAO;IACP,SAAS,GAAG,cAAc,GAAG,EAAE,IAAI,KAAK;IACxC,QAAQ;GACV,CAAC;QACE,IAAI,CAAC,QAAQ,SAAS,kBAAkB,KAAK,GAChD,OAAO,KAAK;IACV,OAAO;IACP,SAAS,GAAG,cAAc,GAAG,EAAE,IAAI,KAAK;IACxC,QAAQ,cAAc,IAAI,WAAW;GACvC,CAAC;QACE,aAAa,KAAK,cAAc,GAAG,CAAC;GACzC,IACE,CAAC,aAAa,MACX,UAAU,MAAM,eAAe,IAAI,cAAc,MAAM,OAAO,IAAI,MAAM,MAAM,KACjF,GAEA,WAAW,IAAI,cAAc,GAAG,CAAC;EACrC;EAEF,IAAI,aAAa,SAAS,GACxB,OAAO,KAAK;GACV,OAAO;GACP,SAAS,8BAA8B,OAAO,aAAa,MAAM,EAAE,QAAQ,aAAa,WAAW,IAAI,UAAU;EACnH,CAAC;EACH,IAAI,WAAW,OAAO,GACpB,OAAO,KAAK;GACV,OAAO;GACP,SAAS,8BAA8B,CAAC,GAAG,UAAU,CAAC,CAAC,KAAK,IAAI;GAChE,QAAQ;EACV,CAAC;CACL,QAAQ;EACN,OAAO,KAAK;GACV,OAAO;GACP,SAAS;GACT,QACE;EACJ,CAAC;CACH;CACA,IAAI;EACF,MAAM,QAAQ,QAAQ;EACtB,OAAO,KAAK;GAAE,OAAO;GAAM,SAAS;EAAgD,CAAC;CACvF,QAAQ;EACN,OAAO,KAAK;GACV,OAAO;GACP,SAAS;GACT,QAAQ;EACV,CAAC;CACH;CACA,MAAM,SAAS,QAAQ,SAAS,OAAO;CACvC,MAAM,WAAW,OAAO,QACrB,UAAU,MAAM,QAAQ,gBAAgB,MAAM,aAAa,UAC9D;CACA,KAAK,MAAM,SAAS,UAClB,OAAO,KAAK;EACV,OAAO;EACP,SAAS,uBAAuB,MAAM,SAAS,GAAG,MAAM;EACxD,QAAQ;CACV,CAAC;CACH,KAAK,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,GAAG;EACrE,IAAI,aAAa,YAAY;EAC7B,IAAI,QAAQ,SAAS,4BAA4B,QAAQ,CAAC,EAAE,iBAAiB,KAAA,GAC3E,OAAO,KAAK;GACV,OAAO;GACP,SAAS,2BAA2B;GACpC,QACE;EACJ,CAAC;CACL;CACA,IAAI;EACF,OAAO,KAAK,GAAG,aAAa,MAAM,QAAQ,OAAO,CAAC,CAAC;CACrD,QAAQ;EACN,OAAO,KAAK;GACV,OAAO;GACP,SAAS;GACT,QACE;EACJ,CAAC;CACH;CACA,OAAO;AACT;;ACjHA,SAAS,SAAS,OAA8B;CAC9C,OAAO,KAAK,UAAU,CAAC,MAAM,IAAI,YAAY,MAAM,IAAI,EAAE,CAAC;AAC5D;AAEA,SAAS,KAAK,OAA8B;CAC1C,MAAM,MAAM,MAAM,YAAY,MAAM;CACpC,OAAO,OAAO,SAAS,GAAG,KAAK,MAAM,aAAa,KAAK,MAAM,cAAc,IAAI,MAAM;AACvF;AAEA,SAAS,MAAM,MAAqB,OAA8B;CAChE,MAAM,IAAI,KAAK,IAAI;CACnB,MAAM,IAAI,KAAK,KAAK;CACpB,IAAI,MAAM,GAAG,OAAO,IAAI,IAAI,KAAK;CACjC,MAAM,IAAI,SAAS,IAAI;CACvB,MAAM,IAAI,SAAS,KAAK;CACxB,IAAI,MAAM,GAAG,OAAO,IAAI,IAAI,KAAK;CACjC,OACE,OAAO,KAAK,SAAS,IAAI,OAAO,MAAM,SAAS,KAC/C,KAAK,gBAAgB,MAAM,iBAC3B,OAAO,KAAK,eAAe,SAAS,MAAM,CAAC,IAAI,OAAO,MAAM,eAAe,SAAS,MAAM,CAAC;AAE/F;;;AAIA,MAAM,oBAAoB;;AAG1B,SAAgB,aAAa,QAAuD;CAClF,MAAM,yBAAS,IAAI,IAA2B;CAC9C,KAAK,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,KAAK,GAAG,OAAO,IAAI,SAAS,KAAK,GAAG,KAAK;CAC9E,MAAM,UAAU,CAAC,GAAG,OAAO,OAAO,CAAC;CACnC,MAAM,QAAQ,KAAK,KAAK,QAAQ,SAAS,CAAC;CAC1C,MAAM,SAAS,KAAK,KAAM,QAAQ,SAAS,IAAK,CAAC;CACjD,MAAM,QAAQ,OAAiC,aAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,KAAK,WAAW;EAChD,YAAY,MAAM,IAAI;EACtB,IAAI,MAAM,IAAI;EACd,GAAI,YAAY,MAAM,aAAa,MAAM,eAAe,SAAS,MAAM,IACnE,EAAE,SAAS,OAAO,IAClB,CAAC;CACP,EAAE;CACJ,OAAO;EACL,OAAO,KAAK,QAAQ,MAAM,GAAG,KAAK,GAAG,KAAK;EAC1C,UAAU,KAAK,QAAQ,MAAM,OAAO,MAAM,GAAG,KAAK;EAClD,UAAU,KACR,QACG,MAAM,MAAM,CAAC,CACb,MACE,GAAG,MACF,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,SAAS,KACxC,EAAE,gBAAgB,EAAE,iBACpB,MAAM,GAAG,CAAC,CACd,GACF,IACF;CACF;AACF;;ACpBA,SAAgB,YAAY,OAOT;CACjB,MAAM,wBAAQ,IAAI,IAA4B;CAC9C,KAAK,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,cAAc,OAAO,GAAG,GAAG,MAAM;CAC9E,MAAM,QAAQ,CAAC;CACf,KAAK,MAAM,QAAQ,OACjB,MAAM,QAAQ,MAAM,SAAS,MAAM,KAAK,CAAC,KAAK,QAAQ;EACpD,MAAM,SAAS,MAAM,IAAI,mBAAmB,GAAG,CAAC;EAChD,MAAM,kBAAkB,MAAM,SAAS,mBAAmB,GAAG,MAAM;EACnE,OAAO;GACL;GACA,QAAQ,QAAQ,UAAU;GAC1B,SAAS,QAAQ,QAAQ,SAAS;GAClC,UAAU,QAAQ,WAAW,KAAA;GAC7B,aAAa,QAAQ,QAAQ,SAAS;GACtC,aAAa,oBAAoB,eAAe;GAChD,SAAS,iBAAiB,WAAW;EACvC;CACF,CAAC;CAEH,OAAO;EACL,MAAM,MAAM,SAAS;EACrB,KAAK,MAAM,SAAS;EACpB;EACA,QAAQ,MAAM;EACd,SAAS,MAAM;EACf,UAAU,MAAM;CAClB;AACF;;;;;;;AAQA,SAAS,oBAAoB,SAAgD;CAC3E,IAAI,SAAS,cAAc,KAAA,GAAW,OAAO,KAAK,MAAM,QAAQ,YAAY,GAAG;CAC/E,IAAI,SAAS,mBAAmB,KAAA,GAAW,OAAO,KAAK,OAAO,IAAI,QAAQ,kBAAkB,GAAG;CAC/F,OAAO;AACT;;;ACjFA,eAAsB,iBAAiB,KAAkB,SAA0C;CACjG,IAAI,QAAQ;CACZ,MAAM,YACJ;EACE,MAAM,IAAI;EACV,MAAM,IAAI;EACV,QAAQ,IAAI;EACZ,KAAK;GACH,GAAG,IAAI;GACP,gBAAgB,QAAQ,QAAQ,KAAK;GACrC,cAAc,UAAU;IACtB,QAAQ,gBAAgB;KAAE,GAAG;KAAO,GAAG;IAAM,CAAC;IAC9C,OAAO,QAAQ,QAAQ;KAAE,IAAI;KAAM,UAAU;IAAM,CAAC;GACtD;GACA,cACE,QAAQ,QACN,YAAY;IACV,UAAU;IACV,QAAQ,CAAC;IACT,UAAU,CAAC;IACX,QAAQ;IACR,SAAS,CAAC;IACV,UAAU;GACZ,CAAC,CACH;EACJ;CACF,GACA,QACF;CACA,OAAO;AACT;AAWA,eAAsB,cAAc,SAA2C;CAC7E,MAAM,UAAU,MAAM,QAAQ,IAAI,SAAS;CAC3C,IAAI,QAAQ,iBAAiB;CAE7B,IAAI,CAAC,QAAQ,OAAO;CACpB,IAAI,QAAQ;EACV,GAAG;EACH,MAAM;EACN,iBAAiB;EACjB,OAAO,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,CAAC,SAAS,CAAC,IACtD,QAAQ,QACR,aAAa,QAAQ,OAAO,CAAC;CACnC;CACA,SAAS;EACP,MAAM,UAAU,MAAM,KACnB,SACC,GAAG,KAAK,IAAI,MAAM,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,CAAC,KAAK,KAAK,KAAK,uBACpE,CAAC,CAAC,KAAK,IAAI;EACX,MAAM,SAAS,MAAM,QAAQ,KAAK,OAAO;GACvC,OAAO,0BAA0B,QAAQ;GACzC,SAAS;IACP;KAAE,OAAO;KAA4C,OAAO;IAAM;IAClE;KAAE,OAAO;KAAqC,OAAO;IAAO;IAC5D;KAAE,OAAO;KAAyB,OAAO;IAAO;IAChD;KAAE,OAAO;KAAW,OAAO;IAAQ;GACrC;EACF,CAAC;EACD,IAAI,WAAW,QAAQ;GACrB,QAAQ;IAAE,GAAI,MAAM,QAAQ,KAAK,KAAK;IAAI,MAAM;IAAW,iBAAiB;GAAK;GACjF;EACF;EACA,IAAI,WAAW,UAAU,WAAW,OAAO;GACzC,MAAM,QAAQ,IAAI,YAAY,EAAE,iBAAiB,KAAK,CAAC;GACvD;EACF;EAKA,IAAI,MAJoB,QAAQ,KAAK,QAAQ;GAC3C,OAAO;GACP,SAAS,GAAG,QAAQ;EACtB,CAAC,MACiB,MAAM;EACxB,MAAM,QAAQ,MAAM,QAAQ,IAAI,YAAY;GAC1C,OAAO,MAAM;GACb,MAAM;GACN,iBAAiB;EACnB,CAAC;EACD,IAAI,CAAC,MAAM,IAAI;GACb,MAAM,QAAQ,KAAK,MAAM;IAAE,OAAO;IAAwB,SAAS,MAAM,OAAO,KAAK,IAAI;GAAE,CAAC;GAC5F;EACF;EACA,QAAQ,KAAK,MAAM,eAAe,SAAS;EAC3C,IAAI,WAAW,SAAS,CAAE,MAAM,QAAQ,SAAS,GAC/C,QAAQ,KAAK,MACX,4EACA,OACF;EACF;CACF;AACF;;ACnGA,eAAsB,WAAW,MAAiD;CAChF,MAAM,MAAM,MAAM,KAAK,KAAK;CAC5B,IAAI,QAAQ,KAAA,GAAW,OAAO,CAAC;CAC/B,IAAI,EAAEC,SAAO,GAAG,KAAK,MAAM,QAAQ,IAAI,UAAU,MAAM,IAAI,UAAU,CAAC,SAAS,KAC7E,MAAM,IAAI,MAAM,8CAA8C;CAChE,MAAM,UAAU,IAAI,UAAU,CAAC,KAAK,UAAmB,YAAY,KAAK,CAAC;CACzE,IAAI,CAAC,kBAAkB,KAAK;EAAE,SAAS;EAAG;CAAQ,CAAC,GACjD,MAAM,IAAI,MAAM,8CAA8C;CAChE,OAAO,QAAQ,QAAQ,WAAW,CAAC,OAAO,OAAO;AACnD;AAWA,eAAsB,WAAW,SAAiD;CAChF,MAAM,CAAC,UAAU,QAAQ,UAAU,UAAU,MAAM,QAAQ,IAAI;EAC7D,QAAQ,SAAS;EACjB,iBAAiB,QAAQ,OAAO,IAAI;EACpC,aAAa,QAAQ,QAAQ;EAC7B,WAAW,QAAQ,MAAM;CAC3B,CAAC;CACD,MAAM,OAAO,MAAM,SAAS,SAAS,CAAC,GAAG,SAAS,MAAM,KAAK,CAAC;CAC9D,MAAM,WAAW,MAAM,aAAa,QAAQ,UAAU,IAAI;CAC1D,MAAM,WAAW,IAAI,uBACnB,QAAQ,OAAO,OACf,uBACA,QAAQ,OAAO,KACjB;CACA,SAAS,QAAQ,MAAM;CAGvB,MAAM,YAAY,KAAK,SAAS,QAAQ;EACtC,MAAM,MAAM;GACV,YAAY,IAAI;GAChB,SAAS,IAAI;GACb,GAAI,IAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,IAAI,QAAQ;EAChE;EACA,MAAM,aAAa,SAAS,SAAS,GAAG;EACxC,MAAM,SAAS,SAAS,UAAU,WAAW,SAAS,YAAY,WAAW,MAAM,GAAG;EACtF,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC;GAAE,GAAG;GAAQ;EAAI,CAAC;CACxD,CAAC;CACD,OAAO,YAAY;EACjB,UAAU;GAAE,GAAG;GAAU,MAAM,QAAQ,cAAc,SAAS,IAAI;EAAE;EACpE,QAAQ;EACR,UAAU,SAAS;EACnB,QAAQ,OAAO;EACf,SAAS,OAAO,KAAK,YAAY;GAC/B,WAAW,OAAO;GAClB,MAAM,OAAO;GACb,UAAU,OAAO;EACnB,EAAE;EACF,UAAU,SAAS;CACrB,CAAC;AACH;;;;;;ACrCA,SAAS,UAAU,MAAsB;CACvC,OAAO,OAAO;AAChB;;AAOA,SAAS,KAAK,OAA0B,OAAyB;CAC/D,OAAO,MAAM,SAAS,QAAQ;EAC5B,MAAM,OAAO,yBAAyB,GAAG;EACzC,MAAM,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK,UAAU,CAAC,CAAC,QAAQ,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;EACrF,MAAM,MAAM,IAAI,OAAO,MAAM;EAC7B,OAAO,iBAAiB,KAAK,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,QAAQ,MAAM,CAAC,CAAC,CAAC,KACtE,SAAS,GAAG,MAAM,MACrB;CACF,CAAC;AACH;;AAGA,SAAgB,OACd,OACA,SACA,SACA,QACA,MACA,SACW;CACX,IAAI,QAAQ;CACZ,IAAI,WAAW;CACf,MAAM,iBACJ,QAAQ,QAAQ,WACd,GAAG,OAAO,MAAM,GAAG,OAAO,eAAe,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,YAAY,CAAC,CAC1F;CACF,OAAO;EACL,OAAO,OAAO;GACZ,MAAM,OAAO,SAAS;GACtB,MAAM,WAAW,KAAK,MAAM,MAAM,IAAI,GAAG,KAAK;GAC9C,MAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,MAAM,IAAI,SAAS,SAAS,QAAQ,SAAS,CAAC;GAClF,MAAM,SAAS,KAAK,IAAI,GAAG,WAAW,QAAQ,CAAC;GAC/C,OAAO;IACL,GAAG;IACH,WAAW;IACX,GAAG,KACA,MAAM,QAAQ,SAAS,KAAK,CAAC,CAC7B,KACE,KAAK,UACJ,GAAG,SAAS,UAAU,WAAW,MAAM,IAAI,GAAG,IAAI,QAAQ,IAAI,gBAAgB,KAAA,IAAY,KAAK,MAAM,IAAI,eAC7G;IACF,GAAI,KAAK,WAAW,IAAI,CAAC,YAAY,IAAI,CAAC;IAC1C,GAAG,OAAO,KAAK,MAAM,EAAE,GAAG,KAAK,WAAW,IAAI,WAAW,UAAU;IACnE,GAAG,QAAQ,KAAK,WAAW,GAAG,OAAO,KAAK,IAAI,OAAO,OAAO;GAC9D,CAAC,CAAC,KAAK,SAAS,QAAQ,MAAM,KAAK,CAAC;EACtC;EACA,YAAY,MAAM;GAChB,MAAM,MAAM,SAAS,IAAI;GACzB,MAAM,SAAS,QAAQ,MAAM,cAAc,UAAU,SAAS,GAAG;GACjE,IAAI,WAAW,KAAA,GAAW;IACxB,KAAK;KAAE,QAAQ,KAAA;KAAW,QAAQ,OAAO;IAAM,CAAC;IAChD;GACF;GACA,IAAI,QAAQ,UAAU;IACpB,KAAK;KAAE,QAAQ,KAAA;KAAW,QAAQ,KAAA;IAAU,CAAC;IAC7C;GACF;GACA,MAAM,OAAO,SAAS;GACtB,IAAI,QAAQ,SAAS;IACnB,KAAK;KAAE,QAAQ,KAAK,SAAS,EAAE;KAAO,QAAQ,KAAA;IAAU,CAAC;IACzD;GACF;GACA,IAAI,QAAQ,MAAM,WAAW,KAAK,IAAI,GAAG,WAAW,CAAC;QAChD,IAAI,QAAQ,QAAQ,WAAW,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC,GAAG,WAAW,CAAC;QAClF,IAAI,QAAQ,aAAa;IAC5B,QAAQ,MAAM,MAAM,GAAG,EAAE;IACzB,WAAW;GACb,OAAO,IAAI,eAAe,KAAK,IAAI,GAAG;IACpC,QAAQ,GAAG,QAAQ,OAAO,MAAM,GAAG,GAAG;IACtC,WAAW;GACb;GACA,QAAQ;EACV;EACA,aAAa,CAEb;CACF;AACF;AAEA,SAAgB,OAAO,MAAgC;CACrD,eAAe,OACb,OACA,SACA,UAAqE,CAAC,GAC9C;EACxB,IAAI,KAAK,SAAS,OAChB,OAAO,KAAK,GAAG,QAAuB,KAAK,QAAQ,OAAO,SACxD,OAAO,OAAO,SAAS,SAAS,IAAI,SAAS,MAAM,YAAY;GAC7D,IAAI,cAAc;EACpB,CAAC,CACH;EACF,MAAM,SACJ,QAAQ,SAAS,KACb,MAAM,KAAK,GAAG,MAAM,OAAO,kDAAkD,IAC7E;EACN,IAAI,WAAW,KAAA,GAAW,OAAO;GAAE,QAAQ,KAAA;GAAW,QAAQ,KAAA;EAAU;EACxE,MAAM,UAAU,QAAQ,QAAQ,WAC9B,GAAG,OAAO,MAAM,GAAG,OAAO,eAAe,KAAK,YAAY,CAAC,CAAC,SAAS,OAAO,YAAY,CAAC,CAC3F;EACA,MAAM,SAAS,QAAQ,KACpB,QAAQ,UACP,GAAG,OAAO,QAAQ,CAAC,EAAE,IAAI,OAAO,QAAQ,OAAO,gBAAgB,KAAA,IAAY,KAAK,MAAM,OAAO,eACjG;EACA,MAAM,eAAe,QAAQ,KAAK,WAAW,GAAG,OAAO,KAAK,IAAI,OAAO,OAAO;EAC9E,MAAM,SAAS,MAAM,KAAK,GAAG,OAAO,OAAO,CAAC,GAAG,QAAQ,GAAG,YAAY,CAAC;EACvE,MAAM,QAAQ,WAAW,KAAA,IAAY,KAAK,OAAO,QAAQ,MAAM;EAC/D,MAAM,cAAc,WAAW,KAAA,IAAY,KAAK,aAAa,QAAQ,MAAM;EAC3E,OAAO;GAAE,QAAQ,QAAQ,MAAM,EAAE;GAAO,QAAQ,QAAQ,YAAY,EAAE;EAAM;CAC9E;CACA,eAAe,KACb,OACA,OACA,UAA6B,OACd;EACf,IAAI,KAAK,SAAS,OAAO;GACvB,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,IAAI,QAAQ,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;GAChE;EACF;EACA,MAAM,KAAK,GAAG,QAAmB,KAAK,QAAQ,OAAO,SAAS;GAC5D,IAAI,SAAS;GACb,IAAI,QAAQ,KAAK,IAAI,MAAM,QAAQ,QAAQ,MAAM;GACjD,MAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,IAAI,SAAS,IAAI,IAAI,CAAC;GAC1D,OAAO;IACL,OAAO,OAAO;KACZ,MAAM,QAAQ,KACZ,MAAM,MAAM,SAAS,aAAa,IAAI,IAAI,KAAK,IAAI,UAAU,OAC7D,KACF;KACA,QAAQ,MAAM;KACd,SAAS,KAAK,IAAI,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK,CAAC;KACpD,OAAO;MACL;MACA,GAAG,MAAM,MAAM,QAAQ,SAAS,KAAK;MACrC;KACF,CAAC,CAAC,KAAK,SAAS,QAAQ,MAAM,KAAK,CAAC;IACtC;IACA,YAAY,MAAM;KAChB,MAAM,MAAM,SAAS,IAAI;KACzB,IAAI,QAAQ,YAAY,QAAQ,SAAS;MACvC,KAAK,KAAA,CAAS;MACd;KACF;KACA,IAAI,QAAQ,MAAM,SAAS,KAAK,IAAI,GAAG,SAAS,CAAC;KACjD,IAAI,QAAQ,QAAQ,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,QAAQ,KAAK,GAAG,SAAS,CAAC;KAC5E,IAAI,cAAc;IACpB;IACA,aAAa,CAEb;GACF;EACF,CAAC;CACH;CACA,OAAO;EACL,QAAQ,OAAO,UAAU,MAAM,OAAO,KAAK,OAAO,KAAK,OAAO,EAAA,CAAG;EACjE,cAAc,SAAS,OAAO,KAAK,OAAO,KAAK,SAAS,KAAK,OAAO;EACpE,UAAU,SAAS,KAAK,GAAG,QAAQ,KAAK,OAAO,KAAK,OAAO;EAC3D,QAAQ,SAAS,KAAK,KAAK,OAAO,KAAK,QAAQ,MAAM,IAAI,CAAC;EAC1D,QAAQ,SAAS,KAAK,KAAK,OAAO,KAAK,OAAO,KAAK,YAAY;EAC/D,QAAQ,SAAS,YAAY;GAC3B,KAAK,GAAG,OAAO,SAAS,YAAY,UAAU,UAAU,MAAM;EAChE;CACF;AACF;;;AC3KA,SAAgB,gBACd,IACA,SACA,MACA,SACA,UACmD;CACnD,MAAM,SAAS,OAAO,KAAuB,QAAoC;EAC/E,MAAM,QAAQ,IAAI,cAAc,KAAK,IAAI,YAAY,IAAI,EAAE;EAC3D,OAAO,UAAU,KAAA,KAAc,MAAM,GAAG,SAAS,KAAK;CACxD;CACA,MAAM,eAAe,QAAgD;EACnE,MAAM,UAAU,IAAI,eAAe,aAAa;EAChD,MAAM,UAAU,YAA2B;GAGzC,IAAI,IAAI,eAAe,aAAa,MAAM,SAAS,MAAM,SAAS,GAAG,CAAC,CAAC;EACzE;EACA,MAAM,OAAO,OAAO,GAAG;EACvB,MAAM,eAAe,IAAI,eAAe,UAAU;EAClD,MAAM,UAAU,WAAW;GACzB,UAAU,KAAK;GACf,UAAU,QAAQ;GAClB,WAAW,IAAI,eAAe,aAAa;GAC3C;GACA,aAAa,IAAI;GACjB,mBAAmB;IACjB,MAAM,SAAS,OAAO,CAAC,CAAC,UACrB,UACC,MAAM,SAAS,kBAAkB,MAAM,aAAa,UACxD;IACA,OAAO,WAAW,KAAA,IACd,KAAA,IACA;KAAE,YAAY,OAAO;KAAU,IAAI,OAAO;IAAQ;GACxD;GACA,cAAc,QAAQ,OAAO,KAAK,GAAG;GACrC,SAAS,MAAM,SAAS;IACtB,GAAG,YAAY,MAAM,IAAI;GAC3B;GACA,YAAY,IAAI,OAAO;GACvB,cACE,WAAW;IACT,gBAAgB,aAAa,KAAK,QAAQ;IAC1C,QAAQ,QAAQ;IAChB,UAAU,QAAQ;IAClB,UAAU,QAAQ;IAClB,QAAQ,QAAQ,QAAQ;IACxB,gBAAgB,WAAW,cAAc,IAAI,OAAO,QAAQ,OAAO,CAAC;GACtE,CAAC;EACL,CAAC;EACD,MAAM,MAAM;GACV,GAAG;GACH,MAAM,YAAY,OAAkD;IAClE,MAAM,SAAS,MAAM,QAAQ,YAAY,KAAK;IAC9C,IAAI,OAAO,IAAI,MAAM,QAAQ;IAC7B,OAAO;GACT;GACA,MAAM,eAAe,GAAG,MAAiD;IACvE,MAAM,SAAS,MAAM,QAAQ,eAAe,GAAG,IAAI;IACnD,IAAI,OAAO,IAAI,MAAM,QAAQ;IAC7B,OAAO;GACT;EACF;EACA,MAAM,aAAa,YAAY;GAC7B,MAAM,WAAW,MAAM,aAAa,KAAK,QAAQ;GACjD,OAAO,MAAM,SAAS,SAAS,CAAC,GAAG,SAAS,MAAM,KAAK,CAAC;EAC1D;EACA,OAAO,QAAQ,QAAQ;GACrB,MAAM;GACN;GACA;GACA,cAAc,eAAe,wBAAwB,IAAI,aAAa,CAAC;GACvE,WAAW,IAAI,eAAe,aAAa;GAC3C,OAAO,QAAQ,QAAQ;GACvB,SAAS;IACP,cAAc,QAAQ,oBAAoB,QAAQ,OAAO,MAAM,GAAG;IAClE,cAAc,QAAQ,OAAO,GAAG;IAChC,cAAc,QAAQ,OAAO,GAAG;IAChC,OAAO,YAAY;KACjB,MAAM,kBACJ,MACA,KAAK,cACL,MAAM,WAAW,GACjB,MAAM,QAAQ,aAAa,CAC7B;IACF;IACA,cACE,aAAa;KACX,SAAS,KAAK;KACd,SAAS,KAAK;KACd,YAAY,KAAK;KACjB,UAAU,IAAI;KACd,gBAAgB,aAAa,KAAK,QAAQ;KAC1C,cAAc,QAAQ;KAEtB,eAAe,KAAK,SAAS,cAAc;MAAE,MAAM,KAAA;MAAW,QAAQ,KAAA;KAAU,EAAE;KAClF,QAAQ,IAAI;IACd,CAAC;IACH,mBAAmB,kBAAkB,MAAM,QAAQ,WAAW;IAC9D,gBACE,KAAK,MAAM;KAAE,OAAO;KAAiC,SAAS;IAAmB,CAAC;GACtF;EACF,CAAC;CACH;CACA,iBAAmC,IAAI,EAAE,KAAK,YAAY,CAAC;CAC3D,OAAO,EACL,MAAM,QAAQ,KAAK;EACjB,MAAM,MAAM,MAAM,YAAY,GAAG;EACjC,MAAM,cAAc;GAClB,OAAO,IAAI;GACX,KAAK;IACH,gBAAgB,aAAa,KAAK,QAAQ;IAC1C,cAAc,UAAU,eAAe,KAAK,UAAU,KAAK;GAC7D;GACA,MAAM,IAAI;GACV,cAAc,eAAe,wBAAwB,IAAI,aAAa,CAAC;GACvE,OAAO,UAAU,iBAAiB,KAAK,KAAK;GAC5C,gBAAgB,OAAO,KAAK;IAAE,YAAY;IAAY,IAAI;GAAO,CAAC;EACpE,CAAC;CACH,EACF;AACF;;AC9HA,SAAS,WAAW,OAA8B;CAChD,QAAQ,MAAM,MAAd;EACE,KAAK,WACH,OAAO,GAAG,MAAM,KAAK,KAAK,MAAM;EAClC,KAAK,cACH,OAAO,cAAc,MAAM,KAAK,KAAK,MAAM;EAC7C,KAAK,aACH,OAAO,aAAa,MAAM,KAAK,KAAK,MAAM;EAC5C,KAAK,aACH,OAAO,yBAAyB,MAAM;EACxC,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;CACX;AACF;AAEA,SAAS,aAAa,MAAsB;CAG1C,MAAM,OAAO,yBAAyB,IAAI,CAAC,CAAC,QAAQ,iBAAiB,GAAG;CACxE,OAAO,KAAK,UAAU,KAAK,OAAO,GAAG,KAAK,MAAM,GAAG,EAAE,EAAE;AACzD;;AAGA,SAAgB,mBAAmB;CACjC,IAAI,aAAa;CACjB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM,SAAS,IAAyB,SAAmC;EACzE,IAAI;GACF,IAAI,UAAU,YAAY,IAAI;EAChC,SAAS,OAAO;GACd,YAAY,UAAU,KAAK;EAC7B;CACF;CACA,MAAM,cAAoB;EACxB,cAAc;EACd,UAAU,KAAA;EACV,UAAU,KAAA;EACV,MAAM,OAAO,KAAA,CAAS;EACtB,QAAQ,KAAA;CACV;CAEA,OAAO;;EAEL;;EAEA,QAAiC,KAAQ;GACvC,MAAM,QAAQ;GACd,MAAM,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAA;GAChC,IAAI,WAAW;GACf,MAAM,eAAe;IACnB,QAAQ;IACR,MAAM,IAAI,WAAW,OAAO;GAC9B;GACA,MAAM,QAAQ,UAA+B;IAC3C,IAAI,UAAU,YAAY;IAC1B,IAAI,MAAM,SAAS,YAAY,WAAW;IAC1C,UAAU,aAAa,WAAW,KAAK,CAAC;IACxC,OAAO;GACT;GACA,MAAM,aAAa,KAAa,SAAmC;IACjE,IAAI,UAAU,YAAY;IAC1B,IAAI,QAAQ,YAAY;KACtB,IAAI,UAAU,KAAK,IAAI;KACvB;IACF;IAEA,UAAU;IACV,OAAO;GACT;GAcA,OAAO;IACL,SAZc,OAAO,iBACrB,EAAE,GAAG,IAAI,GACT;KACE,GAAG,OAAO,0BAA0B,GAAG;KACvC,GAAI,IAAI,OAAO,KAAA,IACX,CAAC,IACD,EACE,IAAI;MAAE,OAAO;OAAE,GAAG,IAAI;OAAI;MAAU;MAAG,YAAY;MAAM,cAAc;KAAK,EAC9E;IACN,CAGM;IACN,QAAc;KACZ,IAAI,UAAU,YAAY,MAAM;IAClC;IACA;;IAEA,WACE,OACA,MAKM;KACN,IAAI,UAAU,YAAY;KAC1B,UAAU,KAAA;KACV,IAAI,UAAU;MACZ,KAAK,EAAE,MAAM,WAAW,CAAC;MACzB;KACF;KACA,IAAI,OAA+C;KACnD,IAAI,KAAK,UAAU,KAAK,OAAO,YAAY,KAAK,GAAG,OAAO;UACrD,KAAK,KAAK,OAAO,eAAe,KAAK,GAAG,OAAO;KACpD,KAAK;MACH;MACA,MAAM,KAAK;MACX,OAAO,MAAM;KACf,CAAC;IACH;;IAEA;GACF;EACF;CACF;AACF;;ACrFA,SAAgB,iBAAiB,IAAU,SAA0B,MAAyB;CAC5F,MAAM,WAAW,iBAAiB,QAAQ,QAAQ;CAClD,MAAM,SAAS,iBAAiB;CAChC,MAAM,iBAAiB,QAA0B;EAC/C,MAAM,WAAW,OAAO,QAAQ,GAAG;EACnC,OAAO,YAA2B;GAChC,IAAI,CAAC,IAAI,OAAO;GAChB,IAAI;IACF,MAAM,UAAU,MAAM,QAAQ,SAAS;IACvC,MAAM,SAAS,IAAI,eAAe,UAAU;IAC5C,MAAM,KAAK,gBAAgB,IAAI,KAAK;IACpC,MAAM,OAAO,cAAc,IAAI,OAAO,QAAQ,MAAM,MAAM;IAC1D,MAAM,OAAO,OAAO,KAAA,KAAa,OAAO,SAAU,cAAc,MAAM,KAAK,aAAc;IACzF,IAAI,IAAI,UAAU,KAAA,KAAa,SAAS,OAAO,SAAS,MAAM;SACzD,IAAI,OAAO,KAAA,KAAa,SAAS,WAAW,SAAS,KAAK;KAAE,MAAM;KAAa;IAAK,CAAC;SACrF,IAAI,QAAQ,MAAM,KAAK,CAAC,WAAW,GAAG,SAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;GAC5E,SAAS,OAAO;IACd,SAAS,KAAK,EAAE,MAAM,WAAW,CAAC;IAClC,YAAY,UAAU,KAAK;GAC7B;EACF;CACF;CACA,MAAM,UAAuB,EAAE,MAAM,KAAA,EAAU;CAC/C,MAAM,aAA8B,EAAE,MAAM,KAAA,EAAU;;CAEtD,MAAM,iBAAiB,OACrB,MAOA,UACkB;EAClB,IAAI,KAAK,YAAY,KAAA,GAAW;EAChC,MAAM,UAAU,MAAM,cAAc,QAAQ,UAAU;GACpD,IAAI,QAAQ,OAAO,MAAM;GACzB,WAAW,KAAK;GAChB,QAAQ,KAAK;GACb,MAAM,KAAK;GACX,UAAU,KAAK;EACjB,CAAC;EACD,IAAI,KAAK,SAAS,SAAS,SACzB,WAAW,OAAO;GAChB,MAAM,KAAK;GACX,SAAS,KAAK;GACd,UAAU,MAAM;GAChB,OAAO,MAAM;EACf;EACF,MAAM,EAAE,cAAc,MAAM,gBAAgB,QAAQ,WAAW;EAC/D,IAAI,CAAC,gBAAgB,WAAW,KAAK,UAAU,QAAQ,IAAI,GAAG;EAM9D,WAAW,IAAI;GAJb,SAAS;GACT,MAAM,aAAa,KAAK,UAAU,KAAK,MAAM,KAAK,KAAK;GACvD,WAAW,QAAQ;EAEN,CAAI;EACnB,QAAQ,OAAO,KAAK;CACtB;CACA,gBAAgB,EAAE;CAClB,MAAM,WAAW,OAAO,UAA8D;EACpF,IAAI;GACF,MAAM,EAAE,cAAc,MAAM,gBAAgB,QAAQ,WAAW;GAC/D,IAAI,cAAc,SAAS;GAC3B,WAAW,IAAI;IAAE,SAAS;IAAG,MAAM,WAAW,KAAK;GAAE,CAAC;GACtD,QAAQ,OAAO,KAAA;EACjB,SAAS,OAAO;GACd,YAAY,SAAS,KAAK;EAC5B;CACF;CACA,MAAM,UAAU,gBAAgB,IAAI,SAAS,OAAO;CACpD,MAAM,UAAU,gBACd,IACA,SACA,MACA;EACE,SAAS,QAAQ,QAAQ,OAAO,OAAO,QAAQ,GAAG,CAAC,CAAC,OAAO;EAC3D,SAAS,QAAQ,QAAQ,OAAO,OAAO,QAAQ,GAAG,CAAC,CAAC,OAAO;CAC7D,GACA,aACF;CACA,GAAG,GAAG,SAAS,OAAO,OAAO,QAAQ;EACnC,MAAM,WAAW,OAAO,QAAQ,GAAG;EACnC,MAAM,SAAS,MAAM,QAAQ,MAAM,OAAO,SAAS,OAAO;EAC1D,IAAI,OAAO,WAAW,WAAW,OAAO;EACxC,OAAO,aAAa,IAAI,SAAS,eAAe,SAAS,IAAI,CAAC,CAAC,OAAO,GAAG;CAC3E,CAAC;CACD,GAAG,GAAG,gBAAgB,OAAO,OAAO,QAAQ;EAC1C,OAAO,MAAM;EACb,MAAM,WAAW,OAAO,QAAQ,GAAG;EACnC,MAAM,UAAU,cAAc,GAAG;EACjC,IAAI,gBAAgB,MAAM,KAAK,MAAM,KAAA,GAAW;GAC9C,SAAS,MAAM;GAEf,IAAI,gBAAgB,MAAM,aAAa,MAAM,KAAA,GAAW,MAAM,SAAS,MAAM,KAAK;EACpF;EACA,MAAM,QAAQ,YAAY,MAAM,OAAO,SAAS,OAAO;EACvD,MAAM,QAAQ;CAChB,CAAC;CACD,GAAG,GAAG,iBAAiB,OAAO,QAAQ,QAAQ;EAC5C,OAAO,MAAM;EACb,MAAM,WAAW,OAAO,QAAQ,GAAG;EACnC,MAAM,UAAU,cAAc,GAAG;EACjC,SAAS,MAAM;EACf,QAAQ,OAAO,KAAA;EACf,MAAM,QAAQ;EACd,MAAM,QAAQ,aAAa,SAAS,OAAO;EAC3C,IAAI;GACF,MAAM,QAAQ,QAAQ,GAAG;EAC3B,SAAS,OAAO;GACd,YAAY,cAAc,KAAK;EACjC;CACF,CAAC;CACD,GAAG,GAAG,gBAAgB,OAAO,QAAQ,QAAQ;EAC3C,OAAO,MAAM;EACb,MAAM,cAAc,GAAG,CAAC,CAAC;CAC3B,CAAC;CAID,IAAI,UAAyB,QAAQ,QAAQ;CAC7C,GAAG,GAAG,oBAAoB,YAAY;EACpC,OAAO,MAAM;EACb,QAAQ,SAAS;EACjB,MAAM;CACR,CAAC;CACD,KAAK,MAAM,cAAc,cACvB,eACM,GAAG,eAAe,GACxB,UACC,OAAO,SAAS;EACf,SAAS,SAAS,MAAM,QAAQ;EAChC,UAAU,QAAQ,WAChB,eAAe,MAAM,KAAK,CAAC,CAAC,OAAO,UAAmB;GACpD,YAAY,YAAY,KAAK;EAC/B,CAAC,CACH;CACF,IACC,QAAQ,OAAO,QAAQ,GAAG,CAC7B,GACE,GAAG,qBAAqB,UAAU;CACpC,GAAG,aAAa,SAAS,QAAQ,QAAQ,CAAC;CAC1C,GAAG,aACD,eACE,QAAQ,UACR,aAAa,MAAM,gBAAgB,QAAQ,WAAW,EAAA,CAAG,kBAC3D,CACF;CACA,GAAG,GAAG,eAAe,OAAO,OAAO,QAAQ;EACzC,IAAI,MAAM,QAAQ,SAAS,aAAa,SAAS,MAAM;EACvD,MAAM;EACN,MAAM,cAAc,MAAM,SAAS,KAAK,SAAS,UAAU;CAC7D,CAAC;CACD,GAAG,GAAG,4BAA4B,UAAU,SAAS,SAAS,MAAM,OAAO,CAAC;CAC5E,GAAG,GAAG,kBAAkB,OAAO,QAAQ;EACrC,SAAS,MAAM;EACf,MAAM,WAAW,OAAO,QAAQ,GAAG;EACnC,OAAO,SACL,OACA,KACA,UACC,YAAY;GACX,GAAG,YAAY,SAAS,EAAE,aAAa,KAAK,CAAC;EAC/C,IACC,aAAa,QAAQ,QAAQ,UAAU,SAAS,OAAO,IACvD,SAAS,QAAQ,YAAY,MAAM,SAAS,OAAO,CACtD;CACF,CAAC;AACH;;AA4BA,eAAsB,cACpB,SACA,KACA,SACA,aAA8B,EAAE,MAAM,KAAA,EAAU,GACjC;CACf,MAAM,EAAE,UAAU,OAAO,eAAe;CACxC,IACE,QAAQ,SAAS,eACjB,aAAa,KAAA,KACb,aAAa,cACb,UAAU,KAAA,KACV,eAAe,KAAA,GAEf;CACF,IAAI;EACF,MAAM,WAAW,MAAM,QAAQ,SAAS;EAExC,IAAI,cAAc,IAAI,OAAO,SAAS,MAAM,IAAI,eAAe,UAAU,CAAC,MAAM,OAAO;EACvF,MAAM,iBAAiB,MAAM,WAAW,QAAQ,SAAS,aACvD,eACE,UACA;GAAE,YAAY;GAAU,IAAI;EAAM,GAClC;GAAE;GAAY,cAAc,QAAQ;EAAa,CACnD,CACF;EACA,MAAM,OAAO,WAAW;EACxB,IAAI,SAAS,KAAA,GAAW;EACxB,IAAI,KAAK,aAAa,YAAY,KAAK,UAAU,OAAO;EACxD,IAAI,UAA0B,EAAE,QAAQ,YAAY;EACpD,IAAI,eAAe,WAAW,UAAU;GAAE,QAAQ;GAAe,QAAQ;EAAO;OAC3E,IAAI,eAAe,WAAW,mBAAmB,KAAA,GACpD,UAAU;GAAE,QAAQ;GAAU,UAAU,eAAe;EAAS;EAClE,MAAM,qBACJ,QAAQ,UACR;GAAE,WAAW,KAAK;GAAS,QAAQ,KAAK;EAAK,GAC7C,OACF;CACF,SAAS,OAAO;EACd,YAAY,UAAU,KAAK;CAC7B;AACF;AASA,SAAS,eAAe,UAAoB,WAA4B;CACtE,IAAI,WAAW,OAAO,2DAA2D,SAAS,KAAK;CAC/F,MAAM,SAAS,SAAS,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI;CAC5D,OAAO,WAAW,KACd,+CAA+C,SAAS,KAAK,KAC7D,aAAa,OAAO,iCAAiC,SAAS,KAAK;AACzE;;AAGA,eAAsB,SACpB,OACA,KACA,SACA,MACA,MAEA,OACe;CACf,MAAM,KAAK,gBAAgB,IAAI,KAAK;CACpC,IAAI,MAAM,WAAW,OAAO,KAAA,GAAW;CACvC,IAAI;EACF,MAAM,WAAW,MAAM,QAAQ,SAAS;EACxC,MAAM,SAAS,IAAI,eAAe,UAAU;EAC5C,MAAM,QAAQ;GACZ;GACA,qBAAqB,MAAM,gBAAgB,QAAQ,WAAW,EAAA,CAAG;GACjE,UAAU;IAAE,GAAG;IAAU,MAAM,cAAc,IAAI,OAAO,SAAS,MAAM,MAAM;GAAE;GAC/E;GACA,WAAW,SAAS,IAAI,aAAa,CAAC,CAAC,KAAK,WAAW;IACrD,YAAY,MAAM;IAClB,IAAI,MAAM;GACZ,EAAE;GACF,MAAM;GACN,OAAO,QAAQ;EACjB;EACA,MAAM,aAAa,mBAAmB,KAAK;EAC3C,MAAM,WAAW,cAAc,gBAAgB,KAAK;EACpD,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,UAAU,gBAAgB,KAAK;GACrC,IAAI,YAAY,KAAA,GAAW;IACzB,MAAM,OAAO,OAAO;IACpB;GACF;GAKA,MAAM,OAAO,WAAW,KAAK;GAC7B,IAAI,SAAS,KAAA,GAAW,MAAM,QAAQ,IAAI;GAC1C;EACF;EACA,IAAI,MAAM,OAAO,QAAQ,GAAG;EAC5B,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,eAAe,UAAU,eAAe,KAAA,CAAS,CAAC;EAC/E,KAAK;GACH,YAAY;GACZ,SAAS;GACT,SAAS;GACT,SAAS;EACX,CAAC;CACH,SAAS,OAAO;EACd,YAAY,cAAc,KAAK;CACjC;AACF;;;;;;;;;;;;ACvWA,MAAM,gBAAgB;AAEtB,MAAM,kBAAkB;AACxB,MAAM,gBAAgB;AAsBtB,SAAS,UAAU,OAAyB;CAC1C,OAAO,QAAQ,IAAI,OAAO,KAAK,GAAG,MAAM;AAC1C;AAEA,eAAe,MAAM,MAAgC;CACnD,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,SAAS,MAAM,MAAM;CACpC,SAAS,OAAO;EACd,IAAI,UAAU,KAAK,MAAM,UACvB;EAEF,MAAM;CACR;CACA,IAAI;EAEF,OADuB,KAAK,MAAM,IACvB;CACb,QAAQ;EACN,MAAM,IAAI,MAAM,mBAAmB,KAAK,mBAAmB;CAC7D;AACF;AAEA,eAAe,QAAQ,MAAc,OAAoC;CACvE,MAAM,WAAW,MAAM,IAAI;CAC3B,SAAS;EACP,IAAI;GACF,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI;GACpC,MAAM,OAAO,UAAU,OAAO,QAAQ,GAAG,CAAC;GAC1C,MAAM,OAAO,MAAM;GACnB;EACF,SAAS,OAAO;GACd,IAAI,UAAU,KAAK,MAAM,UACvB,MAAM;EAEV;EAGA,MAAM,OAAO,MAAM,SAAS,MAAM,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EAC/D,MAAM,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,YAAY,KAAA,CAAS;EACnD,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,KAAa,MAAM,IAAI,KAAK,UAAU,eAAe;GAItF,IAAK,MAAM,SAAS,MAAM,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS,MAAO,MAC5D,MAAM,GAAG,MAAM,EAAE,OAAO,KAAK,CAAC;GAChC;EACF;EACA,IAAI,MAAM,KAAK,UACb,MAAM,IAAI,MAAM,mBAAmB,KAAK,+BAA+B;EAEzE,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,aAAa,CAAC;CACnE;AACF;AAEA,SAAgB,SACd,MACA,QAAsB,KAAK,KACK;CAChC,MAAM,OAAO,GAAG,KAAK;CACrB,OAAO;EACL,YAAY,MAAM,IAAI;EACtB,OAAO,QAAQ;GACb,OAAO,KAAK,aAAa,YAAY,QAAQ,QAAQ,OAAO,OAAO,CAAC,CAAC;EACvE;EACA,MAAM,YAAY,QAAQ;GACxB,MAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GAC9C,MAAM,QAAQ,MAAM,KAAK;GACzB,IAAI;IACF,MAAM,EAAE,MAAM,WAAW,MAAM,OAAO,MAAM,MAAM,IAAI,CAAC;IACvD,IAAI,SAAS,KAAA,GAAW;KACtB,MAAM,YAAY,GAAG,KAAK,GAAG,WAAW,EAAE;KAC1C,MAAM,UAAU,WAAW,GAAG,KAAK,UAAU,IAAI,EAAE,KAAK,EAAE,MAAM,IAAM,CAAC;KACvE,MAAM,OAAO,WAAW,IAAI;IAC9B;IACA,OAAO;GACT,UAAU;IACR,MAAM,GAAG,MAAM,EAAE,OAAO,KAAK,CAAC;GAChC;EACF;CACF;AACF;;ACvHA,MAAa,SAAkC,UAAU,UAAU;CACjE,MAAM,SAAS,WAAW,UAAU,KAAK;CACzC,aAAa;EACX,aAAa,MAAM;CACrB;AACF;;;;;;AGIA,SAAwB,SAAS,IAAkD;CACjF,MAAM,OAAO,KAAK,YAAY,GAAG,YAAY,eAAe;CAC5D,iBACE,IACA;EACE,OAAO;EACP,UAAU;GACR,MAAM,SAAS,KAAK,YAAY,GAAG,YAAY,eAAe,CAAC;GAC/D,OAAO,KAAK;EACd;EACA,SAAS;GACP,MAAM,SAAS,KAAK,YAAY,GAAG,YAAY,aAAa,CAAC;GAC7D,OAAO,KAAK;GACZ;EACF;EACA,QAAQ;GACN,MAAM,SAAS,KAAK,YAAY,GAAG,YAAY,aAAa,CAAC;GAC7D,OAAO,KAAK;GACZ,OAAO;EACT;EACA,UAAU,SAAS,KAAK,YAAY,GAAG,YAAY,eAAe,CAAC;EACnE,aAAa,SAAS,KAAK,YAAY,GAAG,YAAY,kBAAkB,CAAC;EACzE,UAAU,YAAY;GACpB,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,SAAS,MAAM,MAAM;GACpC,SAAS,OAAO;IACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,gBAAgB;IACzB,MAAM;GACR;GACA,IAAI;GACJ,IAAI;IACF,MAAM,KAAK,MAAM,IAAI;GACvB,QAAQ;IACN,MAAM,IAAI,MAAM,iCAAiC;GACnD;GACA,MAAM,SAAS,WAAW,gBAAgB,GAAG,GAAG;GAChD,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,MAAM,sBAAsB,OAAO,OAAO,KAAK,IAAI,GAAG;GAChF,OAAO,OAAO;EAChB;EACA,oBACE,qBAAqB,KAAK,YAAY,GAAG,YAAY,mBAAmB,IAAI,SAC1E,SAAS,MAAM,MAAM,CACvB;CACJ,GACA;EACE,UAAU,SAAS,IAAI;EACvB,cAAc,SAAS,KAAK,YAAY,GAAG,YAAY,mBAAmB,CAAC;EAC3E,SAAS;EACAC;EAEGC;CACd,CACF;AACF"}
|