@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.3-beta.2
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/LICENSE +21 -0
- package/README.md +83 -0
- package/package.json +82 -15
- package/src/actions/generate-media.d.ts +59 -0
- package/src/actions/generate-media.d.ts.map +1 -0
- package/src/actions/generate-media.ts +647 -0
- package/src/actions/identify-speaker.d.ts +23 -0
- package/src/actions/identify-speaker.d.ts.map +1 -0
- package/src/actions/identify-speaker.ts +171 -0
- package/src/actions/transcription-control.d.ts +29 -0
- package/src/actions/transcription-control.d.ts.map +1 -0
- package/src/actions/transcription-control.test.ts +100 -0
- package/src/actions/transcription-control.ts +127 -0
- package/src/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
- package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
- package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
- package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
- package/src/adapters/capacitor-llama/environment.ts +71 -0
- package/src/adapters/capacitor-llama/index.browser.ts +83 -0
- package/src/adapters/capacitor-llama/index.ts +807 -0
- package/src/adapters/capacitor-llama/loader.ts +109 -0
- package/src/adapters/capacitor-llama/structured-output.ts +165 -0
- package/src/adapters/capacitor-llama/text-streaming.ts +227 -0
- package/src/adapters/capacitor-llama/types.ts +374 -0
- package/src/backends/apple-foundation.ts +127 -0
- package/src/index.d.ts +8 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +62 -0
- package/src/local-inference-routes.d.ts +38 -0
- package/src/local-inference-routes.d.ts.map +1 -0
- package/src/local-inference-routes.test.ts +344 -0
- package/src/local-inference-routes.ts +1543 -0
- package/src/provider.d.ts +21 -0
- package/src/provider.d.ts.map +1 -0
- package/src/provider.ts +1082 -0
- package/src/routes/compat-helpers.d.ts +18 -0
- package/src/routes/compat-helpers.d.ts.map +1 -0
- package/src/routes/compat-helpers.ts +274 -0
- package/src/routes/family-member-route.d.ts +62 -0
- package/src/routes/family-member-route.d.ts.map +1 -0
- package/src/routes/family-member-route.ts +353 -0
- package/src/routes/index.d.ts +19 -0
- package/src/routes/index.d.ts.map +1 -0
- package/src/routes/index.ts +60 -0
- package/src/routes/live-diarization-route.d.ts +26 -0
- package/src/routes/live-diarization-route.d.ts.map +1 -0
- package/src/routes/live-diarization-route.test.ts +213 -0
- package/src/routes/live-diarization-route.ts +122 -0
- package/src/routes/local-inference-asr-route.d.ts +4 -0
- package/src/routes/local-inference-asr-route.d.ts.map +1 -0
- package/src/routes/local-inference-asr-route.test.ts +205 -0
- package/src/routes/local-inference-asr-route.ts +163 -0
- package/src/routes/local-inference-asr-transcribe.d.ts +20 -0
- package/src/routes/local-inference-asr-transcribe.d.ts.map +1 -0
- package/src/routes/local-inference-asr-transcribe.test.ts +118 -0
- package/src/routes/local-inference-asr-transcribe.ts +97 -0
- package/src/routes/local-inference-compat-routes.d.ts +16 -0
- package/src/routes/local-inference-compat-routes.d.ts.map +1 -0
- package/src/routes/local-inference-compat-routes.test.ts +485 -0
- package/src/routes/local-inference-compat-routes.ts +808 -0
- package/src/routes/local-inference-tts-route.d.ts +7 -0
- package/src/routes/local-inference-tts-route.d.ts.map +1 -0
- package/src/routes/local-inference-tts-route.test.ts +179 -0
- package/src/routes/local-inference-tts-route.ts +230 -0
- package/src/routes/transcript-audio-store.d.ts +15 -0
- package/src/routes/transcript-audio-store.d.ts.map +1 -0
- package/src/routes/transcript-audio-store.ts +27 -0
- package/src/routes/transcripts-routes.d.ts +36 -0
- package/src/routes/transcripts-routes.d.ts.map +1 -0
- package/src/routes/transcripts-routes.test.ts +144 -0
- package/src/routes/transcripts-routes.ts +159 -0
- package/src/routes/voice-first-run-routes.d.ts +62 -0
- package/src/routes/voice-first-run-routes.d.ts.map +1 -0
- package/src/routes/voice-first-run-routes.ts +524 -0
- package/src/routes/voice-models-routes.d.ts +62 -0
- package/src/routes/voice-models-routes.d.ts.map +1 -0
- package/src/routes/voice-models-routes.ts +554 -0
- package/src/routes/voice-profile-plugin-routes.d.ts +19 -0
- package/src/routes/voice-profile-plugin-routes.d.ts.map +1 -0
- package/src/routes/voice-profile-plugin-routes.ts +138 -0
- package/src/routes/voice-profiles-management-routes.d.ts +52 -0
- package/src/routes/voice-profiles-management-routes.d.ts.map +1 -0
- package/src/routes/voice-profiles-management-routes.ts +476 -0
- package/src/routes/voice-speaker-profile-routes.d.ts +57 -0
- package/src/routes/voice-speaker-profile-routes.d.ts.map +1 -0
- package/src/routes/voice-speaker-profile-routes.ts +199 -0
- package/src/runtime/aosp-llama-loader-selection.test.ts +80 -0
- package/src/runtime/capacitor-llama.d.ts +25 -0
- package/src/runtime/embedding-manager-support.d.ts +77 -0
- package/src/runtime/embedding-manager-support.d.ts.map +1 -0
- package/src/runtime/embedding-manager-support.ts +497 -0
- package/src/runtime/embedding-presets.d.ts +16 -0
- package/src/runtime/embedding-presets.d.ts.map +1 -0
- package/src/runtime/embedding-presets.ts +81 -0
- package/src/runtime/embedding-warmup-policy.d.ts +14 -0
- package/src/runtime/embedding-warmup-policy.d.ts.map +1 -0
- package/src/runtime/embedding-warmup-policy.test.ts +53 -0
- package/src/runtime/embedding-warmup-policy.ts +48 -0
- package/src/runtime/ensure-local-inference-handler.d.ts +62 -0
- package/src/runtime/ensure-local-inference-handler.d.ts.map +1 -0
- package/src/runtime/ensure-local-inference-handler.test.ts +528 -0
- package/src/runtime/ensure-local-inference-handler.ts +1448 -0
- package/src/runtime/index.d.ts +15 -0
- package/src/runtime/index.d.ts.map +1 -0
- package/src/runtime/index.ts +33 -0
- package/src/runtime/mobile-local-inference-gate.d.ts +31 -0
- package/src/runtime/mobile-local-inference-gate.d.ts.map +1 -0
- package/src/runtime/mobile-local-inference-gate.test.ts +69 -0
- package/src/runtime/mobile-local-inference-gate.ts +44 -0
- package/src/runtime/voice-entity-binding.d.ts +103 -0
- package/src/runtime/voice-entity-binding.d.ts.map +1 -0
- package/src/runtime/voice-entity-binding.transcript.test.ts +69 -0
- package/src/runtime/voice-entity-binding.ts +328 -0
- package/src/services/README.md +71 -0
- package/src/services/__tests__/backend-selector.test.ts +101 -0
- package/src/services/__tests__/checkpoint-manager.test.ts +376 -0
- package/src/services/__tests__/gpu-autotune.test.ts +400 -0
- package/src/services/__tests__/llm-streaming-binding.test.ts +85 -0
- package/src/services/__tests__/planner-grammar.test.ts +372 -0
- package/src/services/__tests__/runtime-target.test.ts +176 -0
- package/src/services/active-model-switch-rollback.test.ts +183 -0
- package/src/services/active-model.d.ts +282 -0
- package/src/services/active-model.d.ts.map +1 -0
- package/src/services/active-model.ts +1213 -0
- package/src/services/assignments.d.ts +71 -0
- package/src/services/assignments.d.ts.map +1 -0
- package/src/services/assignments.test.ts +80 -0
- package/src/services/assignments.ts +230 -0
- package/src/services/backend-selector.ts +95 -0
- package/src/services/backend.d.ts +346 -0
- package/src/services/backend.d.ts.map +1 -0
- package/src/services/backend.ts +612 -0
- package/src/services/bionic-host-loader.d.ts +46 -0
- package/src/services/bionic-host-loader.d.ts.map +1 -0
- package/src/services/bionic-host-loader.test.ts +133 -0
- package/src/services/bionic-host-loader.ts +180 -0
- package/src/services/bundled-models.d.ts +34 -0
- package/src/services/bundled-models.d.ts.map +1 -0
- package/src/services/bundled-models.ts +129 -0
- package/src/services/cache-bridge.d.ts +206 -0
- package/src/services/cache-bridge.d.ts.map +1 -0
- package/src/services/cache-bridge.test.ts +516 -0
- package/src/services/cache-bridge.ts +423 -0
- package/src/services/catalog.d.ts +10 -0
- package/src/services/catalog.d.ts.map +1 -0
- package/src/services/catalog.test.ts +238 -0
- package/src/services/catalog.ts +27 -0
- package/src/services/checkpoint-client.d.ts +109 -0
- package/src/services/checkpoint-client.d.ts.map +1 -0
- package/src/services/checkpoint-client.ts +258 -0
- package/src/services/checkpoint-manager.ts +474 -0
- package/src/services/cloud-fallback.d.ts +102 -0
- package/src/services/cloud-fallback.d.ts.map +1 -0
- package/src/services/cloud-fallback.ts +230 -0
- package/src/services/conversation-registry.d.ts +142 -0
- package/src/services/conversation-registry.d.ts.map +1 -0
- package/src/services/conversation-registry.test.ts +235 -0
- package/src/services/conversation-registry.ts +264 -0
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts +95 -0
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
- package/src/services/desktop-fused-ffi-backend-runtime.ts +339 -0
- package/src/services/device-bridge.d.ts +188 -0
- package/src/services/device-bridge.d.ts.map +1 -0
- package/src/services/device-bridge.ts +1237 -0
- package/src/services/device-resource-metrics.d.ts +149 -0
- package/src/services/device-resource-metrics.d.ts.map +1 -0
- package/src/services/device-resource-metrics.test.ts +98 -0
- package/src/services/device-resource-metrics.ts +346 -0
- package/src/services/device-tier.d.ts +115 -0
- package/src/services/device-tier.d.ts.map +1 -0
- package/src/services/device-tier.test.ts +371 -0
- package/src/services/device-tier.ts +410 -0
- package/src/services/downloader.d.ts +82 -0
- package/src/services/downloader.d.ts.map +1 -0
- package/src/services/downloader.test.ts +747 -0
- package/src/services/downloader.ts +925 -0
- package/src/services/engine-direct-bundle.test.ts +58 -0
- package/src/services/engine-streaming.test.ts +80 -0
- package/src/services/engine.d.ts +540 -0
- package/src/services/engine.d.ts.map +1 -0
- package/src/services/engine.ts +1909 -0
- package/src/services/ensure-local-artifacts.integration.test.ts +273 -0
- package/src/services/ensure-local-artifacts.test.ts +368 -0
- package/src/services/ensure-local-artifacts.ts +351 -0
- package/src/services/external-scanner.d.ts +17 -0
- package/src/services/external-scanner.d.ts.map +1 -0
- package/src/services/external-scanner.ts +312 -0
- package/src/services/ffi-llm-mock.ts +354 -0
- package/src/services/ffi-llm-streaming-abi.ts +442 -0
- package/src/services/ffi-streaming-backend.d.ts +180 -0
- package/src/services/ffi-streaming-backend.d.ts.map +1 -0
- package/src/services/ffi-streaming-backend.ts +382 -0
- package/src/services/ffi-streaming-runner.d.ts +122 -0
- package/src/services/ffi-streaming-runner.d.ts.map +1 -0
- package/src/services/ffi-streaming-runner.test.ts +60 -0
- package/src/services/ffi-streaming-runner.ts +354 -0
- package/src/services/ffi-unload-ordering.test.ts +162 -0
- package/src/services/gpu-autotune.ts +534 -0
- package/src/services/gpu-detect.d.ts +56 -0
- package/src/services/gpu-detect.d.ts.map +1 -0
- package/src/services/gpu-detect.ts +139 -0
- package/src/services/handler-registry.d.ts +72 -0
- package/src/services/handler-registry.d.ts.map +1 -0
- package/src/services/handler-registry.ts +240 -0
- package/src/services/hardware.d.ts +63 -0
- package/src/services/hardware.d.ts.map +1 -0
- package/src/services/hardware.test.ts +231 -0
- package/src/services/hardware.ts +410 -0
- package/src/services/hf-search.d.ts +26 -0
- package/src/services/hf-search.d.ts.map +1 -0
- package/src/services/hf-search.test.ts +69 -0
- package/src/services/hf-search.ts +420 -0
- package/src/services/image-description-runtime.d.ts +14 -0
- package/src/services/image-description-runtime.d.ts.map +1 -0
- package/src/services/image-description-runtime.test.ts +61 -0
- package/src/services/image-description-runtime.ts +118 -0
- package/src/services/imagegen/aosp-unavailable.d.ts +134 -0
- package/src/services/imagegen/aosp-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/aosp-unavailable.ts +229 -0
- package/src/services/imagegen/backend-selector.d.ts +118 -0
- package/src/services/imagegen/backend-selector.d.ts.map +1 -0
- package/src/services/imagegen/backend-selector.ts +277 -0
- package/src/services/imagegen/coreml-unavailable.d.ts +105 -0
- package/src/services/imagegen/coreml-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/coreml-unavailable.ts +237 -0
- package/src/services/imagegen/errors.d.ts +16 -0
- package/src/services/imagegen/errors.d.ts.map +1 -0
- package/src/services/imagegen/errors.ts +40 -0
- package/src/services/imagegen/index.d.ts +58 -0
- package/src/services/imagegen/index.d.ts.map +1 -0
- package/src/services/imagegen/index.ts +144 -0
- package/src/services/imagegen/mflux.d.ts +74 -0
- package/src/services/imagegen/mflux.d.ts.map +1 -0
- package/src/services/imagegen/mflux.ts +313 -0
- package/src/services/imagegen/sd-cpp.d.ts +180 -0
- package/src/services/imagegen/sd-cpp.d.ts.map +1 -0
- package/src/services/imagegen/sd-cpp.ts +718 -0
- package/src/services/imagegen/tensorrt-unavailable.d.ts +83 -0
- package/src/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
- package/src/services/imagegen/types.d.ts +181 -0
- package/src/services/imagegen/types.d.ts.map +1 -0
- package/src/services/imagegen/types.ts +193 -0
- package/src/services/index.d.ts +29 -0
- package/src/services/index.d.ts.map +1 -0
- package/src/services/index.ts +211 -0
- package/src/services/inference-capabilities.d.ts +132 -0
- package/src/services/inference-capabilities.d.ts.map +1 -0
- package/src/services/inference-capabilities.test.ts +75 -0
- package/src/services/inference-capabilities.ts +204 -0
- package/src/services/inference-telemetry.d.ts +59 -0
- package/src/services/inference-telemetry.d.ts.map +1 -0
- package/src/services/inference-telemetry.ts +143 -0
- package/src/services/ios-llama-streaming.ts +248 -0
- package/src/services/kv-spill.d.ts +189 -0
- package/src/services/kv-spill.d.ts.map +1 -0
- package/src/services/kv-spill.test.ts +222 -0
- package/src/services/kv-spill.ts +356 -0
- package/src/services/latency-trace.d.ts +346 -0
- package/src/services/latency-trace.d.ts.map +1 -0
- package/src/services/latency-trace.test.ts +266 -0
- package/src/services/latency-trace.ts +844 -0
- package/src/services/llama-server-metrics.ts +304 -0
- package/src/services/llm-streaming-binding.d.ts +96 -0
- package/src/services/llm-streaming-binding.d.ts.map +1 -0
- package/src/services/llm-streaming-binding.ts +136 -0
- package/src/services/load-args.d.ts +82 -0
- package/src/services/load-args.d.ts.map +1 -0
- package/src/services/load-args.ts +81 -0
- package/src/services/manifest/eliza-1.manifest.v1.json +708 -0
- package/src/services/manifest/index.d.ts +4 -0
- package/src/services/manifest/index.d.ts.map +1 -0
- package/src/services/manifest/index.ts +66 -0
- package/src/services/manifest/manifest.test.ts +689 -0
- package/src/services/manifest/schema.d.ts +713 -0
- package/src/services/manifest/schema.d.ts.map +1 -0
- package/src/services/manifest/schema.ts +653 -0
- package/src/services/manifest/types.d.ts +30 -0
- package/src/services/manifest/types.d.ts.map +1 -0
- package/src/services/manifest/types.ts +55 -0
- package/src/services/manifest/validator.d.ts +66 -0
- package/src/services/manifest/validator.d.ts.map +1 -0
- package/src/services/manifest/validator.ts +567 -0
- package/src/services/memory-arbiter.d.ts +318 -0
- package/src/services/memory-arbiter.d.ts.map +1 -0
- package/src/services/memory-arbiter.test.ts +419 -0
- package/src/services/memory-arbiter.ts +925 -0
- package/src/services/memory-monitor.d.ts +122 -0
- package/src/services/memory-monitor.d.ts.map +1 -0
- package/src/services/memory-monitor.test.ts +208 -0
- package/src/services/memory-monitor.ts +297 -0
- package/src/services/memory-pressure.d.ts +130 -0
- package/src/services/memory-pressure.d.ts.map +1 -0
- package/src/services/memory-pressure.ts +414 -0
- package/src/services/mtp-doctor.d.ts +13 -0
- package/src/services/mtp-doctor.d.ts.map +1 -0
- package/src/services/mtp-doctor.ts +78 -0
- package/src/services/network-policy.d.ts +127 -0
- package/src/services/network-policy.d.ts.map +1 -0
- package/src/services/network-policy.ts +346 -0
- package/src/services/paths.d.ts +6 -0
- package/src/services/paths.d.ts.map +1 -0
- package/src/services/paths.ts +25 -0
- package/src/services/planner-skeleton.d.ts +124 -0
- package/src/services/planner-skeleton.d.ts.map +1 -0
- package/src/services/planner-skeleton.ts +175 -0
- package/src/services/providers.d.ts +38 -0
- package/src/services/providers.d.ts.map +1 -0
- package/src/services/providers.ts +507 -0
- package/src/services/ram-budget-cache.test.ts +163 -0
- package/src/services/ram-budget.d.ts +110 -0
- package/src/services/ram-budget.d.ts.map +1 -0
- package/src/services/ram-budget.ts +0 -0
- package/src/services/readiness.d.ts +9 -0
- package/src/services/readiness.d.ts.map +1 -0
- package/src/services/readiness.test.ts +87 -0
- package/src/services/readiness.ts +238 -0
- package/src/services/recommendation.d.ts +111 -0
- package/src/services/recommendation.d.ts.map +1 -0
- package/src/services/recommendation.ts +671 -0
- package/src/services/registry.d.ts +35 -0
- package/src/services/registry.d.ts.map +1 -0
- package/src/services/registry.ts +151 -0
- package/src/services/router-handler.d.ts +92 -0
- package/src/services/router-handler.d.ts.map +1 -0
- package/src/services/router-handler.test.ts +45 -0
- package/src/services/router-handler.ts +407 -0
- package/src/services/routing-policy.d.ts +69 -0
- package/src/services/routing-policy.d.ts.map +1 -0
- package/src/services/routing-policy.test.ts +164 -0
- package/src/services/routing-policy.ts +297 -0
- package/src/services/routing-preferences.d.ts +8 -0
- package/src/services/routing-preferences.d.ts.map +1 -0
- package/src/services/routing-preferences.ts +17 -0
- package/src/services/runtime-target.d.ts +98 -0
- package/src/services/runtime-target.d.ts.map +1 -0
- package/src/services/runtime-target.ts +154 -0
- package/src/services/service.d.ts +128 -0
- package/src/services/service.d.ts.map +1 -0
- package/src/services/service.test.ts +223 -0
- package/src/services/service.ts +735 -0
- package/src/services/session-pool.d.ts +72 -0
- package/src/services/session-pool.d.ts.map +1 -0
- package/src/services/session-pool.ts +153 -0
- package/src/services/structured-output/deterministic-repair.d.ts +23 -0
- package/src/services/structured-output/deterministic-repair.d.ts.map +1 -0
- package/src/services/structured-output/deterministic-repair.test.ts +169 -0
- package/src/services/structured-output/deterministic-repair.ts +443 -0
- package/src/services/structured-output/index.ts +4 -0
- package/src/services/structured-output.d.ts +311 -0
- package/src/services/structured-output.d.ts.map +1 -0
- package/src/services/structured-output.test.ts +483 -0
- package/src/services/structured-output.ts +712 -0
- package/src/services/system-memory.d.ts +33 -0
- package/src/services/system-memory.d.ts.map +1 -0
- package/src/services/system-memory.test.ts +47 -0
- package/src/services/system-memory.ts +67 -0
- package/src/services/transcription-priority.test.ts +211 -0
- package/src/services/types.d.ts +19 -0
- package/src/services/types.d.ts.map +1 -0
- package/src/services/types.ts +55 -0
- package/src/services/verify-on-device.d.ts +34 -0
- package/src/services/verify-on-device.d.ts.map +1 -0
- package/src/services/verify-on-device.test.ts +87 -0
- package/src/services/verify-on-device.ts +127 -0
- package/src/services/verify.d.ts +8 -0
- package/src/services/verify.d.ts.map +1 -0
- package/src/services/verify.ts +13 -0
- package/src/services/vision/aosp-unavailable.d.ts +115 -0
- package/src/services/vision/aosp-unavailable.d.ts.map +1 -0
- package/src/services/vision/aosp-unavailable.ts +163 -0
- package/src/services/vision/capacitor-llama.d.ts +99 -0
- package/src/services/vision/capacitor-llama.d.ts.map +1 -0
- package/src/services/vision/capacitor-llama.ts +255 -0
- package/src/services/vision/cloud-fallback.d.ts +47 -0
- package/src/services/vision/cloud-fallback.d.ts.map +1 -0
- package/src/services/vision/cloud-fallback.test.ts +243 -0
- package/src/services/vision/cloud-fallback.ts +268 -0
- package/src/services/vision/fallback-chain.test.ts +86 -0
- package/src/services/vision/hash.d.ts +71 -0
- package/src/services/vision/hash.d.ts.map +1 -0
- package/src/services/vision/hash.ts +157 -0
- package/src/services/vision/index.d.ts +95 -0
- package/src/services/vision/index.d.ts.map +1 -0
- package/src/services/vision/index.ts +251 -0
- package/src/services/vision/llama-server.d.ts +73 -0
- package/src/services/vision/llama-server.d.ts.map +1 -0
- package/src/services/vision/llama-server.ts +177 -0
- package/src/services/vision/types.d.ts +153 -0
- package/src/services/vision/types.d.ts.map +1 -0
- package/src/services/vision/types.ts +154 -0
- package/src/services/vision/vast-fallback.d.ts +18 -0
- package/src/services/vision/vast-fallback.d.ts.map +1 -0
- package/src/services/vision/vast-fallback.ts +127 -0
- package/src/services/vision-embedding-cache.d.ts +98 -0
- package/src/services/vision-embedding-cache.d.ts.map +1 -0
- package/src/services/vision-embedding-cache.ts +189 -0
- package/src/services/voice/VOICE_WORKBENCH.md +88 -0
- package/src/services/voice/__test-helpers__/fake-ffi.ts +94 -0
- package/src/services/voice/__test-helpers__/synthetic-speech.ts +124 -0
- package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
- package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
- package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
- package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
- package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
- package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
- package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
- package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
- package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
- package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
- package/src/services/voice/__tests__/turn-detector-resolver.test.ts +195 -0
- package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
- package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
- package/src/services/voice/asr-timed.real.test.ts +141 -0
- package/src/services/voice/audio-frame-consumer.d.ts +212 -0
- package/src/services/voice/audio-frame-consumer.d.ts.map +1 -0
- package/src/services/voice/audio-frame-consumer.test.ts +343 -0
- package/src/services/voice/audio-frame-consumer.ts +491 -0
- package/src/services/voice/barge-in.d.ts +112 -0
- package/src/services/voice/barge-in.d.ts.map +1 -0
- package/src/services/voice/barge-in.test.ts +244 -0
- package/src/services/voice/barge-in.ts +336 -0
- package/src/services/voice/cancellation-coordinator.d.ts +127 -0
- package/src/services/voice/cancellation-coordinator.d.ts.map +1 -0
- package/src/services/voice/cancellation-coordinator.test.ts +196 -0
- package/src/services/voice/cancellation-coordinator.ts +269 -0
- package/src/services/voice/checkpoint-manager.d.ts +199 -0
- package/src/services/voice/checkpoint-manager.d.ts.map +1 -0
- package/src/services/voice/checkpoint-manager.ts +401 -0
- package/src/services/voice/checkpoint-policy.ts +336 -0
- package/src/services/voice/composite-eot-classifier.test.ts +59 -0
- package/src/services/voice/e2e-harness.test.ts +182 -0
- package/src/services/voice/e2e-harness.ts +743 -0
- package/src/services/voice/eager-context-builder.d.ts +170 -0
- package/src/services/voice/eager-context-builder.d.ts.map +1 -0
- package/src/services/voice/eager-context-builder.ts +262 -0
- package/src/services/voice/eliza1-eot-scorer.d.ts +124 -0
- package/src/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
- package/src/services/voice/eliza1-eot-scorer.ts +242 -0
- package/src/services/voice/embedding-server.ts +200 -0
- package/src/services/voice/embedding.d.ts +133 -0
- package/src/services/voice/embedding.d.ts.map +1 -0
- package/src/services/voice/embedding.test.ts +131 -0
- package/src/services/voice/embedding.ts +243 -0
- package/src/services/voice/emotion-attribution.d.ts +68 -0
- package/src/services/voice/emotion-attribution.d.ts.map +1 -0
- package/src/services/voice/emotion-attribution.test.ts +129 -0
- package/src/services/voice/emotion-attribution.ts +361 -0
- package/src/services/voice/engine-bridge-cancellation.test.ts +422 -0
- package/src/services/voice/engine-bridge.d.ts +759 -0
- package/src/services/voice/engine-bridge.d.ts.map +1 -0
- package/src/services/voice/engine-bridge.test.ts +384 -0
- package/src/services/voice/engine-bridge.ts +2302 -0
- package/src/services/voice/eot-classifier-ggml.d.ts +179 -0
- package/src/services/voice/eot-classifier-ggml.d.ts.map +1 -0
- package/src/services/voice/eot-classifier-ggml.ts +566 -0
- package/src/services/voice/eot-classifier.d.ts +214 -0
- package/src/services/voice/eot-classifier.d.ts.map +1 -0
- package/src/services/voice/eot-classifier.ts +533 -0
- package/src/services/voice/errors.d.ts +20 -0
- package/src/services/voice/errors.d.ts.map +1 -0
- package/src/services/voice/errors.ts +32 -0
- package/src/services/voice/expressive-tags.d.ts +158 -0
- package/src/services/voice/expressive-tags.d.ts.map +1 -0
- package/src/services/voice/expressive-tags.ts +405 -0
- package/src/services/voice/ffi-bindings.d.ts +674 -0
- package/src/services/voice/ffi-bindings.d.ts.map +1 -0
- package/src/services/voice/ffi-bindings.test.ts +728 -0
- package/src/services/voice/ffi-bindings.ts +3225 -0
- package/src/services/voice/first-line-cache.d.ts +181 -0
- package/src/services/voice/first-line-cache.d.ts.map +1 -0
- package/src/services/voice/first-line-cache.ts +725 -0
- package/src/services/voice/fused-eot-scorer.d.ts +51 -0
- package/src/services/voice/fused-eot-scorer.d.ts.map +1 -0
- package/src/services/voice/fused-eot-scorer.ts +135 -0
- package/src/services/voice/index.d.ts +91 -0
- package/src/services/voice/index.d.ts.map +1 -0
- package/src/services/voice/index.ts +481 -0
- package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +151 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +151 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.test.ts +60 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-discovery.test.ts +277 -0
- package/src/services/voice/kokoro/__tests__/kokoro-ffi-runtime.test.ts +235 -0
- package/src/services/voice/kokoro/__tests__/kokoro-runtime.test.ts +95 -0
- package/src/services/voice/kokoro/__tests__/phonemizer.test.ts +53 -0
- package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +231 -0
- package/src/services/voice/kokoro/__tests__/voices.test.ts +57 -0
- package/src/services/voice/kokoro/index.ts +79 -0
- package/src/services/voice/kokoro/kokoro-backend.d.ts +72 -0
- package/src/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-backend.ts +207 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -0
- package/src/services/voice/kokoro/kokoro-runtime.d.ts +100 -0
- package/src/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-runtime.ts +170 -0
- package/src/services/voice/kokoro/phoneme-stream.ts +123 -0
- package/src/services/voice/kokoro/phonemizer.d.ts +50 -0
- package/src/services/voice/kokoro/phonemizer.d.ts.map +1 -0
- package/src/services/voice/kokoro/phonemizer.ts +344 -0
- package/src/services/voice/kokoro/pick-runtime.d.ts +61 -0
- package/src/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/pick-runtime.test.ts +91 -0
- package/src/services/voice/kokoro/pick-runtime.ts +130 -0
- package/src/services/voice/kokoro/runtime-selection.d.ts +92 -0
- package/src/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
- package/src/services/voice/kokoro/runtime-selection.ts +237 -0
- package/src/services/voice/kokoro/types.d.ts +82 -0
- package/src/services/voice/kokoro/types.d.ts.map +1 -0
- package/src/services/voice/kokoro/types.ts +95 -0
- package/src/services/voice/kokoro/voice-presets.d.ts +23 -0
- package/src/services/voice/kokoro/voice-presets.d.ts.map +1 -0
- package/src/services/voice/kokoro/voice-presets.ts +129 -0
- package/src/services/voice/kokoro/voices.d.ts +30 -0
- package/src/services/voice/kokoro/voices.d.ts.map +1 -0
- package/src/services/voice/kokoro/voices.ts +64 -0
- package/src/services/voice/lifecycle.d.ts +135 -0
- package/src/services/voice/lifecycle.d.ts.map +1 -0
- package/src/services/voice/lifecycle.test.ts +315 -0
- package/src/services/voice/lifecycle.ts +301 -0
- package/src/services/voice/live-diarization-session.d.ts +96 -0
- package/src/services/voice/live-diarization-session.d.ts.map +1 -0
- package/src/services/voice/live-diarization-session.ts +289 -0
- package/src/services/voice/mic-source.d.ts +136 -0
- package/src/services/voice/mic-source.d.ts.map +1 -0
- package/src/services/voice/mic-source.test.ts +210 -0
- package/src/services/voice/mic-source.ts +503 -0
- package/src/services/voice/optimistic-policy.d.ts +109 -0
- package/src/services/voice/optimistic-policy.d.ts.map +1 -0
- package/src/services/voice/optimistic-policy.test.ts +101 -0
- package/src/services/voice/optimistic-policy.ts +192 -0
- package/src/services/voice/optimistic-rollback.ts +343 -0
- package/src/services/voice/partial-stabilizer.d.ts +73 -0
- package/src/services/voice/partial-stabilizer.d.ts.map +1 -0
- package/src/services/voice/partial-stabilizer.test.ts +68 -0
- package/src/services/voice/partial-stabilizer.ts +140 -0
- package/src/services/voice/phoneme-tokenizer.d.ts +49 -0
- package/src/services/voice/phoneme-tokenizer.d.ts.map +1 -0
- package/src/services/voice/phoneme-tokenizer.ts +158 -0
- package/src/services/voice/phrase-cache.d.ts +76 -0
- package/src/services/voice/phrase-cache.d.ts.map +1 -0
- package/src/services/voice/phrase-cache.test.ts +242 -0
- package/src/services/voice/phrase-cache.ts +186 -0
- package/src/services/voice/phrase-chunker.d.ts +62 -0
- package/src/services/voice/phrase-chunker.d.ts.map +1 -0
- package/src/services/voice/phrase-chunker.test.ts +239 -0
- package/src/services/voice/phrase-chunker.ts +281 -0
- package/src/services/voice/pipeline-impls.d.ts +151 -0
- package/src/services/voice/pipeline-impls.d.ts.map +1 -0
- package/src/services/voice/pipeline-impls.l6.test.ts +110 -0
- package/src/services/voice/pipeline-impls.test.ts +292 -0
- package/src/services/voice/pipeline-impls.ts +315 -0
- package/src/services/voice/pipeline.d.ts +216 -0
- package/src/services/voice/pipeline.d.ts.map +1 -0
- package/src/services/voice/pipeline.ts +505 -0
- package/src/services/voice/prefill-client.d.ts +123 -0
- package/src/services/voice/prefill-client.d.ts.map +1 -0
- package/src/services/voice/prefill-client.ts +316 -0
- package/src/services/voice/prefix-preserving-queue.d.ts +113 -0
- package/src/services/voice/prefix-preserving-queue.d.ts.map +1 -0
- package/src/services/voice/prefix-preserving-queue.ts +162 -0
- package/src/services/voice/profile-store.d.ts +248 -0
- package/src/services/voice/profile-store.d.ts.map +1 -0
- package/src/services/voice/profile-store.ts +887 -0
- package/src/services/voice/real-audio-decode.test.ts +148 -0
- package/src/services/voice/ring-buffer.d.ts +40 -0
- package/src/services/voice/ring-buffer.d.ts.map +1 -0
- package/src/services/voice/ring-buffer.test.ts +129 -0
- package/src/services/voice/ring-buffer.ts +123 -0
- package/src/services/voice/rollback-queue.d.ts +24 -0
- package/src/services/voice/rollback-queue.d.ts.map +1 -0
- package/src/services/voice/rollback-queue.ts +74 -0
- package/src/services/voice/samantha-preset-placeholder.d.ts +67 -0
- package/src/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
- package/src/services/voice/samantha-preset-placeholder.test.ts +97 -0
- package/src/services/voice/samantha-preset-placeholder.ts +148 -0
- package/src/services/voice/samantha-preset-regenerator.d.ts +87 -0
- package/src/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
- package/src/services/voice/samantha-preset-regenerator.ts +393 -0
- package/src/services/voice/scheduler.d.ts +146 -0
- package/src/services/voice/scheduler.d.ts.map +1 -0
- package/src/services/voice/scheduler.t2.test.ts +141 -0
- package/src/services/voice/scheduler.ts +927 -0
- package/src/services/voice/shared-resources.d.ts +190 -0
- package/src/services/voice/shared-resources.d.ts.map +1 -0
- package/src/services/voice/shared-resources.ts +320 -0
- package/src/services/voice/speaker/attribution-pipeline.d.ts +74 -0
- package/src/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
- package/src/services/voice/speaker/attribution-pipeline.ts +386 -0
- package/src/services/voice/speaker/diarizer-fused.d.ts +59 -0
- package/src/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
- package/src/services/voice/speaker/diarizer-fused.real.test.ts +100 -0
- package/src/services/voice/speaker/diarizer-fused.ts +154 -0
- package/src/services/voice/speaker/diarizer.d.ts +75 -0
- package/src/services/voice/speaker/diarizer.d.ts.map +1 -0
- package/src/services/voice/speaker/diarizer.ts +218 -0
- package/src/services/voice/speaker/encoder-fused.d.ts +60 -0
- package/src/services/voice/speaker/encoder-fused.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder-fused.real.test.ts +113 -0
- package/src/services/voice/speaker/encoder-fused.ts +138 -0
- package/src/services/voice/speaker/encoder-ggml.d.ts +33 -0
- package/src/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder-ggml.ts +79 -0
- package/src/services/voice/speaker/encoder.d.ts +37 -0
- package/src/services/voice/speaker/encoder.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder.ts +105 -0
- package/src/services/voice/speaker-imprint.d.ts +83 -0
- package/src/services/voice/speaker-imprint.d.ts.map +1 -0
- package/src/services/voice/speaker-imprint.test.ts +185 -0
- package/src/services/voice/speaker-imprint.ts +312 -0
- package/src/services/voice/speaker-preset-cache.d.ts +77 -0
- package/src/services/voice/speaker-preset-cache.d.ts.map +1 -0
- package/src/services/voice/speaker-preset-cache.test.ts +154 -0
- package/src/services/voice/speaker-preset-cache.ts +195 -0
- package/src/services/voice/streaming-asr/streaming-pipeline-adapter.ts +292 -0
- package/src/services/voice/system-audio-sink.d.ts +73 -0
- package/src/services/voice/system-audio-sink.d.ts.map +1 -0
- package/src/services/voice/system-audio-sink.test.ts +29 -0
- package/src/services/voice/system-audio-sink.ts +366 -0
- package/src/services/voice/transcriber.d.ts +244 -0
- package/src/services/voice/transcriber.d.ts.map +1 -0
- package/src/services/voice/transcriber.test.ts +392 -0
- package/src/services/voice/transcriber.ts +704 -0
- package/src/services/voice/transcript-knowledge.d.ts +37 -0
- package/src/services/voice/transcript-knowledge.d.ts.map +1 -0
- package/src/services/voice/transcript-knowledge.test.ts +68 -0
- package/src/services/voice/transcript-knowledge.ts +75 -0
- package/src/services/voice/transcript-service.d.ts +41 -0
- package/src/services/voice/transcript-service.d.ts.map +1 -0
- package/src/services/voice/transcript-service.test.ts +137 -0
- package/src/services/voice/transcript-service.ts +141 -0
- package/src/services/voice/transcript-store.d.ts +53 -0
- package/src/services/voice/transcript-store.d.ts.map +1 -0
- package/src/services/voice/transcript-store.test.ts +153 -0
- package/src/services/voice/transcript-store.ts +132 -0
- package/src/services/voice/turn-controller.d.ts +183 -0
- package/src/services/voice/turn-controller.d.ts.map +1 -0
- package/src/services/voice/turn-controller.test.ts +575 -0
- package/src/services/voice/turn-controller.ts +596 -0
- package/src/services/voice/types.d.ts +643 -0
- package/src/services/voice/types.d.ts.map +1 -0
- package/src/services/voice/types.ts +699 -0
- package/src/services/voice/vad.d.ts +282 -0
- package/src/services/voice/vad.d.ts.map +1 -0
- package/src/services/voice/vad.test.ts +480 -0
- package/src/services/voice/vad.ts +827 -0
- package/src/services/voice/vad.v1-v4.test.ts +222 -0
- package/src/services/voice/voice-budget.d.ts +241 -0
- package/src/services/voice/voice-budget.d.ts.map +1 -0
- package/src/services/voice/voice-budget.test.ts +418 -0
- package/src/services/voice/voice-budget.ts +635 -0
- package/src/services/voice/voice-duet.test.ts +375 -0
- package/src/services/voice/voice-emotion-classifier.d.ts +95 -0
- package/src/services/voice/voice-emotion-classifier.d.ts.map +1 -0
- package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
- package/src/services/voice/voice-emotion-classifier.ts +273 -0
- package/src/services/voice/voice-preset-format.d.ts +158 -0
- package/src/services/voice/voice-preset-format.d.ts.map +1 -0
- package/src/services/voice/voice-preset-format.ts +700 -0
- package/src/services/voice/voice-preset-generator.test.ts +89 -0
- package/src/services/voice/voice-profile-artifact.d.ts +116 -0
- package/src/services/voice/voice-profile-artifact.d.ts.map +1 -0
- package/src/services/voice/voice-profile-artifact.test.ts +138 -0
- package/src/services/voice/voice-profile-artifact.ts +518 -0
- package/src/services/voice/voice-profile-routes.d.ts +83 -0
- package/src/services/voice/voice-profile-routes.d.ts.map +1 -0
- package/src/services/voice/voice-profile-routes.test.ts +429 -0
- package/src/services/voice/voice-profile-routes.ts +425 -0
- package/src/services/voice/voice-scenario.ts +154 -0
- package/src/services/voice/voice-settings.d.ts +82 -0
- package/src/services/voice/voice-settings.d.ts.map +1 -0
- package/src/services/voice/voice-settings.ts +172 -0
- package/src/services/voice/voice-state-machine.d.ts +364 -0
- package/src/services/voice/voice-state-machine.d.ts.map +1 -0
- package/src/services/voice/voice-state-machine.ts +727 -0
- package/src/services/voice/voice-workbench-report.test.ts +168 -0
- package/src/services/voice/voice-workbench-report.ts +326 -0
- package/src/services/voice/voice-workbench.test.ts +158 -0
- package/src/services/voice/voice.test.ts +1070 -0
- package/src/services/voice/wake-word-ggml.d.ts +101 -0
- package/src/services/voice/wake-word-ggml.d.ts.map +1 -0
- package/src/services/voice/wake-word-ggml.ts +320 -0
- package/src/services/voice/wake-word.d.ts +255 -0
- package/src/services/voice/wake-word.d.ts.map +1 -0
- package/src/services/voice/wake-word.test.ts +298 -0
- package/src/services/voice/wake-word.ts +554 -0
- package/src/services/voice/wrap-with-first-line-cache.d.ts +70 -0
- package/src/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
- package/src/services/voice/wrap-with-first-line-cache.ts +267 -0
- package/src/services/voice-model-updater.d.ts +240 -0
- package/src/services/voice-model-updater.d.ts.map +1 -0
- package/src/services/voice-model-updater.ts +724 -0
- package/src/services/voice-prewarm.d.ts +3 -0
- package/src/services/voice-prewarm.d.ts.map +1 -0
- package/src/services/voice-prewarm.ts +51 -0
- package/dist/index.d.ts +0 -37
- package/dist/index.js +0 -1098
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform memory-pressure sources for the Memory Arbiter (WS1).
|
|
3
|
+
*
|
|
4
|
+
* The arbiter consumes a `MemoryPressureSource` interface so it doesn't
|
|
5
|
+
* care whether the signal comes from polling `os.freemem()`, an Android
|
|
6
|
+
* `ComponentCallbacks2.onTrimMemory()` callback, or an iOS
|
|
7
|
+
* `UIApplicationDidReceiveMemoryWarningNotification` subscription.
|
|
8
|
+
*
|
|
9
|
+
* Three concrete implementations live here:
|
|
10
|
+
*
|
|
11
|
+
* 1. `nodeOsPressureSource` — desktop / server. Polls `os.freemem()` /
|
|
12
|
+
* `os.totalmem()` on a fixed cadence (~5 s). Emits `nominal` /
|
|
13
|
+
* `low` / `critical` from a two-threshold high-water mark over total
|
|
14
|
+
* RAM. The polling timer is `unref`'d so it never holds the process
|
|
15
|
+
* open.
|
|
16
|
+
*
|
|
17
|
+
* 2. `capacitorPressureSource` — Capacitor iOS/Android shim. The native
|
|
18
|
+
* side (Android `ComponentCallbacks2.onTrimMemory`, iOS
|
|
19
|
+
* `UIApplicationDidReceiveMemoryWarningNotification`) calls
|
|
20
|
+
* `dispatch(level)` via the bridge, which fans the level out to
|
|
21
|
+
* arbiter listeners. The JS contract is fixed here; the native
|
|
22
|
+
* modules will be wired in WS2 / WS8.
|
|
23
|
+
*
|
|
24
|
+
* 3. `compositePressureSource` — combine sources (e.g. one OS poll +
|
|
25
|
+
* one Capacitor bridge). The composite emits the *worst* reported
|
|
26
|
+
* level so neither signal can mask the other.
|
|
27
|
+
*
|
|
28
|
+
* Pressure semantics — what each level means to the arbiter:
|
|
29
|
+
* - `nominal` → no action; the arbiter may load freely.
|
|
30
|
+
* - `low` → the arbiter SHOULD evict the lowest-priority resident
|
|
31
|
+
* role and may pause optimistic preloads.
|
|
32
|
+
* - `critical` → the arbiter MUST evict every non-text-target role
|
|
33
|
+
* immediately; `acquire()` for non-text capabilities is
|
|
34
|
+
* allowed to throw.
|
|
35
|
+
*
|
|
36
|
+
* No fallback sludge:
|
|
37
|
+
* - When a probe fails (e.g. `os.freemem()` returns NaN under sandboxing),
|
|
38
|
+
* the source emits `nominal` and logs a warning. It does NOT pretend
|
|
39
|
+
* the system is critical and start trashing models.
|
|
40
|
+
* - `dispatch(level)` from a native bridge is trusted; the JS layer does
|
|
41
|
+
* not second-guess it with its own poll.
|
|
42
|
+
*/
|
|
43
|
+
/** Pressure level the arbiter consumes. */
|
|
44
|
+
export type MemoryPressureLevel = "nominal" | "low" | "critical";
|
|
45
|
+
export interface MemoryPressureEvent {
|
|
46
|
+
level: MemoryPressureLevel;
|
|
47
|
+
/** Optional free RAM, MB. Present for poll-based sources; absent for OS-callback bridges. */
|
|
48
|
+
freeMb?: number;
|
|
49
|
+
/** Optional total RAM, MB. */
|
|
50
|
+
totalMb?: number;
|
|
51
|
+
/** Free as a fraction of total (0..1). Present when both above are present. */
|
|
52
|
+
freeFraction?: number;
|
|
53
|
+
/** Source identifier — handy for telemetry. `os-poll` / `capacitor` / `composite`. */
|
|
54
|
+
source: string;
|
|
55
|
+
/** Wall-clock ms when the event was generated. */
|
|
56
|
+
atMs: number;
|
|
57
|
+
}
|
|
58
|
+
export type MemoryPressureListener = (event: MemoryPressureEvent) => void;
|
|
59
|
+
export interface MemoryPressureSource {
|
|
60
|
+
/** Stable identifier for the source (used in telemetry tags). */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Subscribe to pressure events. Returns the unsubscribe fn. */
|
|
63
|
+
subscribe(listener: MemoryPressureListener): () => void;
|
|
64
|
+
/** Begin observing. Idempotent. */
|
|
65
|
+
start(): void;
|
|
66
|
+
/** Stop observing. Idempotent. */
|
|
67
|
+
stop(): void;
|
|
68
|
+
/** Take a one-shot reading without subscribing. May reuse the cached level. */
|
|
69
|
+
current(): MemoryPressureEvent;
|
|
70
|
+
}
|
|
71
|
+
export interface NodeOsPressureConfig {
|
|
72
|
+
/** Poll interval, ms. Default 5000 (5 s); min 500 ms. */
|
|
73
|
+
intervalMs: number;
|
|
74
|
+
/**
|
|
75
|
+
* Below this fraction of total RAM, level becomes `low`. Default 0.15.
|
|
76
|
+
*/
|
|
77
|
+
lowWaterFraction: number;
|
|
78
|
+
/**
|
|
79
|
+
* Below this fraction of total RAM, level becomes `critical`. Default 0.05.
|
|
80
|
+
* Must be < lowWaterFraction; the source enforces this at construction.
|
|
81
|
+
*/
|
|
82
|
+
criticalWaterFraction: number;
|
|
83
|
+
/** Optional injected clock (testing). Defaults to `Date.now()`. */
|
|
84
|
+
now?: () => number;
|
|
85
|
+
}
|
|
86
|
+
export interface NodeOsPressureSources {
|
|
87
|
+
/**
|
|
88
|
+
* Available/total memory in bytes. Defaults to `readSystemMemory()`
|
|
89
|
+
* (`/proc/meminfo` `MemAvailable` on Linux/Android, `os.freemem()` elsewhere).
|
|
90
|
+
*/
|
|
91
|
+
osMemory?: () => {
|
|
92
|
+
freeBytes: number;
|
|
93
|
+
totalBytes: number;
|
|
94
|
+
};
|
|
95
|
+
/** Optional logger; warnings only. */
|
|
96
|
+
logger?: {
|
|
97
|
+
warn?: (m: string) => void;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Polling pressure source for desktop/server. The poll happens on an
|
|
102
|
+
* `unref`'d timer so the process can exit naturally. Listeners only fire
|
|
103
|
+
* when the level *changes* (or the first time after `start()`); raw
|
|
104
|
+
* readings are still available via `current()` for logging.
|
|
105
|
+
*/
|
|
106
|
+
export declare function nodeOsPressureSource(overrides?: Partial<NodeOsPressureConfig>, sources?: NodeOsPressureSources): MemoryPressureSource;
|
|
107
|
+
/**
|
|
108
|
+
* Capacitor-side bridge. The native module dispatches a level whenever
|
|
109
|
+
* the OS hands it a memory-pressure callback (Android: `onTrimMemory`,
|
|
110
|
+
* mapping `TRIM_MEMORY_RUNNING_LOW`/`TRIM_MEMORY_RUNNING_CRITICAL` to
|
|
111
|
+
* `low`/`critical`; iOS: `didReceiveMemoryWarning` → `critical`). The JS
|
|
112
|
+
* surface is `dispatch(level, freeMb?)`. The host wires this to the
|
|
113
|
+
* Capacitor plugin in WS2/WS8; here we own the contract + JS state.
|
|
114
|
+
*/
|
|
115
|
+
export interface CapacitorPressureSource extends MemoryPressureSource {
|
|
116
|
+
/** Called by the Capacitor native bridge whenever the OS signals pressure. */
|
|
117
|
+
dispatch(level: MemoryPressureLevel, freeMb?: number): void;
|
|
118
|
+
}
|
|
119
|
+
export declare function capacitorPressureSource(opts?: {
|
|
120
|
+
now?: () => number;
|
|
121
|
+
}): CapacitorPressureSource;
|
|
122
|
+
/**
|
|
123
|
+
* Combine multiple sources. Subscribers see the *worst* level reported by
|
|
124
|
+
* any underlying source — once a critical signal arrives, the composite
|
|
125
|
+
* stays critical until every source returns to nominal/low.
|
|
126
|
+
*/
|
|
127
|
+
export declare function compositePressureSource(sources: ReadonlyArray<MemoryPressureSource>, opts?: {
|
|
128
|
+
now?: () => number;
|
|
129
|
+
}): MemoryPressureSource;
|
|
130
|
+
//# sourceMappingURL=memory-pressure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-pressure.d.ts","sourceRoot":"","sources":["memory-pressure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,2CAA2C;AAC3C,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACpC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,SAAS,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI,CAAC;IACxD,mCAAmC;IACnC,KAAK,IAAI,IAAI,CAAC;IACd,kCAAkC;IAClC,IAAI,IAAI,IAAI,CAAC;IACb,+EAA+E;IAC/E,OAAO,IAAI,mBAAmB,CAAC;CAC/B;AAID,MAAM,WAAW,oBAAoB;IACpC,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,sCAAsC;IACtC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACxC;AAQD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,EAC7C,OAAO,GAAE,qBAA0B,GACjC,oBAAoB,CAyGtB;AAQD;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACpE,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5D;AAED,wBAAgB,uBAAuB,CACtC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GAC/B,uBAAuB,CAoDzB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,OAAO,EAAE,aAAa,CAAC,oBAAoB,CAAC,EAC5C,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GAC/B,oBAAoB,CAiGtB"}
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform memory-pressure sources for the Memory Arbiter (WS1).
|
|
3
|
+
*
|
|
4
|
+
* The arbiter consumes a `MemoryPressureSource` interface so it doesn't
|
|
5
|
+
* care whether the signal comes from polling `os.freemem()`, an Android
|
|
6
|
+
* `ComponentCallbacks2.onTrimMemory()` callback, or an iOS
|
|
7
|
+
* `UIApplicationDidReceiveMemoryWarningNotification` subscription.
|
|
8
|
+
*
|
|
9
|
+
* Three concrete implementations live here:
|
|
10
|
+
*
|
|
11
|
+
* 1. `nodeOsPressureSource` — desktop / server. Polls `os.freemem()` /
|
|
12
|
+
* `os.totalmem()` on a fixed cadence (~5 s). Emits `nominal` /
|
|
13
|
+
* `low` / `critical` from a two-threshold high-water mark over total
|
|
14
|
+
* RAM. The polling timer is `unref`'d so it never holds the process
|
|
15
|
+
* open.
|
|
16
|
+
*
|
|
17
|
+
* 2. `capacitorPressureSource` — Capacitor iOS/Android shim. The native
|
|
18
|
+
* side (Android `ComponentCallbacks2.onTrimMemory`, iOS
|
|
19
|
+
* `UIApplicationDidReceiveMemoryWarningNotification`) calls
|
|
20
|
+
* `dispatch(level)` via the bridge, which fans the level out to
|
|
21
|
+
* arbiter listeners. The JS contract is fixed here; the native
|
|
22
|
+
* modules will be wired in WS2 / WS8.
|
|
23
|
+
*
|
|
24
|
+
* 3. `compositePressureSource` — combine sources (e.g. one OS poll +
|
|
25
|
+
* one Capacitor bridge). The composite emits the *worst* reported
|
|
26
|
+
* level so neither signal can mask the other.
|
|
27
|
+
*
|
|
28
|
+
* Pressure semantics — what each level means to the arbiter:
|
|
29
|
+
* - `nominal` → no action; the arbiter may load freely.
|
|
30
|
+
* - `low` → the arbiter SHOULD evict the lowest-priority resident
|
|
31
|
+
* role and may pause optimistic preloads.
|
|
32
|
+
* - `critical` → the arbiter MUST evict every non-text-target role
|
|
33
|
+
* immediately; `acquire()` for non-text capabilities is
|
|
34
|
+
* allowed to throw.
|
|
35
|
+
*
|
|
36
|
+
* No fallback sludge:
|
|
37
|
+
* - When a probe fails (e.g. `os.freemem()` returns NaN under sandboxing),
|
|
38
|
+
* the source emits `nominal` and logs a warning. It does NOT pretend
|
|
39
|
+
* the system is critical and start trashing models.
|
|
40
|
+
* - `dispatch(level)` from a native bridge is trusted; the JS layer does
|
|
41
|
+
* not second-guess it with its own poll.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import { readSystemMemory } from "./system-memory";
|
|
45
|
+
|
|
46
|
+
/** Pressure level the arbiter consumes. */
|
|
47
|
+
export type MemoryPressureLevel = "nominal" | "low" | "critical";
|
|
48
|
+
|
|
49
|
+
export interface MemoryPressureEvent {
|
|
50
|
+
level: MemoryPressureLevel;
|
|
51
|
+
/** Optional free RAM, MB. Present for poll-based sources; absent for OS-callback bridges. */
|
|
52
|
+
freeMb?: number;
|
|
53
|
+
/** Optional total RAM, MB. */
|
|
54
|
+
totalMb?: number;
|
|
55
|
+
/** Free as a fraction of total (0..1). Present when both above are present. */
|
|
56
|
+
freeFraction?: number;
|
|
57
|
+
/** Source identifier — handy for telemetry. `os-poll` / `capacitor` / `composite`. */
|
|
58
|
+
source: string;
|
|
59
|
+
/** Wall-clock ms when the event was generated. */
|
|
60
|
+
atMs: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type MemoryPressureListener = (event: MemoryPressureEvent) => void;
|
|
64
|
+
|
|
65
|
+
export interface MemoryPressureSource {
|
|
66
|
+
/** Stable identifier for the source (used in telemetry tags). */
|
|
67
|
+
readonly id: string;
|
|
68
|
+
/** Subscribe to pressure events. Returns the unsubscribe fn. */
|
|
69
|
+
subscribe(listener: MemoryPressureListener): () => void;
|
|
70
|
+
/** Begin observing. Idempotent. */
|
|
71
|
+
start(): void;
|
|
72
|
+
/** Stop observing. Idempotent. */
|
|
73
|
+
stop(): void;
|
|
74
|
+
/** Take a one-shot reading without subscribing. May reuse the cached level. */
|
|
75
|
+
current(): MemoryPressureEvent;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const BYTES_PER_MB = 1024 * 1024;
|
|
79
|
+
|
|
80
|
+
export interface NodeOsPressureConfig {
|
|
81
|
+
/** Poll interval, ms. Default 5000 (5 s); min 500 ms. */
|
|
82
|
+
intervalMs: number;
|
|
83
|
+
/**
|
|
84
|
+
* Below this fraction of total RAM, level becomes `low`. Default 0.15.
|
|
85
|
+
*/
|
|
86
|
+
lowWaterFraction: number;
|
|
87
|
+
/**
|
|
88
|
+
* Below this fraction of total RAM, level becomes `critical`. Default 0.05.
|
|
89
|
+
* Must be < lowWaterFraction; the source enforces this at construction.
|
|
90
|
+
*/
|
|
91
|
+
criticalWaterFraction: number;
|
|
92
|
+
/** Optional injected clock (testing). Defaults to `Date.now()`. */
|
|
93
|
+
now?: () => number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface NodeOsPressureSources {
|
|
97
|
+
/**
|
|
98
|
+
* Available/total memory in bytes. Defaults to `readSystemMemory()`
|
|
99
|
+
* (`/proc/meminfo` `MemAvailable` on Linux/Android, `os.freemem()` elsewhere).
|
|
100
|
+
*/
|
|
101
|
+
osMemory?: () => { freeBytes: number; totalBytes: number };
|
|
102
|
+
/** Optional logger; warnings only. */
|
|
103
|
+
logger?: { warn?: (m: string) => void };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const NODE_OS_DEFAULTS: NodeOsPressureConfig = {
|
|
107
|
+
intervalMs: 5_000,
|
|
108
|
+
lowWaterFraction: 0.15,
|
|
109
|
+
criticalWaterFraction: 0.05,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Polling pressure source for desktop/server. The poll happens on an
|
|
114
|
+
* `unref`'d timer so the process can exit naturally. Listeners only fire
|
|
115
|
+
* when the level *changes* (or the first time after `start()`); raw
|
|
116
|
+
* readings are still available via `current()` for logging.
|
|
117
|
+
*/
|
|
118
|
+
export function nodeOsPressureSource(
|
|
119
|
+
overrides: Partial<NodeOsPressureConfig> = {},
|
|
120
|
+
sources: NodeOsPressureSources = {},
|
|
121
|
+
): MemoryPressureSource {
|
|
122
|
+
const config: NodeOsPressureConfig = {
|
|
123
|
+
intervalMs: Math.max(
|
|
124
|
+
500,
|
|
125
|
+
overrides.intervalMs ?? NODE_OS_DEFAULTS.intervalMs,
|
|
126
|
+
),
|
|
127
|
+
lowWaterFraction: clampFraction(
|
|
128
|
+
overrides.lowWaterFraction,
|
|
129
|
+
NODE_OS_DEFAULTS.lowWaterFraction,
|
|
130
|
+
),
|
|
131
|
+
criticalWaterFraction: clampFraction(
|
|
132
|
+
overrides.criticalWaterFraction,
|
|
133
|
+
NODE_OS_DEFAULTS.criticalWaterFraction,
|
|
134
|
+
),
|
|
135
|
+
now: overrides.now,
|
|
136
|
+
};
|
|
137
|
+
if (config.criticalWaterFraction >= config.lowWaterFraction) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`[memory-pressure] criticalWaterFraction (${config.criticalWaterFraction}) must be < lowWaterFraction (${config.lowWaterFraction})`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const probe = sources.osMemory ?? (() => readSystemMemory());
|
|
143
|
+
const now = config.now ?? (() => Date.now());
|
|
144
|
+
const listeners = new Set<MemoryPressureListener>();
|
|
145
|
+
let timer: NodeJS.Timeout | null = null;
|
|
146
|
+
let lastLevel: MemoryPressureLevel | null = null;
|
|
147
|
+
let lastEvent: MemoryPressureEvent = {
|
|
148
|
+
level: "nominal",
|
|
149
|
+
source: "os-poll",
|
|
150
|
+
atMs: now(),
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const sample = (): MemoryPressureEvent => {
|
|
154
|
+
const { freeBytes, totalBytes } = probe();
|
|
155
|
+
const totalMb = Math.round(totalBytes / BYTES_PER_MB);
|
|
156
|
+
const freeMb = Math.round(freeBytes / BYTES_PER_MB);
|
|
157
|
+
if (!Number.isFinite(freeMb) || !Number.isFinite(totalMb) || totalMb <= 0) {
|
|
158
|
+
sources.logger?.warn?.(
|
|
159
|
+
`[memory-pressure] os memory probe returned invalid (free=${freeMb}, total=${totalMb}); reporting nominal`,
|
|
160
|
+
);
|
|
161
|
+
return { level: "nominal", source: "os-poll", atMs: now() };
|
|
162
|
+
}
|
|
163
|
+
const freeFraction = freeMb / totalMb;
|
|
164
|
+
const level: MemoryPressureLevel =
|
|
165
|
+
freeFraction <= config.criticalWaterFraction
|
|
166
|
+
? "critical"
|
|
167
|
+
: freeFraction <= config.lowWaterFraction
|
|
168
|
+
? "low"
|
|
169
|
+
: "nominal";
|
|
170
|
+
return {
|
|
171
|
+
level,
|
|
172
|
+
freeMb,
|
|
173
|
+
totalMb,
|
|
174
|
+
freeFraction,
|
|
175
|
+
source: "os-poll",
|
|
176
|
+
atMs: now(),
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const tick = (): void => {
|
|
181
|
+
const event = sample();
|
|
182
|
+
lastEvent = event;
|
|
183
|
+
if (lastLevel === event.level) return;
|
|
184
|
+
lastLevel = event.level;
|
|
185
|
+
for (const listener of listeners) {
|
|
186
|
+
try {
|
|
187
|
+
listener(event);
|
|
188
|
+
} catch {
|
|
189
|
+
// Listener faults should never crash the poller. Drop it.
|
|
190
|
+
listeners.delete(listener);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
id: "os-poll",
|
|
197
|
+
subscribe(listener) {
|
|
198
|
+
listeners.add(listener);
|
|
199
|
+
// Fire the current level immediately so subscribers can react without
|
|
200
|
+
// waiting a full interval.
|
|
201
|
+
try {
|
|
202
|
+
listener(lastEvent);
|
|
203
|
+
} catch {
|
|
204
|
+
listeners.delete(listener);
|
|
205
|
+
}
|
|
206
|
+
return () => {
|
|
207
|
+
listeners.delete(listener);
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
start() {
|
|
211
|
+
if (timer) return;
|
|
212
|
+
tick();
|
|
213
|
+
const t = setInterval(tick, config.intervalMs);
|
|
214
|
+
t.unref();
|
|
215
|
+
timer = t;
|
|
216
|
+
},
|
|
217
|
+
stop() {
|
|
218
|
+
if (!timer) return;
|
|
219
|
+
clearInterval(timer);
|
|
220
|
+
timer = null;
|
|
221
|
+
},
|
|
222
|
+
current(): MemoryPressureEvent {
|
|
223
|
+
return sample();
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function clampFraction(value: number | undefined, fallback: number): number {
|
|
229
|
+
if (value === undefined) return fallback;
|
|
230
|
+
if (!Number.isFinite(value) || value <= 0 || value >= 1) return fallback;
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Capacitor-side bridge. The native module dispatches a level whenever
|
|
236
|
+
* the OS hands it a memory-pressure callback (Android: `onTrimMemory`,
|
|
237
|
+
* mapping `TRIM_MEMORY_RUNNING_LOW`/`TRIM_MEMORY_RUNNING_CRITICAL` to
|
|
238
|
+
* `low`/`critical`; iOS: `didReceiveMemoryWarning` → `critical`). The JS
|
|
239
|
+
* surface is `dispatch(level, freeMb?)`. The host wires this to the
|
|
240
|
+
* Capacitor plugin in WS2/WS8; here we own the contract + JS state.
|
|
241
|
+
*/
|
|
242
|
+
export interface CapacitorPressureSource extends MemoryPressureSource {
|
|
243
|
+
/** Called by the Capacitor native bridge whenever the OS signals pressure. */
|
|
244
|
+
dispatch(level: MemoryPressureLevel, freeMb?: number): void;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function capacitorPressureSource(
|
|
248
|
+
opts: { now?: () => number } = {},
|
|
249
|
+
): CapacitorPressureSource {
|
|
250
|
+
const now = opts.now ?? (() => Date.now());
|
|
251
|
+
const listeners = new Set<MemoryPressureListener>();
|
|
252
|
+
let lastEvent: MemoryPressureEvent = {
|
|
253
|
+
level: "nominal",
|
|
254
|
+
source: "capacitor",
|
|
255
|
+
atMs: now(),
|
|
256
|
+
};
|
|
257
|
+
let started = false;
|
|
258
|
+
return {
|
|
259
|
+
id: "capacitor",
|
|
260
|
+
subscribe(listener) {
|
|
261
|
+
listeners.add(listener);
|
|
262
|
+
try {
|
|
263
|
+
listener(lastEvent);
|
|
264
|
+
} catch {
|
|
265
|
+
listeners.delete(listener);
|
|
266
|
+
}
|
|
267
|
+
return () => {
|
|
268
|
+
listeners.delete(listener);
|
|
269
|
+
};
|
|
270
|
+
},
|
|
271
|
+
start() {
|
|
272
|
+
started = true;
|
|
273
|
+
},
|
|
274
|
+
stop() {
|
|
275
|
+
started = false;
|
|
276
|
+
},
|
|
277
|
+
current(): MemoryPressureEvent {
|
|
278
|
+
return lastEvent;
|
|
279
|
+
},
|
|
280
|
+
dispatch(level: MemoryPressureLevel, freeMb?: number): void {
|
|
281
|
+
if (!started) {
|
|
282
|
+
// Allow dispatch even before start() so the boot path can pre-load
|
|
283
|
+
// state from a recent OS callback; we just don't gate on it.
|
|
284
|
+
}
|
|
285
|
+
const event: MemoryPressureEvent = {
|
|
286
|
+
level,
|
|
287
|
+
source: "capacitor",
|
|
288
|
+
atMs: now(),
|
|
289
|
+
...(freeMb !== undefined ? { freeMb } : {}),
|
|
290
|
+
};
|
|
291
|
+
lastEvent = event;
|
|
292
|
+
for (const listener of listeners) {
|
|
293
|
+
try {
|
|
294
|
+
listener(event);
|
|
295
|
+
} catch {
|
|
296
|
+
listeners.delete(listener);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Combine multiple sources. Subscribers see the *worst* level reported by
|
|
305
|
+
* any underlying source — once a critical signal arrives, the composite
|
|
306
|
+
* stays critical until every source returns to nominal/low.
|
|
307
|
+
*/
|
|
308
|
+
export function compositePressureSource(
|
|
309
|
+
sources: ReadonlyArray<MemoryPressureSource>,
|
|
310
|
+
opts: { now?: () => number } = {},
|
|
311
|
+
): MemoryPressureSource {
|
|
312
|
+
const now = opts.now ?? (() => Date.now());
|
|
313
|
+
// Index by position rather than by `source.id` — two underlying sources of
|
|
314
|
+
// the same kind (e.g. two `capacitor` bridges) must each get their own
|
|
315
|
+
// slot, otherwise the second one overwrites the first and we lose visibility
|
|
316
|
+
// into the first source's level.
|
|
317
|
+
const latestBySlot: (MemoryPressureEvent | null)[] = sources.map(() => null);
|
|
318
|
+
const listeners = new Set<MemoryPressureListener>();
|
|
319
|
+
const subs: Array<() => void> = [];
|
|
320
|
+
|
|
321
|
+
const worst = (): MemoryPressureEvent => {
|
|
322
|
+
let level: MemoryPressureLevel = "nominal";
|
|
323
|
+
let freeMb: number | undefined;
|
|
324
|
+
let totalMb: number | undefined;
|
|
325
|
+
for (const e of latestBySlot) {
|
|
326
|
+
if (!e) continue;
|
|
327
|
+
if (rank(e.level) > rank(level)) {
|
|
328
|
+
level = e.level;
|
|
329
|
+
freeMb = e.freeMb;
|
|
330
|
+
totalMb = e.totalMb;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const event: MemoryPressureEvent = {
|
|
334
|
+
level,
|
|
335
|
+
source: "composite",
|
|
336
|
+
atMs: now(),
|
|
337
|
+
};
|
|
338
|
+
if (freeMb !== undefined) event.freeMb = freeMb;
|
|
339
|
+
if (totalMb !== undefined) event.totalMb = totalMb;
|
|
340
|
+
if (freeMb !== undefined && totalMb !== undefined && totalMb > 0) {
|
|
341
|
+
event.freeFraction = freeMb / totalMb;
|
|
342
|
+
}
|
|
343
|
+
return event;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const fanout = (): void => {
|
|
347
|
+
const event = worst();
|
|
348
|
+
for (const listener of listeners) {
|
|
349
|
+
try {
|
|
350
|
+
listener(event);
|
|
351
|
+
} catch {
|
|
352
|
+
listeners.delete(listener);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
let started = false;
|
|
358
|
+
let lastLevel: MemoryPressureLevel | null = null;
|
|
359
|
+
|
|
360
|
+
const handleAt = (slot: number) => (e: MemoryPressureEvent) => {
|
|
361
|
+
latestBySlot[slot] = e;
|
|
362
|
+
const w = worst();
|
|
363
|
+
if (lastLevel === w.level) return;
|
|
364
|
+
lastLevel = w.level;
|
|
365
|
+
fanout();
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
return {
|
|
369
|
+
id: "composite",
|
|
370
|
+
subscribe(listener) {
|
|
371
|
+
listeners.add(listener);
|
|
372
|
+
try {
|
|
373
|
+
listener(worst());
|
|
374
|
+
} catch {
|
|
375
|
+
listeners.delete(listener);
|
|
376
|
+
}
|
|
377
|
+
return () => {
|
|
378
|
+
listeners.delete(listener);
|
|
379
|
+
};
|
|
380
|
+
},
|
|
381
|
+
start() {
|
|
382
|
+
if (started) return;
|
|
383
|
+
started = true;
|
|
384
|
+
sources.forEach((s, idx) => {
|
|
385
|
+
s.start();
|
|
386
|
+
subs.push(s.subscribe(handleAt(idx)));
|
|
387
|
+
});
|
|
388
|
+
},
|
|
389
|
+
stop() {
|
|
390
|
+
if (!started) return;
|
|
391
|
+
started = false;
|
|
392
|
+
while (subs.length) {
|
|
393
|
+
const u = subs.pop();
|
|
394
|
+
try {
|
|
395
|
+
u?.();
|
|
396
|
+
} catch {
|
|
397
|
+
// Ignore — unsubscribe must never throw out.
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
for (const s of sources) s.stop();
|
|
401
|
+
for (let i = 0; i < latestBySlot.length; i++) latestBySlot[i] = null;
|
|
402
|
+
lastLevel = null;
|
|
403
|
+
},
|
|
404
|
+
current(): MemoryPressureEvent {
|
|
405
|
+
return worst();
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function rank(level: MemoryPressureLevel): number {
|
|
411
|
+
if (level === "critical") return 2;
|
|
412
|
+
if (level === "low") return 1;
|
|
413
|
+
return 0;
|
|
414
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type MtpDoctorCheckStatus = "pass" | "warn" | "fail";
|
|
2
|
+
export interface MtpDoctorCheck {
|
|
3
|
+
label: string;
|
|
4
|
+
status: MtpDoctorCheckStatus;
|
|
5
|
+
detail: string;
|
|
6
|
+
fix?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MtpDoctorReport {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
checks: MtpDoctorCheck[];
|
|
11
|
+
}
|
|
12
|
+
export declare function runMtpDoctor(): Promise<MtpDoctorReport>;
|
|
13
|
+
//# sourceMappingURL=mtp-doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mtp-doctor.d.ts","sourceRoot":"","sources":["mtp-doctor.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CA4D7D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { MODEL_CATALOG } from "./catalog";
|
|
2
|
+
import { probeHardware } from "./hardware";
|
|
3
|
+
|
|
4
|
+
export type MtpDoctorCheckStatus = "pass" | "warn" | "fail";
|
|
5
|
+
|
|
6
|
+
export interface MtpDoctorCheck {
|
|
7
|
+
label: string;
|
|
8
|
+
status: MtpDoctorCheckStatus;
|
|
9
|
+
detail: string;
|
|
10
|
+
fix?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface MtpDoctorReport {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
checks: MtpDoctorCheck[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function runMtpDoctor(): Promise<MtpDoctorReport> {
|
|
19
|
+
const checks: MtpDoctorCheck[] = [];
|
|
20
|
+
const mtpCatalogEntries = MODEL_CATALOG.filter(
|
|
21
|
+
(entry) => entry.runtime?.mtp !== undefined,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
checks.push({
|
|
25
|
+
label: "catalog metadata",
|
|
26
|
+
status: mtpCatalogEntries.length > 0 ? "pass" : "fail",
|
|
27
|
+
detail:
|
|
28
|
+
mtpCatalogEntries.length > 0
|
|
29
|
+
? `${mtpCatalogEntries.length} MTP-capable model entries found`
|
|
30
|
+
: "No catalog entries advertise runtime.mtp",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const hardware = await probeHardware();
|
|
35
|
+
const backend = hardware.gpu?.backend ?? "cpu";
|
|
36
|
+
checks.push({
|
|
37
|
+
label: "hardware probe",
|
|
38
|
+
status: "pass",
|
|
39
|
+
detail: `${hardware.platform}/${hardware.arch}, backend=${backend}, ram=${hardware.totalRamGb}GB`,
|
|
40
|
+
});
|
|
41
|
+
if (backend === "cpu") {
|
|
42
|
+
checks.push({
|
|
43
|
+
label: "accelerator",
|
|
44
|
+
status: "warn",
|
|
45
|
+
detail:
|
|
46
|
+
"No GPU backend detected; MTP can run but may not improve latency",
|
|
47
|
+
fix: "install a Metal/CUDA/Vulkan-capable llama.cpp runtime",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
checks.push({
|
|
52
|
+
label: "hardware probe",
|
|
53
|
+
status: "warn",
|
|
54
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
checks.push({
|
|
59
|
+
label: "runtime mode",
|
|
60
|
+
status:
|
|
61
|
+
process.env.ELIZA_LOCAL_INFERENCE_BACKEND === "capacitor-llama"
|
|
62
|
+
? "warn"
|
|
63
|
+
: "pass",
|
|
64
|
+
detail:
|
|
65
|
+
process.env.ELIZA_LOCAL_INFERENCE_BACKEND === "capacitor-llama"
|
|
66
|
+
? "Backend override forces capacitor-llama, bypassing optimized llama.cpp MTP"
|
|
67
|
+
: "No backend override is blocking optimized llama.cpp selection",
|
|
68
|
+
fix:
|
|
69
|
+
process.env.ELIZA_LOCAL_INFERENCE_BACKEND === "capacitor-llama"
|
|
70
|
+
? "unset ELIZA_LOCAL_INFERENCE_BACKEND"
|
|
71
|
+
: undefined,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
ok: checks.every((check) => check.status !== "fail"),
|
|
76
|
+
checks,
|
|
77
|
+
};
|
|
78
|
+
}
|