@opengeni/worker-bundle 2.3.1 → 2.3.2-canary.37090756480001
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/dist/activities/agent-turn/claude-usage-observer.d.ts +30 -6
- package/dist/activities/agent-turn/credential-leases.d.ts +5 -32
- package/dist/activities/agent-turn/errors.d.ts +3 -0
- package/dist/activities/agent-turn/finalization-monitor.d.ts +1 -1
- package/dist/activities/agent-turn/finalization.d.ts +2 -0
- package/dist/activities/agent-turn/quiescence.d.ts +3 -4
- package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
- package/dist/activities/agent-turn/turn-context.d.ts +1 -1
- package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
- package/dist/activities/session-state.d.ts +2 -2
- package/dist/activities/types.d.ts +7 -0
- package/dist/{activities-control-3HAH4FMG.js → activities-control-3BY4IJKL.js} +166 -35
- package/dist/activities-control-3BY4IJKL.js.map +1 -0
- package/dist/activities-control.d.ts +6 -4
- package/dist/{activities-turn-KU25J3VQ.js → activities-turn-TTNAVGKN.js} +263 -308
- package/dist/activities-turn-TTNAVGKN.js.map +1 -0
- package/dist/activities.d.ts +6 -4
- package/dist/{chunk-3K3ULWEE.js → chunk-PA7Z55P4.js} +242 -17
- package/dist/chunk-PA7Z55P4.js.map +1 -0
- package/dist/{chunk-YG27NEMX.js → chunk-YOI3Z3GF.js} +9 -1
- package/dist/chunk-YOI3Z3GF.js.map +1 -0
- package/dist/http.d.ts +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +82 -16
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +6 -1
- package/dist/sandbox-resume.d.ts +3 -0
- package/dist/session-event-fanout.d.ts +6 -0
- package/dist/worker-service-lifecycle.d.ts +12 -0
- package/dist/workflow-bundle.js +3 -2
- package/package.json +21 -21
- package/src/activities/agent-turn/claim.ts +13 -0
- package/src/activities/agent-turn/claude-usage-observer.ts +99 -8
- package/src/activities/agent-turn/credential-leases.ts +86 -213
- package/src/activities/agent-turn/errors.ts +61 -1
- package/src/activities/agent-turn/failure-settlement.ts +59 -5
- package/src/activities/agent-turn/finalization-monitor.ts +3 -4
- package/src/activities/agent-turn/finalization.ts +8 -3
- package/src/activities/agent-turn/quiescence.ts +3 -4
- package/src/activities/agent-turn/run.ts +24 -20
- package/src/activities/agent-turn/sandbox-establish.ts +2 -0
- package/src/activities/agent-turn/sandbox-runtime.ts +5 -1
- package/src/activities/agent-turn/skill-selection.ts +2 -0
- package/src/activities/agent-turn/subscription-lease.ts +115 -0
- package/src/activities/agent-turn/turn-context.ts +1 -4
- package/src/activities/codex-rotation.ts +2 -12
- package/src/activities/model-call-fact-reconciler.ts +112 -0
- package/src/activities/sandbox-lease.ts +59 -8
- package/src/activities/session-state.ts +29 -4
- package/src/activities/types.ts +7 -0
- package/src/activities-control.ts +2 -0
- package/src/activities-turn.ts +5 -0
- package/src/activities.ts +7 -0
- package/src/http.ts +4 -2
- package/src/index.ts +39 -9
- package/src/observability-metrics.ts +27 -0
- package/src/sandbox-resume.ts +9 -0
- package/src/sandbox-routing.ts +77 -0
- package/src/session-event-fanout.ts +23 -0
- package/src/worker-service-lifecycle.ts +53 -0
- package/src/workflows/file-upload-reaper.ts +2 -0
- package/src/workflows/session.ts +6 -1
- package/dist/activities-control-3HAH4FMG.js.map +0 -1
- package/dist/activities-turn-KU25J3VQ.js.map +0 -1
- package/dist/chunk-3K3ULWEE.js.map +0 -1
- package/dist/chunk-YG27NEMX.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/observability-metrics.ts","../src/opensandbox-kubernetes-inventory.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { errorCodeToJSON } from \"@opengeni/agent-proto\";\nimport {\n BundledSkillId,\n CREDIT_GRANT_CLASSES,\n SandboxBackend,\n type SessionEventType,\n type SkillReadKind,\n type SkillUseSource,\n} from \"@opengeni/contracts\";\nimport {\n ACTIVE_USER_WINDOWS,\n type ActiveUserWindow,\n type CreditGrantTotals,\n type SessionEventAppendPhaseObservation,\n} from \"@opengeni/db\";\nimport {\n natsSubscriptionTerminationCounter,\n type EventBusOptions,\n type EventLogger,\n} from \"@opengeni/events\";\nimport type { Attributes, AttributeValue, Observability } from \"@opengeni/observability\";\nimport type { CompanyBrainContributionReceipt } from \"./model-context-contributions\";\nimport {\n OPENSANDBOX_BATCHSANDBOX_PHASES,\n OPENSANDBOX_WORKLOAD_POD_CONDITIONS,\n type OpenSandboxKubernetesInventory,\n} from \"./opensandbox-kubernetes-inventory\";\nimport {\n SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES,\n modelUsageTokenCountOrNull,\n type RuntimeMetricsHooks,\n type SelfhostedOpObservation,\n type SelfhostedOpObserver,\n type ToolPreparationPhaseMeasurement,\n} from \"@opengeni/runtime\";\n\nexport type TurnOutcome = \"completed\" | \"failed\" | \"cancelled\" | \"recovering\";\nexport type WorkerDeathRecoveryOutcome = \"recovering\" | \"exhausted\";\nexport type CreditMicrosKind = \"usage\" | \"grant\" | \"topup\" | \"refund\";\nexport type SandboxLeaseLiveness = \"cold\" | \"warming\" | \"warm\" | \"draining\";\nexport type CreditBalanceGauge = { accountId: string; balanceMicros: number };\nexport type TurnTaskQueueStats = {\n /** Temporal activity tasks ready for a turn worker to accept. */\n eligibleBacklog: number;\n oldestBacklogAgeSeconds: number;\n tasksAddRate: number;\n tasksDispatchRate: number;\n};\nexport type SessionRecoveryBacklog = {\n quiescence_missing: number;\n projection_stale: number;\n};\nexport type ContextCompactionPendingSummary = {\n pendingCount: number;\n oldestStartedAt: Date | null;\n};\n\nexport type TemporalTurnTaskQueueStats = {\n approximateBacklogCount?: unknown;\n approximateBacklogAge?: {\n seconds?: unknown;\n nanos?: unknown;\n } | null;\n tasksAddRate?: unknown;\n tasksDispatchRate?: unknown;\n} | null;\n\nconst turnTrackers = new WeakMap<Observability, TurnLifecycleMetrics>();\nconst modelRequestTrackers = new WeakMap<Observability, ModelRequestLifecycleMetrics>();\nconst creditBalanceGaugeAccounts = new WeakMap<Observability, Set<string>>();\nconst modelCacheCounterTotals = new WeakMap<Observability, Map<string, number>>();\nconst initializedContextCompactionMetrics = new WeakSet<Observability>();\n\n// A worker process reaching one trillion tokens in one provider/cache counter is\n// already far outside an ordinary scrape lifetime. Refuse further increments\n// before floating-point precision can degrade; a restart resets both the\n// process-local Prometheus registry and this guard together.\nconst MAX_MODEL_CACHE_COUNTER_TOTAL = 1_000_000_000_000;\nconst TURN_OUTCOMES: readonly TurnOutcome[] = [\"completed\", \"failed\", \"cancelled\", \"recovering\"];\nconst WORKER_DEATH_RECOVERY_OUTCOMES: readonly WorkerDeathRecoveryOutcome[] = [\n \"recovering\",\n \"exhausted\",\n];\nconst WORKER_DEATH_TIMEOUT_TYPES = [\"heartbeat\", \"schedule_to_start\"] as const;\nconst CONTEXT_COMPACTION_TRIGGERS = [\"auto\", \"operator\", \"proactive\", \"overflow\"] as const;\n\nexport type ContextCompactionTrigger = (typeof CONTEXT_COMPACTION_TRIGGERS)[number];\n\nconst CONTEXT_COMPACTION_STARTS_METRIC = {\n name: \"opengeni_context_compaction_starts_total\",\n help: \"Total durable context compaction starts, by trigger.\",\n} as const;\nconst CONTEXT_COMPACTIONS_METRIC = {\n name: \"opengeni_context_compactions_total\",\n help: \"Total completed context compactions, by trigger.\",\n} as const;\n\n/** Logger plus the closed-label subscription-termination counter for NATS connections. */\nexport function observabilityEventBusOptions(\n observability: Observability,\n): Pick<EventBusOptions, \"logger\" | \"onSubscriptionTerminated\"> {\n return {\n logger: observabilityEventLogger(observability),\n onSubscriptionTerminated: natsSubscriptionTerminationCounter(observability),\n };\n}\n\nexport function observabilityEventLogger(observability: Observability): EventLogger {\n return {\n debug: (message, attributes) => observability.debug(message, eventAttributes(attributes)),\n warn: (message, attributes) => observability.warn(message, eventAttributes(attributes)),\n };\n}\n\nfunction eventAttributes(attributes: Record<string, unknown> | undefined): Attributes | undefined {\n if (!attributes) {\n return undefined;\n }\n const projected: Attributes = {};\n for (const [key, value] of Object.entries(attributes)) {\n projected[key] = eventAttributeValue(value);\n }\n return projected;\n}\n\nfunction eventAttributeValue(value: unknown): AttributeValue {\n if (\n value === null ||\n value === undefined ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport function runtimeMetricsHooksForObservability(\n observability: Observability,\n): RuntimeMetricsHooks {\n return {\n onModelCall: ({ provider, outcome, durationSeconds }) => {\n completedOperationSpan(observability, \"worker.model.call\", durationSeconds, {\n provider,\n outcome,\n });\n observability.incrementCounter({\n name: \"opengeni_model_calls_total\",\n help: \"Total model calls by provider and outcome.\",\n labels: { provider, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_model_call_duration_seconds\",\n help: \"Model call duration in seconds by provider.\",\n labels: { provider },\n value: durationSeconds,\n });\n },\n onSandboxCreate: ({ backend, imageSource, outcome, durationSeconds }) => {\n observability.incrementCounter({\n name: \"opengeni_sandbox_creates_total\",\n help: \"Total sandbox create attempts by backend and outcome.\",\n labels: { backend, image_source: imageSource, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_create_duration_seconds\",\n help: \"Sandbox create duration in seconds by backend.\",\n labels: { backend, image_source: imageSource },\n value: durationSeconds,\n });\n },\n onSandboxWarmingTimeout: ({ backend, stage }) => {\n observability.incrementCounter({\n name: \"opengeni_sandbox_warming_timeouts_total\",\n help: \"Total sandbox warming timeouts.\",\n labels: { backend, stage },\n });\n },\n onSandboxReadinessReplacement: ({ backend, outcome }) => {\n observability.incrementCounter({\n name: \"opengeni_sandbox_readiness_replacements_total\",\n help: \"Fresh sandbox command-readiness replacement decisions by backend and outcome.\",\n labels: { backend, outcome },\n });\n },\n onSandboxProviderApiThrottle: ({ backend, operation }) => {\n observability.incrementCounter({\n name: \"opengeni_sandbox_provider_api_throttles_total\",\n help: \"Total sandbox provider API throttle responses.\",\n labels: { backend, operation },\n });\n },\n onSandboxTtlRenewal: ({ backend, outcome }) => {\n observability.incrementCounter({\n name: \"opengeni_sandbox_ttl_renewals_total\",\n help: \"Total renewable sandbox provider TTL refresh attempts.\",\n labels: { backend, outcome },\n });\n },\n onOpenSandboxSignedEndpoint: ({ outcome, port }) => {\n observability.incrementCounter({\n name: \"opengeni_opensandbox_signed_endpoint_total\",\n help: \"OpenSandbox signed Channel B mint and host-fetch outcomes.\",\n labels: { outcome, port: String(port) },\n });\n },\n onWorkspaceCapture: ({ backend, outcome, durationSeconds }) => {\n if (!Number.isFinite(durationSeconds) || durationSeconds < 0) return;\n const safeBackend = SandboxBackend.safeParse(backend).success ? backend : \"unknown\";\n completedOperationSpan(observability, \"worker.workspace_capture\", durationSeconds, {\n backend: safeBackend,\n outcome,\n });\n observability.observeHistogram({\n name: \"opengeni_workspace_capture_duration_seconds\",\n help: \"Physical warm workspace capture and publication duration, including late settlement after caller timeout.\",\n labels: { backend: safeBackend, outcome },\n value: durationSeconds,\n });\n },\n onWorkspaceArchiveObject: ({ outcome, backend }) => {\n observability.incrementCounter({\n name: \"opengeni_workspace_archive_object_total\",\n help: \"Workspace archive object-storage put/delete outcomes.\",\n labels: { outcome, backend },\n });\n },\n onMcpToolCall: ({ outcome, durationSeconds }) => {\n completedOperationSpan(observability, \"worker.mcp.tool_call\", durationSeconds, { outcome });\n observability.incrementCounter({\n name: \"opengeni_mcp_tool_calls_total\",\n help: \"Total physical MCP tool calls by bounded structural outcome.\",\n labels: { outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_mcp_tool_call_duration_seconds\",\n help: \"MCP tool-call duration in seconds by bounded structural outcome.\",\n labels: { outcome },\n value: durationSeconds,\n });\n },\n onMcpLifecycle: ({ phase, policy, outcome, durationSeconds }) => {\n observability.incrementCounter({\n name: \"opengeni_mcp_lifecycle_operations_total\",\n help: \"Total physical MCP lifecycle operations by bounded phase, policy, and outcome.\",\n labels: { phase, policy, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_mcp_lifecycle_operation_duration_seconds\",\n help: \"MCP lifecycle operation duration in seconds by bounded phase, policy, and outcome.\",\n labels: { phase, policy, outcome },\n value: durationSeconds,\n });\n },\n onSandboxOp: ({ backend, op, outcome, code, healed, durationSeconds, replyBytes }) => {\n observability.incrementCounter({\n name: \"opengeni_machine_op_total\",\n help: \"Total Connected Machine control ops by op, outcome, and typed fault code.\",\n labels: { backend, op, outcome, code: code ?? \"\" },\n });\n observability.observeHistogram({\n name: \"opengeni_machine_op_duration_seconds\",\n help: \"Connected Machine control-op duration in seconds by op.\",\n labels: { backend, op },\n value: durationSeconds,\n });\n // The healed-fault leading indicator: an op that only succeeded after a retry\n // (a blip/backpressure the transport absorbed). The doctrine: healed faults are\n // the leading indicator of the next unhealed one, so they are always recorded.\n if (healed) {\n observability.incrementCounter({\n name: \"opengeni_machine_op_healed_total\",\n help: \"Connected Machine ops that succeeded only after ≥1 in-call retry.\",\n labels: { backend, op },\n });\n }\n // The payload-wall indicator (bytes known only on a PAYLOAD_TOO_LARGE fault today).\n if (replyBytes !== undefined) {\n observability.observeHistogram({\n name: \"opengeni_machine_op_reply_bytes\",\n help: \"Connected Machine control-op reply size in bytes (payload-wall indicator).\",\n labels: { backend, op },\n value: replyBytes,\n });\n }\n },\n };\n}\n\n/**\n * Adapt the runtime's transport-agnostic `SelfhostedOpObserver` to the metrics\n * hooks: map a completed-op observation onto `onSandboxOp`, converting the wire\n * `ErrorCode` to its stable enum-name string (a bounded metric label) and the\n * duration to seconds. Wired into the selfhosted session build so every Connected\n * Machine control op meters.\n */\nexport function selfhostedOpObserverForMetrics(hooks: RuntimeMetricsHooks): SelfhostedOpObserver {\n return (o) => {\n hooks.onSandboxOp?.({\n backend: \"selfhosted\",\n op: o.op,\n outcome: o.outcome,\n healed: o.healed,\n retries: o.retries,\n durationSeconds: o.durationMs / 1000,\n ...(o.code !== undefined ? { code: errorCodeToJSON(o.code) } : {}),\n ...(o.replyBytes !== undefined ? { replyBytes: o.replyBytes } : {}),\n });\n };\n}\n\n/** A session-scoped `machine.op.*` event mapped from a completed-op observation. */\nexport type MachineOpSessionEvent = {\n type: \"machine.op.failed\" | \"machine.op.recovered\";\n payload: {\n op: string;\n faultClass: string;\n attempts: number;\n machineId?: string;\n };\n};\n\n/** Map an observation to a `machine.op.*` session event, or null if it is not\n * eventable. `machine.op.failed` fires ONLY for infrastructure fault classes (a\n * semantic miss the model asked about is an outcome, not an infra fault);\n * `machine.op.recovered` fires for a healed op (success after ≥1 retry). */\nexport function machineOpSessionEventFor(o: SelfhostedOpObservation): MachineOpSessionEvent | null {\n if (\n o.outcome === \"failed\" &&\n o.faultClass &&\n SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES.has(o.faultClass)\n ) {\n return {\n type: \"machine.op.failed\",\n payload: {\n op: o.op,\n faultClass: o.faultClass,\n attempts: o.retries,\n ...(o.machineId ? { machineId: o.machineId } : {}),\n },\n };\n }\n if (o.outcome === \"ok\" && o.healed) {\n return {\n type: \"machine.op.recovered\",\n payload: {\n op: o.op,\n faultClass: o.faultClass ?? \"unknown\",\n attempts: o.retries,\n ...(o.machineId ? { machineId: o.machineId } : {}),\n },\n };\n }\n return null;\n}\n\n/**\n * The Connected Machine op observer wired into a turn: it meters EVERY op (the\n * metrics sink) and BUFFERS the eventable ops (infra failures + healed recoveries)\n * as `machine.op.*` session events. The observer is SYNC (fire-and-forget), so the\n * turn drains the buffer to durable session events at a known checkpoint (turn end),\n * awaited — never an unawaited DB write inside the Temporal activity.\n */\nexport function makeMachineOpObserver(hooks: RuntimeMetricsHooks): {\n observer: SelfhostedOpObserver;\n drainEvents(): MachineOpSessionEvent[];\n} {\n const meter = selfhostedOpObserverForMetrics(hooks);\n const buffered: MachineOpSessionEvent[] = [];\n return {\n observer: (o) => {\n meter(o);\n const event = machineOpSessionEventFor(o);\n if (event) {\n buffered.push(event);\n }\n },\n drainEvents: () => buffered.splice(0, buffered.length),\n };\n}\n\nexport function turnLifecycleMetricsFor(observability: Observability): TurnLifecycleMetrics {\n const existing = turnTrackers.get(observability);\n if (existing) {\n return existing;\n }\n const tracker = new TurnLifecycleMetrics(observability);\n turnTrackers.set(observability, tracker);\n return tracker;\n}\n\nexport function initializeWorkerOutcomeMetrics(observability: Observability): void {\n for (const outcome of TURN_OUTCOMES) {\n observability.incrementCounter({\n name: \"opengeni_turns_total\",\n help: \"Total agent turns by terminal outcome.\",\n labels: { outcome },\n amount: 0,\n });\n }\n for (const outcome of WORKER_DEATH_RECOVERY_OUTCOMES) {\n for (const timeoutType of WORKER_DEATH_TIMEOUT_TYPES) {\n observability.incrementCounter({\n name: \"opengeni_turn_worker_death_recoveries_total\",\n help: \"Total durable same-turn worker-death recovery outcomes.\",\n labels: { outcome, timeout_type: timeoutType },\n amount: 0,\n });\n }\n }\n}\n\n/**\n * Publish every bounded compaction lifecycle series before the first event.\n * The zero counters make the closed trigger catalog explicit before a scrape.\n * Alerting uses the separate durable control-worker projection below; these\n * process-local counters are lifecycle-rate diagnostics only.\n */\nexport function initializeContextCompactionMetrics(observability: Observability): void {\n if (initializedContextCompactionMetrics.has(observability)) return;\n for (const trigger of CONTEXT_COMPACTION_TRIGGERS) {\n observability.incrementCounter({\n ...CONTEXT_COMPACTION_STARTS_METRIC,\n labels: { trigger },\n amount: 0,\n });\n observability.incrementCounter({\n ...CONTEXT_COMPACTIONS_METRIC,\n labels: { trigger },\n amount: 0,\n });\n }\n initializedContextCompactionMetrics.add(observability);\n}\n\nexport function recordWorkerDeathRecoveryMetrics(\n observability: Observability,\n input: {\n outcome: WorkerDeathRecoveryOutcome;\n timeoutType: \"HEARTBEAT\" | \"SCHEDULE_TO_START\";\n },\n): void {\n const turnOutcome: TurnOutcome = input.outcome === \"exhausted\" ? \"failed\" : \"recovering\";\n observability.incrementCounter({\n name: \"opengeni_turn_worker_death_recoveries_total\",\n help: \"Total durable same-turn worker-death recovery outcomes.\",\n labels: {\n outcome: input.outcome,\n timeout_type: input.timeoutType.toLowerCase(),\n },\n });\n // The turn process that owned this attempt is gone, so its process-local\n // lifecycle tracker cannot publish the outcome. Record it from the fenced\n // control activity only after the durable recovery transaction wins.\n observability.incrementCounter({\n name: \"opengeni_turns_total\",\n help: \"Total agent turns by terminal outcome.\",\n labels: { outcome: turnOutcome },\n });\n}\n\nexport class TurnLifecycleMetrics {\n private readonly attempts = new Map<string, { startedAt: number; lastProgressAt: number }>();\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(\n private readonly observability: Observability,\n private readonly options: {\n now?: () => number;\n refreshIntervalMs?: number;\n } = {},\n ) {}\n\n start(input: { attemptId: string }): void {\n const now = this.now();\n this.attempts.set(input.attemptId, { startedAt: now, lastProgressAt: now });\n this.ensureTimer();\n this.refreshGauges();\n }\n\n progress(input: { attemptId: string }): void {\n const attempt = this.attempts.get(input.attemptId);\n if (!attempt) return;\n attempt.lastProgressAt = this.now();\n }\n\n finish(input: {\n attemptId: string;\n outcome: TurnOutcome | null;\n durationSeconds?: number;\n }): void {\n const startedAt = this.attempts.get(input.attemptId)?.startedAt;\n if (startedAt !== undefined) {\n this.attempts.delete(input.attemptId);\n }\n if (input.outcome) {\n const observedDuration =\n input.durationSeconds ??\n (startedAt === undefined ? 0 : Math.max(0, (this.now() - startedAt) / 1000));\n this.observability.incrementCounter({\n name: \"opengeni_turns_total\",\n help: \"Total agent turns by terminal outcome.\",\n labels: { outcome: input.outcome },\n });\n this.observability.observeHistogram({\n name: \"opengeni_turn_duration_seconds\",\n help: \"Agent turn duration in seconds by terminal outcome.\",\n labels: { outcome: input.outcome },\n value: observedDuration,\n });\n }\n this.refreshGauges();\n if (this.attempts.size === 0) {\n this.stopTimer();\n }\n }\n\n refreshGauges(): void {\n this.observability.setGauge({\n name: \"opengeni_turns_inflight\",\n help: \"Current number of in-flight physical agent-turn attempts in this worker process.\",\n value: this.attempts.size,\n });\n this.observability.setGauge({\n name: \"opengeni_turn_oldest_inflight_age_seconds\",\n help: \"Age in seconds of the oldest in-flight physical agent-turn attempt in this worker process.\",\n value: this.oldestInflightAgeSeconds(),\n });\n this.observability.setGauge({\n name: \"opengeni_turn_oldest_no_progress_age_seconds\",\n help: \"Seconds since durable progress for the least recently progressing in-flight physical agent-turn attempt.\",\n value: this.oldestNoProgressAgeSeconds(),\n });\n }\n\n stop(): void {\n this.attempts.clear();\n this.refreshGauges();\n this.stopTimer();\n }\n\n private oldestInflightAgeSeconds(): number {\n if (this.attempts.size === 0) {\n return 0;\n }\n let oldest = Number.POSITIVE_INFINITY;\n for (const { startedAt } of this.attempts.values()) {\n oldest = Math.min(oldest, startedAt);\n }\n return Math.max(0, (this.now() - oldest) / 1000);\n }\n\n private oldestNoProgressAgeSeconds(): number {\n if (this.attempts.size === 0) return 0;\n let leastRecentProgress = Number.POSITIVE_INFINITY;\n for (const { lastProgressAt } of this.attempts.values()) {\n leastRecentProgress = Math.min(leastRecentProgress, lastProgressAt);\n }\n return Math.max(0, (this.now() - leastRecentProgress) / 1000);\n }\n\n private ensureTimer(): void {\n if (this.timer) {\n return;\n }\n this.timer = setInterval(() => this.refreshGauges(), this.options.refreshIntervalMs ?? 15_000);\n this.timer.unref?.();\n }\n\n private stopTimer(): void {\n if (!this.timer) {\n return;\n }\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private now(): number {\n return this.options.now?.() ?? Date.now();\n }\n}\n\nexport function modelRequestLifecycleMetricsFor(\n observability: Observability,\n): ModelRequestLifecycleMetrics {\n const existing = modelRequestTrackers.get(observability);\n if (existing) return existing;\n const tracker = new ModelRequestLifecycleMetrics(observability);\n modelRequestTrackers.set(observability, tracker);\n return tracker;\n}\n\nexport class ModelRequestLifecycleMetrics {\n private readonly requests = new Map<\n string,\n { provider: string; startedAt: number; lastEventAt: number }\n >();\n private readonly providers = new Set<string>();\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(\n private readonly observability: Observability,\n private readonly options: {\n now?: () => number;\n refreshIntervalMs?: number;\n } = {},\n ) {}\n\n start(key: string, provider: string): void {\n const now = this.now();\n this.providers.add(provider);\n this.requests.set(key, { provider, startedAt: now, lastEventAt: now });\n this.ensureTimer();\n this.refreshGauges();\n }\n\n event(key: string, interEventGapMs?: number): void {\n const request = this.requests.get(key);\n if (!request) return;\n request.lastEventAt = this.now();\n this.observability.incrementCounter({\n name: \"opengeni_model_request_stream_events_total\",\n help: \"Complete, valid provider SSE data events by provider.\",\n labels: { provider: request.provider },\n });\n if (interEventGapMs !== undefined) {\n this.observability.observeHistogram({\n name: \"opengeni_model_request_stream_event_gap_seconds\",\n help: \"Seconds between complete, valid provider SSE data events.\",\n buckets: MODEL_REQUEST_PHASE_BUCKETS,\n labels: { provider: request.provider },\n value: Math.max(0, interEventGapMs / 1000),\n });\n }\n }\n\n finish(key: string): void {\n this.requests.delete(key);\n this.refreshGauges();\n if (this.requests.size === 0) this.stopTimer();\n }\n\n refreshGauges(): void {\n const now = this.now();\n for (const provider of this.providers) {\n const active = [...this.requests.values()].filter((request) => request.provider === provider);\n this.observability.setGauge({\n name: \"opengeni_model_requests_inflight\",\n help: \"Current in-flight provider model requests in this worker process.\",\n labels: { provider },\n value: active.length,\n });\n this.observability.setGauge({\n name: \"opengeni_model_request_oldest_no_event_age_seconds\",\n help: \"Seconds since the least recently progressing in-flight provider request received a valid SSE event.\",\n labels: { provider },\n value:\n active.length === 0\n ? 0\n : Math.max(0, (now - Math.min(...active.map((request) => request.lastEventAt))) / 1000),\n });\n }\n }\n\n stop(): void {\n this.requests.clear();\n this.refreshGauges();\n this.stopTimer();\n }\n\n private ensureTimer(): void {\n if (this.timer) return;\n this.timer = setInterval(() => this.refreshGauges(), this.options.refreshIntervalMs ?? 15_000);\n this.timer.unref?.();\n }\n\n private stopTimer(): void {\n if (!this.timer) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private now(): number {\n return this.options.now?.() ?? Date.now();\n }\n}\n\nexport function recordTurnsQueuedGauge(observability: Observability, value: number): void {\n observability.setGauge({\n name: \"opengeni_turns_queued\",\n help: \"Current number of queued session turns.\",\n value,\n });\n}\n\n/**\n * Record the authoritative turn activity queue rather than aggregate Postgres\n * prompts. A paused human prompt is durable queue truth but is not runnable and\n * never reaches this Temporal task queue. DescribeTaskQueue's approximate\n * backlog count and age are explicitly documented by Temporal as autoscaling\n * signals.\n */\nexport function recordTurnTaskQueueStats(\n observability: Observability,\n stats: TurnTaskQueueStats,\n): void {\n observability.setGauge({\n name: \"opengeni_turn_eligible_backlog\",\n help: \"Temporal runAgentTurn activity tasks eligible for immediate worker admission.\",\n value: nonnegativeFinite(stats.eligibleBacklog),\n });\n observability.setGauge({\n name: \"opengeni_turn_eligible_backlog_oldest_age_seconds\",\n help: \"Approximate age of the oldest eligible runAgentTurn activity task.\",\n value: nonnegativeFinite(stats.oldestBacklogAgeSeconds),\n });\n observability.setGauge({\n name: \"opengeni_turn_eligible_tasks_add_rate\",\n help: \"Temporal runAgentTurn tasks added per second over its rolling window.\",\n value: nonnegativeFinite(stats.tasksAddRate),\n });\n observability.setGauge({\n name: \"opengeni_turn_eligible_tasks_dispatch_rate\",\n help: \"Temporal runAgentTurn tasks dispatched per second over its rolling window.\",\n value: nonnegativeFinite(stats.tasksDispatchRate),\n });\n}\n\nexport function normalizeTurnTaskQueueStats(\n stats: TemporalTurnTaskQueueStats | undefined,\n): TurnTaskQueueStats {\n if (!stats) {\n throw new Error(\"Temporal DescribeTaskQueue response omitted required stats\");\n }\n const eligibleBacklog = requiredTemporalNumber(\n stats.approximateBacklogCount,\n \"approximateBacklogCount\",\n { integer: true },\n );\n let oldestBacklogAgeSeconds = 0;\n if (stats.approximateBacklogAge) {\n const seconds = optionalTemporalNumber(\n stats.approximateBacklogAge.seconds,\n \"approximateBacklogAge.seconds\",\n { integer: true },\n );\n const nanos = optionalTemporalNumber(\n stats.approximateBacklogAge.nanos,\n \"approximateBacklogAge.nanos\",\n { integer: true },\n );\n if (nanos >= 1_000_000_000) {\n throw new Error(\"Temporal approximateBacklogAge.nanos must be less than one second\");\n }\n oldestBacklogAgeSeconds = seconds + nanos / 1_000_000_000;\n } else if (eligibleBacklog > 0) {\n throw new Error(\"Temporal stats omitted approximateBacklogAge for a nonzero backlog\");\n }\n return {\n eligibleBacklog,\n oldestBacklogAgeSeconds,\n tasksAddRate: optionalTemporalNumber(stats.tasksAddRate, \"tasksAddRate\"),\n tasksDispatchRate: optionalTemporalNumber(stats.tasksDispatchRate, \"tasksDispatchRate\"),\n };\n}\n\nexport function startTurnCapacityMonitor(input: {\n observability: Observability;\n read: () => Promise<TurnTaskQueueStats>;\n intervalMs?: number;\n now?: () => number;\n}): { close: () => Promise<void> } {\n const intervalMs = input.intervalMs ?? 15_000;\n const now = input.now ?? Date.now;\n const startedAt = now();\n let lastSuccessAt: number | null = null;\n let lastReadSucceeded = false;\n let stopped = false;\n let running: Promise<void> | null = null;\n const recordStatus = () => {\n const observedAt = now();\n const successAgeMs = observedAt - (lastSuccessAt ?? startedAt);\n const set = (name: string, help: string, value: number) =>\n input.observability.setGauge({ name, help, value });\n set(\n \"opengeni_turn_capacity_monitor_last_read_success\",\n \"Whether the latest Temporal turn-queue capacity read completed successfully.\",\n lastReadSucceeded ? 1 : 0,\n );\n set(\n \"opengeni_turn_capacity_monitor_last_success_timestamp_seconds\",\n \"Unix timestamp of the latest successful Temporal turn-queue capacity read, or zero before one succeeds.\",\n lastSuccessAt === null ? 0 : lastSuccessAt / 1_000,\n );\n set(\n \"opengeni_turn_capacity_monitor_last_success_age_seconds\",\n \"Age of the latest successful Temporal turn-queue capacity read, or monitor age before one succeeds.\",\n Math.max(0, successAgeMs / 1_000),\n );\n set(\n \"opengeni_turn_capacity_monitor_fresh\",\n \"Whether eligible-backlog gauges have a successful Temporal read within three monitor intervals.\",\n lastReadSucceeded && lastSuccessAt !== null && successAgeMs <= intervalMs * 3 ? 1 : 0,\n );\n };\n const refresh = () => {\n // Advance freshness age even while a Temporal read is hung. Old backlog\n // values remain observable for diagnosis but cease to be authoritative.\n recordStatus();\n if (stopped || running) return;\n running = input\n .read()\n .then((stats) => {\n recordTurnTaskQueueStats(input.observability, stats);\n lastSuccessAt = now();\n lastReadSucceeded = true;\n recordStatus();\n })\n .catch((error) => {\n lastReadSucceeded = false;\n recordStatus();\n input.observability.warn(\"turn capacity monitor: Temporal task-queue stats failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n })\n .finally(() => {\n running = null;\n });\n };\n refresh();\n const timer = setInterval(refresh, intervalMs);\n timer.unref?.();\n return {\n close: async () => {\n stopped = true;\n clearInterval(timer);\n await running;\n },\n };\n}\n\nexport function recordSessionRecoveryBacklogGauges(\n observability: Observability,\n counts: SessionRecoveryBacklog,\n): void {\n for (const state of [\"quiescence_missing\", \"projection_stale\"] as const) {\n observability.setGauge({\n name: \"opengeni_session_recovery_backlog\",\n help: \"Current durable recovering-session obligations with no active attempt, by bounded reconciliation state.\",\n labels: { state },\n value: nonnegativeFinite(counts[state]),\n });\n }\n}\n\nexport function startSessionRecoveryMonitor(input: {\n observability: Observability;\n read: () => Promise<SessionRecoveryBacklog>;\n intervalMs?: number;\n now?: () => number;\n}): { close: () => Promise<void> } {\n const intervalMs = input.intervalMs ?? 60_000;\n const now = input.now ?? Date.now;\n const startedAt = now();\n let lastSuccessAt: number | null = null;\n let lastReadSucceeded = false;\n let stopped = false;\n let running: Promise<void> | null = null;\n const recordStatus = () => {\n const observedAt = now();\n const successAgeMs = observedAt - (lastSuccessAt ?? startedAt);\n const set = (name: string, help: string, value: number) =>\n input.observability.setGauge({ name, help, value });\n set(\n \"opengeni_session_recovery_monitor_last_read_success\",\n \"Whether the latest durable session-recovery aggregate read completed successfully.\",\n lastReadSucceeded ? 1 : 0,\n );\n set(\n \"opengeni_session_recovery_monitor_last_success_timestamp_seconds\",\n \"Unix timestamp of the latest successful durable session-recovery aggregate read, or zero before one succeeds.\",\n lastSuccessAt === null ? 0 : lastSuccessAt / 1_000,\n );\n set(\n \"opengeni_session_recovery_monitor_fresh\",\n \"Whether durable session-recovery backlog gauges have a successful read within three monitor intervals.\",\n lastReadSucceeded && lastSuccessAt !== null && successAgeMs <= intervalMs * 3 ? 1 : 0,\n );\n };\n const refresh = () => {\n recordStatus();\n if (stopped || running) return;\n running = input\n .read()\n .then((counts) => {\n recordSessionRecoveryBacklogGauges(input.observability, counts);\n lastSuccessAt = now();\n lastReadSucceeded = true;\n recordStatus();\n })\n .catch((error) => {\n lastReadSucceeded = false;\n recordStatus();\n input.observability.warn(\"session recovery monitor: durable aggregate read failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n })\n .finally(() => {\n running = null;\n });\n };\n refresh();\n const timer = setInterval(refresh, intervalMs);\n timer.unref?.();\n return {\n close: async () => {\n stopped = true;\n clearInterval(timer);\n await running;\n },\n };\n}\n\nexport function recordContextCompactionPendingGauges(\n observability: Observability,\n summary: ContextCompactionPendingSummary,\n nowMs = Date.now(),\n): void {\n const oldestStartedAtMs = summary.oldestStartedAt?.getTime();\n const oldestPendingAgeSeconds =\n oldestStartedAtMs === undefined || !Number.isFinite(oldestStartedAtMs)\n ? 0\n : Math.max(0, (nowMs - oldestStartedAtMs) / 1_000);\n observability.setGauge({\n name: \"opengeni_context_compaction_pending\",\n help: \"Current exact active attempts whose latest automatic compaction landmark is still started.\",\n value: nonnegativeFinite(summary.pendingCount),\n });\n observability.setGauge({\n name: \"opengeni_context_compaction_oldest_pending_age_seconds\",\n help: \"Age in seconds of the oldest durably pending automatic compaction, or zero when none are pending.\",\n value: oldestPendingAgeSeconds,\n });\n}\n\nexport function startContextCompactionPendingMonitor(input: {\n observability: Observability;\n read: () => Promise<ContextCompactionPendingSummary>;\n intervalMs?: number;\n now?: () => number;\n}): { close: () => Promise<void> } {\n const intervalMs = input.intervalMs ?? 60_000;\n const now = input.now ?? Date.now;\n const startedAt = now();\n let lastSuccessAt: number | null = null;\n let lastReadSucceeded = false;\n let stopped = false;\n let running: Promise<void> | null = null;\n const recordStatus = () => {\n const observedAt = now();\n const successAgeMs = observedAt - (lastSuccessAt ?? startedAt);\n const set = (name: string, help: string, value: number) =>\n input.observability.setGauge({ name, help, value });\n set(\n \"opengeni_context_compaction_monitor_last_read_success\",\n \"Whether the latest durable context-compaction aggregate read completed successfully.\",\n lastReadSucceeded ? 1 : 0,\n );\n set(\n \"opengeni_context_compaction_monitor_last_success_timestamp_seconds\",\n \"Unix timestamp of the latest successful durable context-compaction aggregate read, or zero before one succeeds.\",\n lastSuccessAt === null ? 0 : lastSuccessAt / 1_000,\n );\n set(\n \"opengeni_context_compaction_monitor_fresh\",\n \"Whether durable context-compaction pending gauges have a successful read within three monitor intervals.\",\n lastReadSucceeded && lastSuccessAt !== null && successAgeMs <= intervalMs * 3 ? 1 : 0,\n );\n };\n const refresh = () => {\n recordStatus();\n if (stopped || running) return;\n running = input\n .read()\n .then((summary) => {\n recordContextCompactionPendingGauges(input.observability, summary, now());\n lastSuccessAt = now();\n lastReadSucceeded = true;\n recordStatus();\n })\n .catch((error) => {\n lastReadSucceeded = false;\n recordStatus();\n input.observability.warn(\"context compaction monitor: durable aggregate read failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n })\n .finally(() => {\n running = null;\n });\n };\n refresh();\n const timer = setInterval(refresh, intervalMs);\n timer.unref?.();\n return {\n close: async () => {\n stopped = true;\n clearInterval(timer);\n await running;\n },\n };\n}\n\nexport function recordSandboxLeaseGauges(\n observability: Observability,\n counts: Partial<Record<SandboxLeaseLiveness, number>>,\n): void {\n for (const liveness of [\"cold\", \"warming\", \"warm\", \"draining\"] as const) {\n observability.setGauge({\n name: \"opengeni_sandbox_leases\",\n help: \"Current sandbox leases by liveness state.\",\n labels: { liveness },\n value: counts[liveness] ?? 0,\n });\n }\n}\n\nexport function recordOpenSandboxKubernetesInventoryGauges(\n observability: Observability,\n inventory: OpenSandboxKubernetesInventory,\n): void {\n for (const phase of OPENSANDBOX_BATCHSANDBOX_PHASES) {\n observability.setGauge({\n name: \"opengeni_opensandbox_batchsandboxes\",\n help: \"Current OpenSandbox BatchSandboxes by bounded lifecycle phase.\",\n labels: { phase },\n value: inventory.batchSandboxPhases[phase],\n });\n }\n for (const condition of OPENSANDBOX_WORKLOAD_POD_CONDITIONS) {\n observability.setGauge({\n name: \"opengeni_opensandbox_workload_pods\",\n help: \"Current OpenSandbox workload Pods by bounded operational condition.\",\n labels: { condition },\n value: inventory.workloadPodConditions[condition],\n });\n }\n observability.setGauge({\n name: \"opengeni_opensandbox_cleanup_stuck\",\n help: \"Current OpenSandbox BatchSandboxes deleting past the cleanup threshold with finalizers.\",\n value: inventory.cleanupStuck,\n });\n observability.setGauge({\n name: \"opengeni_opensandbox_expiration_overdue\",\n help: \"Current OpenSandbox BatchSandboxes still present past the provider-expiry threshold.\",\n value: inventory.expirationOverdue,\n });\n}\n\nexport const SANDBOX_INVENTORY_PROJECTION_DOMAINS = [\n \"leases\",\n \"checkpoint_artifacts\",\n \"recovery_observations\",\n \"rotation_backlog\",\n \"retained_processes\",\n \"expired_drains\",\n \"opensandbox_kubernetes\",\n] as const;\n\nexport type SandboxInventoryProjectionDomain =\n (typeof SANDBOX_INVENTORY_PROJECTION_DOMAINS)[number];\n\nexport function recordSandboxInventoryProjectionSuccess(\n observability: Observability,\n domain: SandboxInventoryProjectionDomain,\n timestampSeconds = Date.now() / 1_000,\n): void {\n observability.setGauge({\n name: \"opengeni_sandbox_inventory_refresh_timestamp_seconds\",\n help: \"Unix timestamp of the last complete successful sandbox inventory projection by domain.\",\n labels: { domain },\n value: timestampSeconds,\n });\n}\n\nexport function recordSandboxInventoryProjectionFailure(\n observability: Observability,\n domain: SandboxInventoryProjectionDomain,\n): void {\n observability.incrementCounter({\n name: \"opengeni_sandbox_inventory_refresh_failures_total\",\n help: \"Failed sandbox inventory projection refreshes by domain.\",\n labels: { domain },\n });\n}\n\nexport function recordCreditBalanceGauges(\n observability: Observability,\n balances: CreditBalanceGauge[],\n): void {\n const previous = creditBalanceGaugeAccounts.get(observability) ?? new Set<string>();\n const current = new Set<string>();\n for (const balance of balances) {\n current.add(balance.accountId);\n observability.setGauge({\n name: \"opengeni_credit_balance_micros\",\n help: \"Current credit balance in micros by account.\",\n labels: { account_id: balance.accountId },\n value: balance.balanceMicros,\n });\n }\n for (const accountId of previous) {\n if (!current.has(accountId)) {\n observability.setGauge({\n name: \"opengeni_credit_balance_micros\",\n help: \"Current credit balance in micros by account.\",\n labels: { account_id: accountId },\n value: 0,\n });\n }\n }\n creditBalanceGaugeAccounts.set(observability, current);\n}\n\n/**\n * Distinct managed people with authenticated browser activity in each fixed\n * window (migration 0565 presence). Every control worker publishes the same\n * global value, so dashboards must aggregate with `max()` across pods, never\n * `sum()`. API keys, services and embedded hosts are never counted.\n */\nexport function recordActiveUserGauges(\n observability: Observability,\n counts: Record<ActiveUserWindow, number>,\n): void {\n for (const window of ACTIVE_USER_WINDOWS) {\n observability.setGauge({\n name: \"opengeni_active_users\",\n help: \"Distinct managed users with authenticated activity within the window (global; use max across pods).\",\n labels: { window },\n value: counts[window],\n });\n }\n}\n\n/**\n * Positive credit grants observed by the ledger trigger since migration 0565,\n * by closed class. These are cumulative database totals published as gauges by\n * every control worker: aggregate with `max()` across pods, then `increase()`.\n * Counting in the database covers the grants no application process writes:\n * the verified-signup trial grant (a setup trigger) and operator grants.\n */\nexport function recordCreditGrantGauges(\n observability: Observability,\n totals: CreditGrantTotals,\n): void {\n for (const grantClass of CREDIT_GRANT_CLASSES) {\n const total = totals[grantClass];\n observability.setGauge({\n name: \"opengeni_credit_grants_total\",\n help: \"Positive credit grants observed in the ledger since migration 0565, by grant class (global cumulative; use max across pods).\",\n labels: { grant_class: grantClass },\n value: total.count,\n });\n observability.setGauge({\n name: \"opengeni_credit_granted_micros_total\",\n help: \"Credit micros granted in the ledger since migration 0565, by grant class (global cumulative; use max across pods).\",\n labels: { grant_class: grantClass },\n value: total.micros,\n });\n }\n}\n\n/**\n * The deployment-level runtime switch for the one-time verified signup trial\n * credit (migration 0521): 1 while it allows grants, 0 when an operator has\n * disabled it or no revision exists. A grant also needs the API's\n * OPENGENI_VERIFIED_SIGNUP_TRIAL_CREDITS_ENABLED master opt-in, which\n * {@link recordVerifiedSignupTrialDeploymentFlagGauge} reports separately.\n */\nexport function recordVerifiedSignupTrialSwitchGauge(\n observability: Observability,\n grantsEnabled: boolean,\n): void {\n observability.setGauge({\n name: \"opengeni_verified_signup_trial_credits_runtime_enabled\",\n help: \"Whether the runtime switch allows new verified signup trial credit grants (1) or blocks them (0).\",\n value: grantsEnabled ? 1 : 0,\n });\n}\n\n/**\n * The OPENGENI_VERIFIED_SIGNUP_TRIAL_CREDITS_ENABLED master opt-in as this\n * worker's configuration sees it. The API reads the same shared setting; new\n * grants happen only while this gauge and the runtime switch gauge are both 1.\n */\nexport function recordVerifiedSignupTrialDeploymentFlagGauge(\n observability: Observability,\n enabled: boolean,\n): void {\n observability.setGauge({\n name: \"opengeni_verified_signup_trial_credits_deployment_enabled\",\n help: \"Whether the OPENGENI_VERIFIED_SIGNUP_TRIAL_CREDITS_ENABLED master opt-in is on (1) or off (0) in this deployment's configuration.\",\n value: enabled ? 1 : 0,\n });\n}\n\nexport function recordSandboxOrphansTerminated(observability: Observability, count: number): void {\n if (count <= 0) {\n return;\n }\n observability.incrementCounter({\n name: \"opengeni_sandbox_orphans_terminated_total\",\n help: \"Total provider-side orphan sandboxes terminated by defensive sweeps.\",\n amount: count,\n });\n}\n\nexport type SandboxCheckpointArtifactMetricState =\n | \"candidate\"\n | \"current\"\n | \"previous\"\n | \"delete_pending\"\n | \"deleting\"\n | \"delete_failed\"\n | \"deleted\";\n\nexport function recordSandboxCheckpointArtifactGauges(\n observability: Observability,\n counts: Record<SandboxCheckpointArtifactMetricState, number>,\n): void {\n for (const state of [\n \"candidate\",\n \"current\",\n \"previous\",\n \"delete_pending\",\n \"deleting\",\n \"delete_failed\",\n \"deleted\",\n ] as const) {\n observability.setGauge({\n name: \"opengeni_sandbox_checkpoint_artifacts\",\n help: \"Current durable provider checkpoint artifacts by lifecycle state.\",\n labels: { state },\n value: counts[state],\n });\n }\n}\n\nexport type SandboxCheckpointArtifactOutcome =\n | \"legacy_adopted\"\n | \"claimed\"\n | \"deleted\"\n | \"delete_failed\"\n | \"tombstone_pruned\";\n\nexport function recordSandboxCheckpointArtifactOutcome(\n observability: Observability,\n outcome: SandboxCheckpointArtifactOutcome,\n count = 1,\n): void {\n if (count <= 0) return;\n observability.incrementCounter({\n name: \"opengeni_sandbox_checkpoint_artifact_operations_total\",\n help: \"Durable provider checkpoint artifact operations by fixed outcome.\",\n labels: { outcome },\n amount: count,\n });\n}\n\nexport function recordSandboxDeadlineRotationsRequested(\n observability: Observability,\n count: number,\n): void {\n if (count <= 0) return;\n observability.incrementCounter({\n name: \"opengeni_sandbox_deadline_rotations_requested_total\",\n help: \"Total finite-lifetime sandbox rotations requested before provider deadline.\",\n amount: count,\n });\n}\n\n/** Only call after the exact draining->cold commit reports wentCold. The\n * backend is validated against the closed contract so provider IDs and other\n * per-sandbox values can never become metric labels. */\nexport function recordSandboxProviderMissingBeforeCapture(\n observability: Observability,\n backend: string,\n): void {\n const safeBackend = SandboxBackend.safeParse(backend).success ? backend : \"unknown\";\n observability.incrementCounter({\n name: \"opengeni_sandbox_provider_missing_before_capture_total\",\n help: \"Exact sandbox cold commits after definitive provider disappearance before workspace capture.\",\n labels: { backend: safeBackend },\n });\n}\n\nexport function recordSandboxRecoveryObservationGauges(\n observability: Observability,\n observations: {\n providerLosses: number;\n fallbackSelections: number;\n freshWorkspaceSelections?: number;\n },\n): void {\n for (const [kind, value] of [\n [\"provider_missing_before_capture\", observations.providerLosses],\n [\"checkpoint_fallback_selected\", observations.fallbackSelections],\n [\"fresh_workspace_selected\", observations.freshWorkspaceSelections ?? 0],\n ] as const) {\n observability.setGauge({\n name: \"opengeni_sandbox_recovery_observations_recent\",\n help: \"Committed sandbox recovery observations in the last 30 minutes by fixed kind.\",\n labels: { kind },\n value,\n });\n }\n}\n\n/** Fixed outcomes for a committed automatic continuity decision after\n * definitive managed-provider loss: a singleton checkpoint (`selected`), a\n * shared-group checkpoint (`selected_shared`), or a new empty workspace\n * (`fresh_workspace`). Call only after the durable authorization committed. */\nexport const SANDBOX_AUTOMATIC_RECOVERY_OUTCOMES = [\n \"selected\",\n \"selected_shared\",\n \"fresh_workspace\",\n] as const;\nexport type SandboxAutomaticRecoveryOutcome = (typeof SANDBOX_AUTOMATIC_RECOVERY_OUTCOMES)[number];\n\nexport function sandboxAutomaticRecoveryOutcome(input: {\n lane: \"checkpoint\" | \"fresh_workspace\";\n groupSessionCount: number;\n}): SandboxAutomaticRecoveryOutcome {\n if (input.lane === \"fresh_workspace\") return \"fresh_workspace\";\n return input.groupSessionCount > 1 ? \"selected_shared\" : \"selected\";\n}\n\nexport function recordSandboxAutomaticRecoverySelected(\n observability: Observability,\n backend: string,\n outcome: SandboxAutomaticRecoveryOutcome,\n): void {\n const safeBackend = SandboxBackend.safeParse(backend).success ? backend : \"unknown\";\n observability.incrementCounter({\n name: \"opengeni_sandbox_checkpoint_fallback_total\",\n help: \"System-selected continuity after managed provider loss: verified checkpoint or empty workspace.\",\n labels: { backend: safeBackend, outcome },\n });\n}\n\nexport function recordSandboxRotationBacklogGauges(\n observability: Observability,\n backlog: {\n requested: number;\n overdue: number;\n turnBlocked: number;\n directBlocked: number;\n processBlocked: number;\n interactionBlocked: number;\n },\n): void {\n const values = {\n requested: backlog.requested,\n overdue: backlog.overdue,\n turn_blocked: backlog.turnBlocked,\n direct_blocked: backlog.directBlocked,\n process_blocked: backlog.processBlocked,\n interaction_blocked: backlog.interactionBlocked,\n } as const;\n for (const [kind, value] of Object.entries(values)) {\n observability.setGauge({\n name: \"opengeni_sandbox_rotation_backlog\",\n help: \"Current finite-lifetime sandbox rotation backlog by fixed condition.\",\n labels: { kind },\n value,\n });\n }\n}\n\nconst RETAINED_PROCESS_OWNER_STATES = [\n \"direct\",\n \"queued\",\n \"running\",\n \"requires_action\",\n \"recovering\",\n \"waiting_capacity\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n \"superseded\",\n \"withdrawn_for_edit\",\n \"missing\",\n \"unknown\",\n] as const;\n\nconst RETAINED_PROCESS_OWNER_STATE_SET = new Set<string>(RETAINED_PROCESS_OWNER_STATES);\n\nexport function recordRetainedProcessInventoryGauges(\n observability: Observability,\n counts: Array<{\n ownerState: string;\n activeCount: number;\n terminalOwnerCount: number;\n }>,\n): void {\n const normalized = new Map<string, { active: number; terminal: number }>();\n for (const ownerState of RETAINED_PROCESS_OWNER_STATES) {\n normalized.set(ownerState, { active: 0, terminal: 0 });\n }\n for (const count of counts) {\n const ownerState = RETAINED_PROCESS_OWNER_STATE_SET.has(count.ownerState)\n ? count.ownerState\n : \"unknown\";\n const current = normalized.get(ownerState)!;\n current.active += Math.max(0, count.activeCount);\n current.terminal += Math.max(0, count.terminalOwnerCount);\n }\n\n for (const [ownerState, count] of normalized) {\n observability.setGauge({\n name: \"opengeni_retained_processes_active\",\n help: \"Current active retained provider processes by durable owner state.\",\n labels: { owner_state: ownerState },\n value: count.active,\n });\n observability.setGauge({\n name: \"opengeni_retained_processes_terminal_owner_backlog\",\n help: \"Current active retained processes whose exact owner attempt is terminal.\",\n labels: { owner_state: ownerState },\n value: count.terminal,\n });\n }\n}\n\nexport const EXPIRED_DRAINING_BACKENDS = [...SandboxBackend.options, \"unknown\"] as const;\nconst EXPIRED_DRAINING_BACKEND_SET = new Set<string>(EXPIRED_DRAINING_BACKENDS);\nexport const EXPIRED_DRAINING_AGE_BUCKETS = [\"lt_5m\", \"5m_1h\", \"1h_1d\", \"gte_1d\"] as const;\n\nexport function recordExpiredDrainingSandboxLeaseGauges(\n observability: Observability,\n counts: Array<{ backend: string; ageBucket: string; count: number }>,\n): void {\n const normalized = new Map<string, number>();\n for (const backend of EXPIRED_DRAINING_BACKENDS) {\n for (const ageBucket of EXPIRED_DRAINING_AGE_BUCKETS) {\n normalized.set(`${backend}:${ageBucket}`, 0);\n }\n }\n for (const count of counts) {\n const backend = EXPIRED_DRAINING_BACKEND_SET.has(count.backend) ? count.backend : \"unknown\";\n if (!EXPIRED_DRAINING_AGE_BUCKETS.includes(count.ageBucket as never)) continue;\n const key = `${backend}:${count.ageBucket}`;\n normalized.set(key, (normalized.get(key) ?? 0) + Math.max(0, count.count));\n }\n for (const [key, value] of normalized) {\n const [backend, ageBucket] = key.split(\":\") as [string, string];\n observability.setGauge({\n name: \"opengeni_sandbox_leases_expired_draining\",\n help: \"Current expired draining sandbox leases by backend and fixed age bucket.\",\n labels: { backend, age_bucket: ageBucket },\n value,\n });\n }\n}\n\nexport const RETAINED_PROCESS_RECONCILIATION_OUTCOMES = [\n \"claim_failed\",\n \"proof_exited\",\n \"proof_lost\",\n \"proof_checkpoint_failed\",\n \"settled_exited\",\n \"settled_lost\",\n \"settlement_failed\",\n \"identity_mismatch\",\n \"resume_state_missing\",\n \"backend_unsupported\",\n \"provider_running\",\n \"provider_unknown\",\n \"provider_timeout\",\n \"provider_error\",\n \"provider_binding_missing\",\n \"provider_binding_mismatch\",\n \"provider_binding_adopted\",\n \"process_observation_unavailable\",\n \"quarantined_process_observation_unavailable\",\n \"quarantined_binding_missing\",\n \"quarantined_binding_mismatch\",\n \"defer_failed\",\n] as const;\n\nexport type RetainedProcessReconciliationOutcome =\n (typeof RETAINED_PROCESS_RECONCILIATION_OUTCOMES)[number];\n\nexport function recordRetainedProcessReconciliation(\n observability: Observability,\n outcome: RetainedProcessReconciliationOutcome,\n): void {\n observability.incrementCounter({\n name: \"opengeni_retained_process_reconciliation_total\",\n help: \"Bounded retained-process reconciliation observations by fixed app outcome.\",\n labels: { outcome },\n });\n}\n\nexport function recordCreditMicros(\n observability: Observability | undefined,\n kind: CreditMicrosKind,\n amountMicros: number,\n): void {\n if (!observability || amountMicros <= 0) {\n return;\n }\n observability.incrementCounter({\n name: \"opengeni_credit_micros_total\",\n help: \"Total credit micros recorded by kind.\",\n labels: { kind },\n amount: amountMicros,\n });\n}\n\nconst MODEL_REQUEST_PHASE_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.35, 0.5, 1, 2, 5, 10, 30, 60, 300,\n];\n\n/**\n * Record provider lifecycle diagnostics from the synchronous transport observer.\n * Provider ids come from the resolved provider registry; phase/outcome are closed\n * enums. This function never performs I/O outside the in-memory metrics registry.\n */\nexport function recordModelRequestPhase(\n observability: Observability,\n input: {\n provider: string;\n phase: \"headers\" | \"first_byte\" | \"terminal\";\n outcome?: \"completed\" | \"failed\" | \"timed_out\";\n durationSeconds: number;\n },\n): void {\n const outcome = input.outcome ?? \"\";\n observability.incrementCounter({\n name: \"opengeni_model_request_phases_total\",\n help: \"Provider model-request lifecycle phases by bounded phase and outcome.\",\n labels: { provider: input.provider, phase: input.phase, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_model_request_phase_duration_seconds\",\n help: \"Monotonic seconds from provider dispatch to a model-request lifecycle phase.\",\n buckets: MODEL_REQUEST_PHASE_BUCKETS,\n labels: { provider: input.provider, phase: input.phase },\n value: Math.max(0, input.durationSeconds),\n });\n}\n\nexport type TurnStartupPhase =\n | \"claim_and_policy\"\n | \"turn_start_settlement\"\n | \"credential_selection\"\n | \"runtime_preparation\"\n | \"sandbox_establish\"\n | \"file_resolution\"\n | \"tool_context_preparation\"\n | \"tool_preparation\"\n | \"tool_server_construction\"\n | \"tool_required_connect\"\n | \"tool_optional_connect\"\n | \"tool_attempt_catalog_build\"\n | \"tool_attempt_catalog_persist\"\n | \"tool_workspace_gateway_catalog_build\"\n | \"post_tool_preparation\"\n | \"agent_construction\"\n | \"post_agent_preparation\"\n | \"file_materialization\"\n | \"history_preparation\"\n | \"history_system_update_load\"\n | \"history_current_attachment_resolution\"\n | \"history_durable_history_load\"\n | \"history_sandbox_envelope_load\"\n | \"history_canonical_projection\"\n | \"history_provider_projection\"\n | \"history_attachment_ref_projection\"\n | \"history_screenshot_materialization\"\n | \"history_model_attachment_projection\"\n | \"history_runtime_input_assembly\"\n | \"history_artifact_candidate_scan\"\n | \"history_generated_image_materialization\"\n | \"history_position_load\"\n | \"owned_sandbox_setup\"\n | \"runtime_stream_initialization\"\n | \"model_request_preparation\"\n | \"model_sdk_serialization\"\n | \"model_prepare_sandbox_agent_preparation\"\n | \"model_prepare_sandbox_agent_manifest_inventory\"\n | \"model_prepare_sandbox_session_manifest_inventory\"\n | \"model_prepare_sandbox_manifest_apply\"\n | \"model_prepare_sandbox_entry_materialization\"\n | \"model_prepare_sandbox_running_check\"\n | \"model_prepare_sandbox_start\"\n | \"model_prepare_sandbox_client_create\"\n | \"model_prepare_sandbox_client_resume\"\n | \"model_prepare_sandbox_client_delete\"\n | \"model_prepare_sandbox_client_state_serialize\"\n | \"model_prepare_sandbox_client_reuse_check\"\n | \"model_prepare_sandbox_workspace_mutation_admission\"\n | \"model_prepare_sandbox_workspace_mutation_provider\"\n | \"model_prepare_sandbox_workspace_mutation_settlement\"\n | \"model_prepare_sandbox_first_routed_resolution_other\"\n | \"model_prepare_sandbox_first_routed_mutation_admission\"\n | \"model_prepare_sandbox_first_routed_provider_operation\"\n | \"model_prepare_sandbox_first_routed_mutation_settlement\"\n | \"model_prepare_sandbox_first_routed_other\"\n | \"model_prepare_sandbox_snapshot_wait\"\n | \"model_prepare_runner_before_first_sandbox_operation\"\n | \"model_prepare_sdk_after_first_sandbox_operation\"\n | \"model_prepare_runner_before_mcp_tools\"\n | \"model_prepare_mcp_tools_snapshot\"\n | \"model_prepare_mcp_tools_before_input_filter\"\n | \"model_prepare_mcp_tools_before_repository_skill_discovery\"\n | \"model_prepare_repository_skill_discovery\"\n | \"model_prepare_repository_skill_discovery_before_input_filter\"\n | \"model_prepare_input_filter_base\"\n | \"model_prepare_input_filter_genesis\"\n | \"model_prepare_input_filter_host\"\n | \"model_prepare_input_filter_tool_output\"\n | \"model_prepare_input_filter_modality\"\n | \"model_prepare_input_filter_context\"\n | \"model_prepare_responses_input_conversion\"\n | \"model_prepare_responses_request_build\"\n | \"model_credential_resolution\"\n | \"model_wire_normalization\"\n | \"model_request_audit\"\n | \"stream_bootstrap\";\n\nexport type TurnStartupOutcome = \"completed\" | \"failed\";\nexport type TurnStartupMilestone = \"queue\" | \"provider_dispatch\" | \"first_byte\";\nexport type TurnStartupCache = \"hit\" | \"miss\" | \"disabled\" | \"none\";\nexport type TurnStartupCountBucket = \"0\" | \"1\" | \"2-5\" | \"6-20\" | \"21+\" | \"unknown\";\nexport type TurnSandboxEstablishPolicy = \"eager\" | \"on-demand\";\nexport type TurnSandboxEstablishReason =\n | \"eligible\"\n | \"lazy_disabled\"\n | \"machine_primary\"\n | \"backend_none\"\n | \"initial_run_credentials\"\n | \"initial_run_credentials_deferred\"\n | \"generated_video_files\"\n | \"signed_file_resources\";\nexport type SandboxLogicalProvisionCategory =\n | \"create\"\n | \"resume\"\n | \"exec_readiness\"\n | \"sibling_warming\"\n | \"lease_superseded\"\n | \"drain_capture_wait\"\n | \"archive_recovery\"\n | \"provider_transport\"\n | \"configuration\"\n | \"unknown\";\nexport type SandboxLogicalProvisionStage =\n | \"create\"\n | \"resume\"\n | \"exec_readiness\"\n | \"sibling_warming\"\n | \"lease_admission\"\n | \"lifecycle_wait\"\n | \"archive_recovery\"\n | \"configuration\"\n | \"provider_transport\"\n | \"unknown\";\nexport type SandboxLogicalProvisionOutcome = \"completed\" | \"expected_transition\" | \"failed\";\nexport type SandboxProvisionAttemptOutcome = \"completed\" | \"retrying\" | \"failed\";\n\nconst TURN_STARTUP_PHASE_BUCKETS = [\n 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60, 120,\n];\nconst TURN_STARTUP_MILESTONE_BUCKETS = [\n ...TURN_STARTUP_PHASE_BUCKETS,\n 300,\n 600,\n 1_800,\n 3_600,\n 7_200,\n];\n\nexport function turnStartupCountBucket(count: number | null): TurnStartupCountBucket {\n if (count === null || !Number.isFinite(count) || count < 0) return \"unknown\";\n if (count === 0) return \"0\";\n if (count === 1) return \"1\";\n if (count <= 5) return \"2-5\";\n if (count <= 20) return \"6-20\";\n return \"21+\";\n}\n\n/**\n * Measure startup operations, including nested and parallel work. These are\n * not additive critical-path intervals; use milestones for elapsed latency.\n * Every label is a closed or configuration-derived enum; high-cardinality turn,\n * session, credential, connection, file, and model identifiers are forbidden.\n */\nexport function recordTurnStartupPhase(\n observability: Observability,\n input: {\n phase: TurnStartupPhase;\n provider: string;\n backend: string;\n outcome: TurnStartupOutcome;\n durationSeconds: number;\n count?: number | null;\n cache?: TurnStartupCache;\n /** Trace-only lookup for the completed claim while its execution root is still open. */\n executionCorrelationId?: string;\n },\n): void {\n completedOperationSpan(observability, `worker.prepare.${input.phase}`, input.durationSeconds, {\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n ...(input.phase === \"claim_and_policy\" &&\n /^turn_[0-9a-f]{32}$/.test(input.executionCorrelationId ?? \"\")\n ? { correlationId: input.executionCorrelationId }\n : {}),\n });\n observability.observeHistogram({\n name: \"opengeni_turn_startup_phase_duration_seconds\",\n help: \"Turn startup phase duration before the model response stream begins.\",\n buckets: TURN_STARTUP_PHASE_BUCKETS,\n labels: {\n phase: input.phase,\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n count_bucket: turnStartupCountBucket(input.count ?? null),\n cache: input.cache ?? \"none\",\n },\n value: Math.max(0, input.durationSeconds),\n });\n}\n\n/** Background MCP preparation must not inflate startup phase distributions. */\nexport function recordToolPreparationPhase(\n observability: Observability,\n input: ToolPreparationPhaseMeasurement & { provider: string; backend: string },\n): void {\n if (input.execution === \"blocking\") {\n recordTurnStartupPhase(observability, {\n ...input,\n phase: `tool_${input.phase}`,\n });\n return;\n }\n completedOperationSpan(\n observability,\n `worker.tool_prepare.${input.phase}`,\n input.durationSeconds,\n {\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n },\n );\n observability.observeHistogram({\n name: \"opengeni_tool_background_preparation_duration_seconds\",\n help: \"Nonblocking MCP preparation operations; may overlap startup and later execution.\",\n buckets: TURN_STARTUP_PHASE_BUCKETS,\n labels: {\n phase: input.phase,\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n },\n value: Math.max(0, input.durationSeconds),\n });\n}\n\n/** Completed measurements become siblings under the scoped physical attempt.\n * They never establish ambient ancestry for work which has already finished. */\nfunction completedOperationSpan(\n observability: Observability,\n name: string,\n durationSeconds: number,\n attributes: {\n outcome: string;\n provider?: string;\n backend?: string;\n correlationId?: string | undefined;\n },\n): void {\n if (!Number.isFinite(durationSeconds) || durationSeconds < 0) return;\n try {\n const failed = [\n \"failed\",\n \"error\",\n \"provider_declared_error\",\n \"auth_needed\",\n \"outcome_uncertain\",\n \"timeout\",\n \"thrown_transport_error\",\n \"thrown_protocol_error\",\n ].includes(attributes.outcome);\n observability\n .startSpan(name, attributes, { startTimeMs: Date.now() - durationSeconds * 1_000 })\n .end({\n ...(failed ? { error: true } : {}),\n });\n } catch {\n // Observers cannot change the completed model/tool/phase outcome.\n }\n}\n\n/**\n * Explain why a turn did or did not keep provider sandbox work off the\n * pre-model critical path. The reason is a closed enum: never attach session,\n * sandbox, credential, or file identifiers here.\n */\nexport function recordTurnSandboxEstablishPolicy(\n observability: Observability,\n input: {\n policy: TurnSandboxEstablishPolicy;\n reason: TurnSandboxEstablishReason;\n backend: string;\n },\n): void {\n observability.incrementCounter({\n name: \"opengeni_turn_sandbox_establish_policy_total\",\n help: \"Turn sandbox establish policy decisions by bounded reason.\",\n labels: {\n policy: input.policy,\n reason: input.reason,\n backend: input.backend,\n },\n });\n}\n\n/** Physical establish/resume attempts inside one logical provision. Safe\n * lifecycle retries are counted here, never as another user-visible failure. */\nexport function recordSandboxProvisionAttempt(\n observability: Observability,\n input: {\n backend: string;\n stage: SandboxLogicalProvisionStage;\n category: SandboxLogicalProvisionCategory;\n outcome: SandboxProvisionAttemptOutcome;\n durationSeconds: number;\n },\n): void {\n const labels = {\n backend: input.backend,\n stage: input.stage,\n category: input.category,\n outcome: input.outcome,\n };\n try {\n observability.incrementCounter({\n name: \"opengeni_sandbox_provision_attempts_total\",\n help: \"Internal physical attempts within logical sandbox provisions.\",\n labels,\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_provision_attempt_duration_seconds\",\n help: \"Internal sandbox provision attempt duration by bounded structural outcome.\",\n buckets: TURN_STARTUP_PHASE_BUCKETS,\n labels,\n value: Math.max(0, input.durationSeconds),\n });\n } catch {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer: \"sandbox_provision\" },\n });\n } catch {\n // The registry itself is unhealthy; provisioning remains authoritative.\n }\n }\n}\n\n/** One terminal observation for one correlation-qualified logical provision. */\nexport function recordSandboxLogicalProvision(\n observability: Observability,\n input: {\n backend: string;\n stage: SandboxLogicalProvisionStage;\n category: SandboxLogicalProvisionCategory | \"none\";\n outcome: SandboxLogicalProvisionOutcome;\n expected: boolean;\n internalAttempts: number;\n durationSeconds: number;\n },\n): void {\n const labels = {\n backend: input.backend,\n stage: input.stage,\n category: input.category,\n outcome: input.outcome,\n expected: input.expected ? \"true\" : \"false\",\n };\n try {\n observability.incrementCounter({\n name: \"opengeni_sandbox_provisions_total\",\n help: \"Logical sandbox provisions by terminal outcome and bounded failure taxonomy.\",\n labels,\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_provision_duration_seconds\",\n help: \"Logical sandbox provision duration including internal safe retries.\",\n buckets: TURN_STARTUP_PHASE_BUCKETS,\n labels,\n value: Math.max(0, input.durationSeconds),\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_provision_internal_attempts\",\n help: \"Internal physical attempts per terminal logical sandbox provision.\",\n buckets: [1, 2, 3, 4, 5, 8],\n labels,\n value: Math.max(1, input.internalAttempts),\n });\n } catch {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer: \"sandbox_provision\" },\n });\n } catch {\n // The registry itself is unhealthy; provisioning remains authoritative.\n }\n }\n}\n\nexport function recordSandboxSharedPreparation(\n observability: Observability,\n measurement: {\n path: \"owner\" | \"joined\" | \"reused\";\n outcome: \"completed\" | \"failed\";\n durationSeconds: number;\n },\n): void {\n observability.observeHistogram({\n name: \"opengeni_sandbox_shared_preparation_duration_seconds\",\n help: \"Duration of exact-lease immutable sandbox preparation by durable coordination path and outcome.\",\n labels: { path: measurement.path, outcome: measurement.outcome },\n value: Math.max(0, measurement.durationSeconds),\n });\n}\n\nexport function recordTurnWorkerPreparationTotal(\n observability: Observability,\n input: {\n provider: string;\n backend: string;\n outcome: TurnStartupOutcome;\n durationSeconds: number;\n },\n): void {\n observability.observeHistogram({\n name: \"opengeni_turn_worker_preparation_duration_seconds\",\n help: \"Worker preparation from the durable turn-start boundary until entering the runtime; lazy SDK request preparation and model-request audit are separate phases.\",\n buckets: TURN_STARTUP_PHASE_BUCKETS,\n labels: {\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n },\n value: Math.max(0, input.durationSeconds),\n });\n}\n\n/**\n * Measure cumulative user-visible startup latency from the durable turn queue\n * timestamp to a bounded milestone. Unlike the per-phase histogram above,\n * these samples are end-to-end and can therefore back real queue/dispatch/TTFB\n * SLOs without adding turn or session identifiers to Prometheus.\n */\nexport function recordTurnStartupMilestone(\n observability: Observability,\n input: {\n milestone: TurnStartupMilestone;\n provider: string;\n backend: string;\n outcome: TurnStartupOutcome;\n durationSeconds: number;\n },\n): void {\n observability.observeHistogram({\n name: \"opengeni_turn_startup_milestone_duration_seconds\",\n help: \"Cumulative seconds from durable turn queueing to a bounded startup milestone.\",\n buckets: TURN_STARTUP_MILESTONE_BUCKETS,\n labels: {\n milestone: input.milestone,\n provider: input.provider,\n backend: input.backend,\n outcome: input.outcome,\n },\n value: Math.max(0, input.durationSeconds),\n });\n}\n\n// ── Streaming SLIs ────────────────────────────────────────────────────────────\n// Instruments the token-streaming pipeline so \"streaming is sluggish\" is a number,\n// not a vibe. Split across the three attributable stages so an operator can tell\n// WHERE the latency lives: the model (TTFT + inter-delta gaps), our durable write\n// path (append latency), or delivery (publish latency + batcher flush shape). All\n// labels are bounded (provider from the model registry, a two-value delta class) —\n// never a session id or a raw user-supplied model string.\n\nexport type StreamDeltaClass = \"message\" | \"reasoning\";\n\n/** Content-delta classes only. A `null` return means \"not a content delta\" — the\n * event that re-arms the TTFT anchor and closes an inter-delta run. */\nfunction contentDeltaClass(type: SessionEventType): StreamDeltaClass | null {\n if (type === \"agent.message.delta\") {\n return \"message\";\n }\n if (type === \"agent.reasoning.delta\") {\n return \"reasoning\";\n }\n return null;\n}\n\n// TTFT and inter-delta live on a human-perceptible scale (tens of ms to a few\n// seconds), so they get their own SHORT buckets — the default duration buckets\n// (which run to 3600s) would collapse every real streaming value into one bucket.\nconst STREAM_TTFT_BUCKETS = [0.02, 0.05, 0.1, 0.2, 0.35, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10];\nconst STREAM_INTER_DELTA_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.35, 0.5, 1, 2, 5];\n\n/**\n * Per-turn stream-timing tracker fed every normalized runtime event in push order.\n * It emits two model-responsiveness SLIs from the worker's seat on the stream:\n *\n * - `opengeni_stream_ttft_seconds{provider}` — time from a model (re)start to its\n * first streamed content delta. The anchor starts at construction (≈ runStream\n * start, so the first observation is \"how long until text appears\") and re-arms\n * on every non-content event (a tool call, a completed message, a usage frame),\n * so a post-tool response measures the model's restart latency, NOT our own\n * tool-execution time.\n * - `opengeni_stream_inter_delta_gap_seconds{provider,class}` — gap between\n * consecutive content deltas of the SAME class. The run resets on any\n * non-content event so a gap never spans a tool call or a model boundary — it\n * measures only the choppiness of a live token stream.\n *\n * Purely observational and clock-injectable; it never touches the events it sees.\n */\nexport class StreamTimingMetrics {\n private readonly now: () => number;\n private ttftAnchor: number;\n private ttftArmed = true;\n private readonly lastDeltaAt = new Map<StreamDeltaClass, number>();\n\n constructor(\n private readonly observability: Observability,\n private readonly options: { provider: string; now?: () => number },\n ) {\n this.now = options.now ?? (() => performance.now());\n this.ttftAnchor = this.now();\n }\n\n onEvent(type: SessionEventType): void {\n const deltaClass = contentDeltaClass(type);\n if (deltaClass === null) {\n // A non-content event: the model paused emitting. Re-arm TTFT so the next\n // content delta measures (re)start latency, and close every inter-delta run\n // so no gap spans a tool call / model boundary.\n this.ttftAnchor = this.now();\n this.ttftArmed = true;\n this.lastDeltaAt.clear();\n return;\n }\n const at = this.now();\n if (this.ttftArmed) {\n this.observability.observeHistogram({\n name: \"opengeni_stream_ttft_seconds\",\n help: \"Seconds from a model (re)start to its first streamed content delta.\",\n buckets: STREAM_TTFT_BUCKETS,\n labels: { provider: this.options.provider },\n value: Math.max(0, (at - this.ttftAnchor) / 1000),\n });\n this.ttftArmed = false;\n }\n const last = this.lastDeltaAt.get(deltaClass);\n if (last !== undefined) {\n this.observability.observeHistogram({\n name: \"opengeni_stream_inter_delta_gap_seconds\",\n help: \"Seconds between consecutive streamed content deltas of the same class.\",\n buckets: STREAM_INTER_DELTA_BUCKETS,\n labels: { provider: this.options.provider, class: deltaClass },\n value: Math.max(0, (at - last) / 1000),\n });\n }\n this.lastDeltaAt.set(deltaClass, at);\n }\n}\n\n// Batch shapes: sizes are small integers; durations are the append+publish round\n// trip the flush performs (sub-ms to a couple seconds under contention).\nconst STREAM_BATCH_SIZE_BUCKETS = [1, 2, 5, 10, 20, 50, 100, 200, 500];\nconst STREAM_IO_BUCKETS = [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5];\n\n/** Flush shape of the streaming batcher: how many events coalesced into one flush\n * (the coalescing win) and how long that flush took (append + publish). */\nexport function recordBatchFlush(\n observability: Observability,\n input: { events: number; durationSeconds: number },\n): void {\n observability.observeHistogram({\n name: \"opengeni_stream_batch_flush_events\",\n help: \"Session events coalesced into one streaming batcher flush.\",\n buckets: STREAM_BATCH_SIZE_BUCKETS,\n value: input.events,\n });\n observability.observeHistogram({\n name: \"opengeni_stream_batch_flush_duration_seconds\",\n help: \"Duration in seconds of one streaming batcher flush (append + publish).\",\n buckets: STREAM_IO_BUCKETS,\n value: input.durationSeconds,\n });\n}\n\n/** Latency of the durable `appendSessionEvents` DB write — the write path. A p99\n * climb here is our Postgres, not the model or NATS. */\nexport function recordSessionEventAppendLatency(\n observability: Observability,\n input: { durationSeconds: number },\n): void {\n observability.observeHistogram({\n name: \"opengeni_session_event_append_seconds\",\n help: \"Duration in seconds of an appendSessionEvents DB write (the durable write path).\",\n buckets: STREAM_IO_BUCKETS,\n value: input.durationSeconds,\n });\n}\n\nexport function sessionEventBatchSizeClass(eventCount: number): string {\n if (!Number.isFinite(eventCount) || eventCount <= 0) return \"unknown\";\n if (eventCount === 1) return \"1\";\n if (eventCount <= 5) return \"2-5\";\n if (eventCount <= 10) return \"6-10\";\n if (eventCount <= 25) return \"11-25\";\n if (eventCount <= 50) return \"26-50\";\n return \"51+\";\n}\n\n/** Bounded database-phase attribution for exact-attempt event appends. */\nexport function recordSessionEventAppendPhase(\n observability: Observability,\n observation: SessionEventAppendPhaseObservation,\n): void {\n observability.observeHistogram({\n name: \"opengeni_session_event_append_phase_seconds\",\n help: \"Duration of one bounded database phase in an exact-attempt session event append.\",\n buckets: STREAM_IO_BUCKETS,\n labels: {\n path: \"turn_attempt\",\n event_class: observation.eventClass,\n batch_size_class: sessionEventBatchSizeClass(observation.eventCount),\n phase: observation.phase,\n outcome: observation.outcome,\n },\n value: Math.max(0, observation.durationSeconds),\n });\n}\n\n/** Latency of the best-effort NATS live fan-out — the delivery path. A p99 climb\n * here (with append healthy) is delivery, not the write path. */\nexport function recordSessionEventPublishLatency(\n observability: Observability,\n input: { durationSeconds: number },\n): void {\n observability.observeHistogram({\n name: \"opengeni_session_event_publish_seconds\",\n help: \"Duration in seconds of the best-effort NATS live fan-out publish (the delivery path).\",\n buckets: STREAM_IO_BUCKETS,\n value: input.durationSeconds,\n });\n}\n\n// Context tokens per response span a wide range; buckets retain context-pressure\n// diagnostics while compaction alerting follows the durable model-aware start.\nconst MODEL_INPUT_TOKENS_BUCKETS = [\n 1_000, 5_000, 10_000, 25_000, 50_000, 100_000, 150_000, 200_000, 300_000, 500_000, 1_000_000,\n];\n\n/** Observed input (context) tokens per model response for context-pressure\n * dashboards and provider diagnostics. */\nexport function recordModelInputTokens(\n observability: Observability,\n provider: string,\n inputTokens: number,\n): void {\n const normalizedInputTokens = modelUsageTokenCountOrNull(inputTokens);\n if (normalizedInputTokens === null || normalizedInputTokens === 0) {\n return;\n }\n observability.observeHistogram({\n name: \"opengeni_model_input_tokens\",\n help: \"Observed input (context) tokens per model response, by provider.\",\n buckets: MODEL_INPUT_TOKENS_BUCKETS,\n labels: { provider },\n value: normalizedInputTokens,\n });\n}\n\n/** A context compaction successfully completed, by bounded trigger. */\nexport function recordContextCompaction(\n observability: Observability,\n trigger: ContextCompactionTrigger,\n): void {\n observability.incrementCounter({ ...CONTEXT_COMPACTIONS_METRIC, labels: { trigger } });\n}\n\n/**\n * A durable context-compaction start, recorded only after the attempt-fenced\n * `compaction.started` transaction commits. This is the model-aware threshold\n * signal; it does not guess from a static token count shared by unlike models.\n */\nexport function recordContextCompactionStarted(\n observability: Observability,\n trigger: ContextCompactionTrigger,\n): void {\n observability.incrementCounter({ ...CONTEXT_COMPACTION_STARTS_METRIC, labels: { trigger } });\n}\n\nconst MODEL_CONTEXT_CONTRIBUTION_TOKEN_BUCKETS = [1, 8, 32, 128, 512, 2_048, 8_192];\n\n/**\n * Metadata-only Company Brain exposure telemetry. Labels are closed enums and\n * never include tenant ids, record ids, titles, descriptions, or content.\n */\nexport function recordCompanyBrainContributions(\n observability: Observability,\n receipt: CompanyBrainContributionReceipt,\n): void {\n for (const contribution of receipt.contributions) {\n const labels = {\n category: contribution.category,\n source: contribution.source,\n inclusion_reason: contribution.inclusionReason,\n authority_scope: contribution.authorityScope,\n session_role: receipt.sessionRole,\n memory_prompt_mode: receipt.memoryPromptMode,\n };\n observability.incrementCounter({\n name: \"opengeni_model_context_contributions_total\",\n help: \"Agent Knowledge contributions exposed to a model, by bounded reason and authority.\",\n labels,\n });\n observability.observeHistogram({\n name: \"opengeni_model_context_contribution_estimated_tokens\",\n help: \"Estimated tokens per model-visible Agent Knowledge contribution.\",\n buckets: MODEL_CONTEXT_CONTRIBUTION_TOKEN_BUCKETS,\n labels,\n value: contribution.estimatedTokens,\n });\n }\n}\n\n// ── Prompt-cache efficiency ─────────────────────────────────────────────────\n// Per model-call prompt-cache signal, provider-labelled only (bounded\n// cardinality — never a session id or account). `cached_tokens` is the slice of\n// the prompt the provider served from its prompt cache; the ratio cached/prompt\n// is the efficiency of that call. The account-switch hypothesis (a codex account\n// rotation cold-starts the provider's per-account prompt cache) is tested from\n// the per-call STRUCTURED LOG below — the account id is unbounded, so it is\n// hashed into a log field and NEVER a Prometheus label.\n\n// The hit ratio lives in [0, 1]; bucket tighter around the alerting threshold so\n// a p50 near 40% resolves. The default duration buckets (to 3600) would collapse\n// every ratio into the first bucket.\nconst MODEL_CACHE_HIT_RATIO_BUCKETS = [\n 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1,\n];\n\n/**\n * Prompt-cache efficiency of one model response, by provider. Reads from the SAME\n * usage frame that feeds input-token accounting, so the two are always consistent:\n * - `opengeni_model_cached_tokens_total{provider}` — cumulative prompt tokens the\n * provider served from cache. Advanced only when >0, so a provider that never\n * reports cached tokens contributes nothing rather than phantom zero-increments.\n * - `opengeni_model_cache_write_tokens_total{provider}` — cumulative tokens a\n * reporting provider wrote into its prompt cache. Absent telemetry contributes\n * nothing; in particular, Codex subscription usage does not currently expose it.\n * - `opengeni_model_cache_hit_ratio{provider}` — cached/prompt for the call,\n * observed only when prompt tokens are known (>0) AND cached tokens are reported.\n * A reported cached-token zero records a real 0%; absent/null telemetry remains\n * unknown and must not fabricate a low-cache signal.\n * - `opengeni_model_cache_read_telemetry_total{provider,status}` — one bounded\n * availability observation per authoritative call (`reported` or `missing`).\n * Invalid, fractional, unsafe, or over-contract token telemetry is rejected. A call\n * with no prompt tokens has no ratio (skipped).\n */\nexport function recordModelCacheTokens(\n observability: Observability,\n provider: string,\n input: {\n cachedTokens: number | null | undefined;\n cacheWriteTokens?: number | null | undefined;\n promptTokens: number | null | undefined;\n },\n): void {\n const cached = modelUsageTokenCountOrNull(input.cachedTokens);\n const cacheWrite = modelUsageTokenCountOrNull(input.cacheWriteTokens);\n const prompt = modelUsageTokenCountOrNull(input.promptTokens);\n incrementBoundedModelCacheCounter(observability, {\n name: \"opengeni_model_cache_read_telemetry_total\",\n help: \"Authoritative model calls with reported or missing cache-read telemetry, by provider.\",\n provider,\n labels: { provider, status: cached === null ? \"missing\" : \"reported\" },\n amount: 1,\n });\n if (cached !== null && cached > 0) {\n incrementBoundedModelCacheCounter(observability, {\n name: \"opengeni_model_cached_tokens_total\",\n help: \"Total prompt tokens served from the provider's prompt cache, by provider.\",\n provider,\n labels: { provider },\n amount: cached,\n });\n }\n if (cacheWrite !== null && cacheWrite > 0) {\n incrementBoundedModelCacheCounter(observability, {\n name: \"opengeni_model_cache_write_tokens_total\",\n help: \"Total prompt tokens written to the provider's prompt cache, by provider.\",\n provider,\n labels: { provider },\n amount: cacheWrite,\n });\n }\n if (cached !== null && prompt !== null && prompt > 0) {\n observability.observeHistogram({\n name: \"opengeni_model_cache_hit_ratio\",\n help: \"Per-call prompt-cache hit ratio (cached/prompt tokens) by provider.\",\n buckets: MODEL_CACHE_HIT_RATIO_BUCKETS,\n labels: { provider },\n // Clamp to [0, 1]: a provider that (rarely) reports cached >= prompt must\n // not skew the histogram past 1.0.\n value: Math.min(1, cached / prompt),\n });\n }\n}\n\nfunction incrementBoundedModelCacheCounter(\n observability: Observability,\n input: {\n name: string;\n help: string;\n provider: string;\n labels: Record<string, string>;\n amount: number;\n },\n): void {\n const totals = modelCacheCounterTotals.get(observability) ?? new Map<string, number>();\n if (!modelCacheCounterTotals.has(observability)) {\n modelCacheCounterTotals.set(observability, totals);\n }\n const labelKey = Object.entries(input.labels)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, value]) => `${key}=${value}`)\n .join(\",\");\n const key = `${input.name}:${labelKey}`;\n const current = totals.get(key) ?? 0;\n if (input.amount > MAX_MODEL_CACHE_COUNTER_TOTAL - current) {\n observability.warn(\"model cache metric cumulative limit reached\", {\n provider: input.provider,\n metric: input.name,\n });\n return;\n }\n observability.incrementCounter({\n name: input.name,\n help: input.help,\n labels: input.labels,\n amount: input.amount,\n });\n totals.set(key, current + input.amount);\n}\n\nfunction nonnegativeFinite(value: number): number {\n return Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction requiredTemporalNumber(\n value: unknown,\n field: string,\n options: { integer?: boolean } = {},\n): number {\n if (value === null || value === undefined) {\n throw new Error(`Temporal stats omitted required ${field}`);\n }\n const parsed = Number(value);\n if (\n !Number.isFinite(parsed) ||\n parsed < 0 ||\n (options.integer && !Number.isSafeInteger(parsed))\n ) {\n throw new Error(`Temporal stats returned invalid ${field}: ${String(value)}`);\n }\n return parsed;\n}\n\nfunction optionalTemporalNumber(\n value: unknown,\n field: string,\n options: { integer?: boolean } = {},\n): number {\n return value === null || value === undefined ? 0 : requiredTemporalNumber(value, field, options);\n}\n\n/**\n * An opaque, stable, non-reversible tag for a codex credential (account) — the\n * per-call log dimension the account-switch hypothesis correlates against. It is\n * a hash of the NON-SECRET credential ROW id (never a token/bearer), truncated so\n * it is short in logs while still distinguishing a handful of accounts without\n * collision. A null/absent credential (non-codex turn, no active account) tags as\n * \"none\" so the field is always present and never leaks an id verbatim.\n */\nexport function stableAccountHash(credentialId: string | null | undefined): string {\n if (!credentialId) {\n return \"none\";\n }\n return createHash(\"sha256\").update(credentialId).digest(\"hex\").slice(0, 12);\n}\n\n/**\n * The per-call account dimensions for the usage log: the opaque serving-account\n * tag and whether that account CHANGED versus the session's previous call. Within\n * one turn the serving credential is fixed, so a switch can only surface on the\n * turn's FIRST call (compared against the session's durably-recorded prior\n * credential); later calls in the same turn report `false`. A switch is reported\n * only when there was a KNOWN prior account that differs — a session's very first\n * call (no prior) is a cold start, not a switch.\n */\nexport function modelCallAccountContext(input: {\n servingCredentialId: string | null;\n priorSessionCredentialId: string | null;\n isFirstCallOfTurn: boolean;\n}): { servingAccountHash: string; accountChangedFromPrevCall: boolean } {\n const accountChangedFromPrevCall =\n input.isFirstCallOfTurn &&\n input.servingCredentialId !== null &&\n input.priorSessionCredentialId !== null &&\n input.priorSessionCredentialId !== input.servingCredentialId;\n return {\n servingAccountHash: stableAccountHash(input.servingCredentialId),\n accountChangedFromPrevCall,\n };\n}\n\nexport type CodeSearchCallOutcome =\n | \"completed\"\n | \"jev_unavailable\"\n | \"jev_rejected\"\n | \"workspace_unavailable\"\n | \"invalid_arguments\"\n | \"breaker_open\"\n | \"cancelled\"\n | \"failed\";\n\n/** One `code_search` tool call: outcome, wall time and the Jev work it used. */\nexport function recordCodeSearchCall(\n observability: Observability,\n input: {\n outcome: CodeSearchCallOutcome;\n durationSeconds: number;\n jevRequests: number;\n jevCostUsd: number;\n },\n): void {\n observability.incrementCounter({\n name: \"opengeni_code_search_calls_total\",\n help: \"Jev-backed code_search tool calls by outcome.\",\n labels: { outcome: input.outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_code_search_duration_seconds\",\n help: \"Wall time of one code_search tool call.\",\n buckets: [0.5, 1, 2, 4, 8, 15, 30, 60],\n labels: { outcome: input.outcome },\n value: Math.max(0, input.durationSeconds),\n });\n if (input.jevRequests > 0) {\n observability.incrementCounter({\n name: \"opengeni_code_search_jev_requests_total\",\n help: \"Jev requests made by code_search.\",\n amount: input.jevRequests,\n });\n }\n if (input.jevCostUsd > 0) {\n observability.incrementCounter({\n name: \"opengeni_code_search_jev_cost_micro_usd_total\",\n help: \"Estimated Jev list-price cost of code_search, in micro-USD.\",\n amount: Math.round(input.jevCostUsd * 1_000_000),\n });\n }\n}\n\n/**\n * One skill_read call. Labels are closed sets: `skill` is a built-in id or\n * `custom` for every other Skill, so tenant Skill ids, names, and requested\n * identifiers never become labels. `source` is `unknown` when the read was\n * refused before a Skill resolved.\n */\nexport function recordSkillRead(\n observability: Observability,\n read: {\n caller: \"model\" | \"codemode\";\n kind: SkillReadKind;\n source: SkillUseSource | null;\n /** The resolved Skill id, or the requested identifier when none resolved. */\n skill: string;\n },\n): void {\n observability.incrementCounter({\n name: \"opengeni_skill_reads_total\",\n help: \"skill_read calls by Skill source, built-in Skill id (custom for any other Skill), result kind, and caller.\",\n labels: {\n source: read.source ?? \"unknown\",\n skill: skillReadMetricLabel(read.source, read.skill),\n kind: read.kind,\n caller: read.caller,\n },\n });\n}\n\n/**\n * One skill_checkout call. Labels are closed sets and never carry Skill ids,\n * names, or paths. Phases that did not run are not observed.\n */\nexport function recordSkillCheckout(\n observability: Observability,\n checkout: {\n outcome: \"written\" | \"unchanged\" | \"refused\" | \"failed\";\n selection: \"all\" | \"paths\";\n written: number;\n unchanged: number;\n resolveSeconds: number | null;\n sandboxSeconds: number | null;\n writeSeconds: number | null;\n totalSeconds: number;\n },\n): void {\n observability.incrementCounter({\n name: \"opengeni_skill_checkouts_total\",\n help: \"skill_checkout calls by outcome and whether they selected specific paths.\",\n labels: { outcome: checkout.outcome, selection: checkout.selection },\n });\n const phases = [\n [\"resolve\", checkout.resolveSeconds],\n [\"sandbox\", checkout.sandboxSeconds],\n [\"write\", checkout.writeSeconds],\n [\"total\", checkout.totalSeconds],\n ] as const;\n for (const [phase, seconds] of phases) {\n if (seconds === null) continue;\n observability.observeHistogram({\n name: \"opengeni_skill_checkout_duration_seconds\",\n help: \"Wall time of skill_checkout phases: resolve (authority and Skill read), sandbox (filesystem handle, including lazy box start), write (batched file write), and total.\",\n buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 4, 8, 15, 30, 60],\n labels: { phase, outcome: checkout.outcome },\n value: Math.max(0, seconds),\n });\n }\n for (const [result, amount] of [\n [\"written\", checkout.written],\n [\"unchanged\", checkout.unchanged],\n ] as const) {\n if (amount <= 0) continue;\n observability.incrementCounter({\n name: \"opengeni_skill_checkout_files_total\",\n help: \"Files skill_checkout wrote or found already present with the same content.\",\n labels: { result },\n amount,\n });\n }\n}\n\nfunction skillReadMetricLabel(source: SkillUseSource | null, skill: string): string {\n if (source !== null && source !== \"builtin\") return \"custom\";\n // A refused read may name a built-in by its plain name.\n for (const candidate of source === null ? [skill, `builtin:${skill}`] : [skill]) {\n const parsed = BundledSkillId.safeParse(candidate);\n if (parsed.success) return parsed.data;\n }\n return \"custom\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport { request as httpsRequest } from \"node:https\";\n\nconst KUBERNETES_API_URL = \"https://kubernetes.default.svc\";\nconst KUBERNETES_TOKEN_FILE = \"/var/run/secrets/opengeni.io/opensandbox-kubernetes-inventory/token\";\nconst KUBERNETES_CA_FILE = \"/var/run/secrets/opengeni.io/opensandbox-kubernetes-inventory/ca.crt\";\nconst KUBERNETES_REQUEST_TIMEOUT_MS = 10_000;\nconst KUBERNETES_RESPONSE_MAX_BYTES = 64 * 1024 * 1024;\nconst KUBERNETES_LIST_PAGE_SIZE = 200;\nconst KUBERNETES_LIST_MAX_PAGES = 10_000;\n\nexport const OPENSANDBOX_CLEANUP_STUCK_SECONDS = 300;\nexport const OPENSANDBOX_EXPIRATION_OVERDUE_SECONDS = 180;\n\nexport const OPENSANDBOX_BATCHSANDBOX_PHASES = [\n \"pending\",\n \"running\",\n \"pausing\",\n \"paused\",\n \"resuming\",\n \"failed\",\n \"unknown\",\n] as const;\n\nexport type OpenSandboxBatchSandboxPhase = (typeof OPENSANDBOX_BATCHSANDBOX_PHASES)[number];\n\nexport const OPENSANDBOX_WORKLOAD_POD_CONDITIONS = [\n \"pending\",\n \"image_pull\",\n \"unschedulable\",\n] as const;\n\nexport type OpenSandboxWorkloadPodCondition = (typeof OPENSANDBOX_WORKLOAD_POD_CONDITIONS)[number];\n\nexport type OpenSandboxKubernetesInventory = {\n batchSandboxPhases: Record<OpenSandboxBatchSandboxPhase, number>;\n workloadPodConditions: Record<OpenSandboxWorkloadPodCondition, number>;\n cleanupStuck: number;\n expirationOverdue: number;\n};\n\nexport type KubernetesJsonRequest = (url: URL) => Promise<unknown>;\n\ntype JsonRecord = Record<string, unknown>;\n\nconst IMAGE_PULL_REASONS = new Set([\"ErrImagePull\", \"ImagePullBackOff\", \"InvalidImageName\"]);\n\nexport async function inspectOpenSandboxKubernetesInventory(input: {\n namespace: string;\n nowMs?: number;\n requestJson?: KubernetesJsonRequest;\n apiUrl?: string;\n tokenFile?: string;\n caFile?: string;\n}): Promise<OpenSandboxKubernetesInventory> {\n const namespace = kubernetesNamespace(input.namespace);\n const nowMs = input.nowMs ?? Date.now();\n const requestJson =\n input.requestJson ??\n (await authenticatedKubernetesJsonRequest({\n tokenFile: input.tokenFile ?? KUBERNETES_TOKEN_FILE,\n caFile: input.caFile ?? KUBERNETES_CA_FILE,\n }));\n const apiUrl = new URL(input.apiUrl ?? KUBERNETES_API_URL);\n if (apiUrl.protocol !== \"https:\") {\n throw new Error(\"OpenSandbox Kubernetes inventory API must use HTTPS\");\n }\n\n const inventory: OpenSandboxKubernetesInventory = {\n batchSandboxPhases: zeroRecord(OPENSANDBOX_BATCHSANDBOX_PHASES),\n workloadPodConditions: zeroRecord(OPENSANDBOX_WORKLOAD_POD_CONDITIONS),\n cleanupStuck: 0,\n expirationOverdue: 0,\n };\n\n await visitKubernetesList({\n apiUrl,\n requestJson,\n path: `/apis/sandbox.opensandbox.io/v1alpha1/namespaces/${encodeURIComponent(namespace)}/batchsandboxes`,\n visit: (item) => observeBatchSandbox(inventory, item, nowMs),\n });\n await visitKubernetesList({\n apiUrl,\n requestJson,\n path: `/api/v1/namespaces/${encodeURIComponent(namespace)}/pods`,\n query: { labelSelector: \"opensandbox.io/id\" },\n visit: (item) => observeWorkloadPod(inventory, item),\n });\n\n return inventory;\n}\n\nfunction observeBatchSandbox(\n inventory: OpenSandboxKubernetesInventory,\n item: unknown,\n nowMs: number,\n): void {\n const resource = record(item);\n const metadata = record(resource.metadata);\n const spec = record(resource.spec);\n const status = record(resource.status);\n\n inventory.batchSandboxPhases[batchSandboxPhase(status.phase)] += 1;\n\n const deletionTimestampMs = dateMilliseconds(metadata.deletionTimestamp);\n const finalizers = Array.isArray(metadata.finalizers) ? metadata.finalizers : [];\n if (\n deletionTimestampMs !== null &&\n finalizers.length > 0 &&\n nowMs - deletionTimestampMs >= OPENSANDBOX_CLEANUP_STUCK_SECONDS * 1_000\n ) {\n inventory.cleanupStuck += 1;\n }\n\n const expirationMs = dateMilliseconds(spec.expireTime);\n if (\n expirationMs !== null &&\n nowMs - expirationMs >= OPENSANDBOX_EXPIRATION_OVERDUE_SECONDS * 1_000\n ) {\n inventory.expirationOverdue += 1;\n }\n}\n\nfunction observeWorkloadPod(inventory: OpenSandboxKubernetesInventory, item: unknown): void {\n const pod = record(item);\n const metadata = record(pod.metadata);\n if (dateMilliseconds(metadata.deletionTimestamp) !== null) return;\n\n const status = record(pod.status);\n if (status.phase === \"Pending\") inventory.workloadPodConditions.pending += 1;\n if (podHasImagePullFailure(status)) inventory.workloadPodConditions.image_pull += 1;\n if (podIsUnschedulable(status)) inventory.workloadPodConditions.unschedulable += 1;\n}\n\nfunction podHasImagePullFailure(status: JsonRecord): boolean {\n for (const key of [\"initContainerStatuses\", \"containerStatuses\", \"ephemeralContainerStatuses\"]) {\n const statuses = Array.isArray(status[key]) ? status[key] : [];\n for (const value of statuses) {\n const waiting = record(record(record(value).state).waiting);\n if (typeof waiting.reason === \"string\" && IMAGE_PULL_REASONS.has(waiting.reason)) return true;\n }\n }\n return false;\n}\n\nfunction podIsUnschedulable(status: JsonRecord): boolean {\n const conditions = Array.isArray(status.conditions) ? status.conditions : [];\n return conditions.some((value) => {\n const condition = record(value);\n return (\n condition.type === \"PodScheduled\" &&\n condition.status === \"False\" &&\n condition.reason === \"Unschedulable\"\n );\n });\n}\n\nfunction batchSandboxPhase(value: unknown): OpenSandboxBatchSandboxPhase {\n switch (value) {\n case \"Pending\":\n return \"pending\";\n case \"Succeed\":\n case \"Running\":\n return \"running\";\n case \"Pausing\":\n return \"pausing\";\n case \"Paused\":\n return \"paused\";\n case \"Resuming\":\n return \"resuming\";\n case \"Failed\":\n return \"failed\";\n default:\n return \"unknown\";\n }\n}\n\nasync function visitKubernetesList(input: {\n apiUrl: URL;\n requestJson: KubernetesJsonRequest;\n path: string;\n query?: Record<string, string>;\n visit: (item: unknown) => void;\n}): Promise<void> {\n let continuation = \"\";\n for (let page = 0; page < KUBERNETES_LIST_MAX_PAGES; page += 1) {\n const url = new URL(input.path, input.apiUrl);\n url.searchParams.set(\"limit\", String(KUBERNETES_LIST_PAGE_SIZE));\n for (const [key, value] of Object.entries(input.query ?? {})) {\n url.searchParams.set(key, value);\n }\n if (continuation) url.searchParams.set(\"continue\", continuation);\n\n const payload = record(await input.requestJson(url));\n if (!Array.isArray(payload.items)) {\n throw new Error(`Kubernetes list ${input.path} returned no items array`);\n }\n for (const item of payload.items) input.visit(item);\n\n const next = record(payload.metadata).continue;\n if (typeof next !== \"string\" || next.length === 0) return;\n if (next === continuation) {\n throw new Error(`Kubernetes list ${input.path} repeated its continuation token`);\n }\n continuation = next;\n }\n throw new Error(`Kubernetes list ${input.path} exceeded its page safety bound`);\n}\n\nasync function authenticatedKubernetesJsonRequest(input: {\n tokenFile: string;\n caFile: string;\n}): Promise<KubernetesJsonRequest> {\n const [tokenText, ca] = await Promise.all([\n readFile(input.tokenFile, \"utf8\"),\n readFile(input.caFile),\n ]);\n const token = tokenText.trim();\n if (!token) throw new Error(\"OpenSandbox Kubernetes inventory token is empty\");\n\n return async (url) =>\n await new Promise<unknown>((resolve, reject) => {\n const request = httpsRequest(\n url,\n {\n method: \"GET\",\n ca,\n headers: {\n accept: \"application/json\",\n authorization: `Bearer ${token}`,\n },\n },\n (response) => {\n const chunks: Buffer[] = [];\n let bytes = 0;\n response.on(\"data\", (chunk: Buffer | string) => {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n bytes += buffer.length;\n if (bytes > KUBERNETES_RESPONSE_MAX_BYTES) {\n request.destroy(new Error(\"Kubernetes inventory response exceeded its byte limit\"));\n return;\n }\n chunks.push(buffer);\n });\n response.on(\"end\", () => {\n const statusCode = response.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new Error(`Kubernetes inventory request failed with HTTP ${statusCode}`));\n return;\n }\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString(\"utf8\")));\n } catch {\n reject(new Error(\"Kubernetes inventory response was not valid JSON\"));\n }\n });\n response.on(\"error\", reject);\n },\n );\n request.setTimeout(KUBERNETES_REQUEST_TIMEOUT_MS, () => {\n request.destroy(new Error(\"Kubernetes inventory request timed out\"));\n });\n request.on(\"error\", reject);\n request.end();\n });\n}\n\nfunction kubernetesNamespace(value: string): string {\n const namespace = value.trim();\n if (\n namespace.length === 0 ||\n namespace.length > 63 ||\n !/^[a-z0-9](?:[-a-z0-9]*[a-z0-9])?$/u.test(namespace)\n ) {\n throw new Error(\"OpenSandbox Kubernetes inventory namespace is invalid\");\n }\n return namespace;\n}\n\nfunction dateMilliseconds(value: unknown): number | null {\n if (typeof value !== \"string\" || value.length === 0) return null;\n const milliseconds = Date.parse(value);\n return Number.isFinite(milliseconds) ? milliseconds : null;\n}\n\nfunction record(value: unknown): JsonRecord {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as JsonRecord) : {};\n}\n\nfunction zeroRecord<const T extends readonly string[]>(keys: T): Record<T[number], number> {\n return Object.fromEntries(keys.map((key) => [key, 0])) as Record<T[number], number>;\n}\n"],"mappings":"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","names":["key"]}
|