@bendyline/gezel-inference 1.0.1 → 1.0.3
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/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/manifest.json +120 -0
- package/dist/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/versions/1.0.0/manifest.json +21 -0
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +6 -5
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.2/manifest.json +27 -0
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.3/manifest.json +27 -0
- package/dist/catalog/chat-models/index.json +1 -1
- package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/manifest.json +157 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/versions/1.0.0/manifest.json +30 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/manifest.json +156 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/versions/1.0.0/manifest.json +28 -0
- package/dist/catalog/chat-models/raw-index.json +1 -1
- package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/keywords.json +56 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/keywords.json +13 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/keywords.json +14 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/keywords.json +17 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/keywords.json +12 -0
- package/dist/catalog/knowledge-catalogs/index.json +1 -1
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/keywords.json +21 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/keywords.json +27 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/keywords.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/keywords.json +26 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/keywords.json +28 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/keywords.json +29 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/keywords.json +21 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/keywords.json +14 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/keywords.json +20 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/keywords.json +24 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/keywords.json +27 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/keywords.json +18 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/keywords.json +28 -0
- package/dist/catalog/knowledge-catalogs/raw-index.json +1 -1
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/keywords.json +1700 -0
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/keywords.json +750 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/keywords.json +1281 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/keywords.json +1125 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/keywords.json +3287 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/keywords.json +1835 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/keywords.json +1184 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/keywords.json +1503 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/keywords.json +2836 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/keywords.json +813 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/keywords.json +2082 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/keywords.json +1481 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/keywords.json +1272 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/keywords.json +758 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/keywords.json +896 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/keywords.json +1281 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/keywords.json +346 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/keywords.json +2688 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/keywords.json +973 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/keywords.json +937 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/keywords.json +608 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/keywords.json +633 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/keywords.json +2697 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/keywords.json +606 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/keywords.json +564 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe/keywords.json +3247 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/manifest.json +47 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/manifest.json +47 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/versions/2026.10.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/keywords.json +5437 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.10.1/manifest.json +181 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.10.1/manifest.json +181 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.10.1/manifest.json +217 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/keywords.json +5583 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.10.1/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/keywords.json +6386 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +2 -2
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.10.1/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/keywords.json +5672 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.10.1/manifest.json +137 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/manifest.json +68 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/versions/2026.10.1/manifest.json +217 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/manifest.json +68 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/versions/2026.10.1/manifest.json +217 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.10.1/manifest.json +141 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/keywords.json +5719 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.10.1/manifest.json +193 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.10.1/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/keywords.json +16009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/keywords.json +5843 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.10.1/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/keywords.json +6264 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.10.1/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/manifest.json +66 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/versions/2026.10.1/manifest.json +209 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/manifest.json +61 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/versions/2026.10.1/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/versions/2026.10.1/manifest.json +201 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/manifest.json +60 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/manifest.json +55 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/versions/2026.10.1/manifest.json +165 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/manifest.json +63 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/versions/2026.10.1/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/versions/2026.10.1/manifest.json +201 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/manifest.json +65 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/versions/2026.10.1/manifest.json +205 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/manifest.json +73 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/versions/2026.10.1/manifest.json +237 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/keywords.json +5447 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.10.1/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.10.1/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/keywords.json +4009 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/keywords.json +5209 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.10.1/manifest.json +193 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/keywords.json +6537 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.10.1/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/keywords.json +5989 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +1 -1
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.10.1/manifest.json +189 -0
- package/dist/catalog/provenance.json +1 -1
- package/dist/engines/native-file-manifest.json +483 -413
- package/dist/engines/native-manifest.d.ts +4 -4
- package/dist/engines/native-manifest.js +36 -34
- package/dist/engines/resolver.js +3 -1
- package/dist/fs/atomic.d.ts +4 -1
- package/dist/fs/atomic.js +7 -1
- package/dist/http/openai-compat/chat-target.d.ts +1 -1
- package/dist/http/openai-compat/chat-target.js +1 -1
- package/dist/http/openai-compat/engine-failure.d.ts +25 -0
- package/dist/http/openai-compat/engine-failure.js +76 -0
- package/dist/http/openai-compat/responses-streaming.js +2 -1
- package/dist/http/openai-compat/responses-translate.d.ts +1 -1
- package/dist/http/openai-compat/translate.d.ts +1 -1
- package/dist/http/routes/engines.js +35 -0
- package/dist/http/routes/v1-chat.js +11 -2
- package/dist/http/routes/v1-knowledge.js +4 -0
- package/dist/http/routes/v1-models.js +6 -4
- package/dist/http/routes/v1-responses.d.ts +1 -1
- package/dist/http/routes/v1-responses.js +7 -1
- package/dist/inference-service.d.ts +6 -1
- package/dist/inference-service.js +20 -9
- package/dist/knowledge/catalog-host.d.ts +9 -1
- package/dist/knowledge/catalog-host.js +2 -0
- package/dist/knowledge/manager.d.ts +21 -0
- package/dist/knowledge/manager.js +85 -7
- package/dist/knowledge/search-worker.d.ts +1 -1
- package/dist/knowledge/spatial-query.d.ts +2 -3
- package/dist/knowledge/spatial-query.js +12 -6
- package/dist/knowledge/worker-host.js +2 -0
- package/dist/memory/embed-core.d.ts +16 -0
- package/dist/memory/embed-core.js +31 -0
- package/dist/memory/embed-worker.d.ts +7 -3
- package/dist/memory/embed-worker.js +13 -4
- package/dist/memory/embeddings.d.ts +17 -2
- package/dist/memory/embeddings.js +36 -7
- package/dist/models/ensure.d.ts +2 -0
- package/dist/models/ensure.js +9 -0
- package/dist/perf/responsiveness.d.ts +14 -1
- package/dist/perf/responsiveness.js +81 -10
- package/dist/providers/audio/kokoro-frontend.js +1 -1
- package/dist/providers/ds4/build-provider.js +6 -0
- package/dist/providers/llama-cpp/backend-health.d.ts +30 -0
- package/dist/providers/llama-cpp/backend-health.js +64 -0
- package/dist/providers/llama-cpp/backend-quarantine.d.ts +40 -0
- package/dist/providers/llama-cpp/backend-quarantine.js +100 -0
- package/dist/providers/llama-cpp/build-provider.js +247 -199
- package/dist/providers/llama-cpp/cache-adapter.d.ts +7 -1
- package/dist/providers/llama-cpp/cache-adapter.js +11 -1
- package/dist/providers/llama-cpp/devices.d.ts +22 -2
- package/dist/providers/llama-cpp/devices.js +48 -5
- package/dist/providers/llama-cpp/engine-flags.d.ts +0 -18
- package/dist/providers/llama-cpp/engine-flags.js +12 -18
- package/dist/providers/llama-cpp/gguf-metadata.js +20 -3
- package/dist/providers/llama-cpp/gpu-startup-watch.d.ts +41 -0
- package/dist/providers/llama-cpp/gpu-startup-watch.js +58 -0
- package/dist/providers/llama-cpp/models.d.ts +6 -0
- package/dist/providers/llama-cpp/models.js +23 -2
- package/dist/providers/llama-cpp/offload-planner.d.ts +26 -18
- package/dist/providers/llama-cpp/offload-planner.js +30 -14
- package/dist/providers/llama-cpp/provider.d.ts +22 -3
- package/dist/providers/llama-cpp/provider.js +39 -3
- package/dist/providers/mlx/provider.js +5 -6
- package/dist/providers/mlx/python/qwen4_ple.py +9 -2
- package/dist/providers/mlx/reasoning-stream.d.ts +15 -0
- package/dist/providers/mlx/reasoning-stream.js +35 -0
- package/dist/providers/native/capacity-broker.d.ts +21 -15
- package/dist/providers/native/capacity-broker.js +25 -13
- package/dist/providers/native/capacity-budget.d.ts +35 -3
- package/dist/providers/native/capacity-budget.js +49 -5
- package/dist/providers/native/device-capacity.d.ts +1 -1
- package/dist/providers/native/device-capacity.js +23 -5
- package/dist/providers/native/local-engine-runtime.js +31 -31
- package/dist/providers/native/measured-budget.js +2 -0
- package/dist/providers/native/supervisor.d.ts +25 -0
- package/dist/providers/native/supervisor.js +62 -8
- package/dist/providers/queue.d.ts +9 -2
- package/dist/providers/queue.js +17 -2
- package/dist/providers/session-hooks.d.ts +4 -1
- package/dist/system/amdgpu-adapters.d.ts +18 -0
- package/dist/system/amdgpu-adapters.js +55 -0
- package/dist/system/gpu-carve-out.d.ts +84 -0
- package/dist/system/gpu-carve-out.js +111 -0
- package/dist/system/memory.d.ts +17 -1
- package/dist/system/memory.js +94 -13
- package/dist/transformers-cache.d.ts +2 -0
- package/dist/transformers-cache.js +6 -3
- package/package.json +5 -5
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* lazily respawn its process (see {@link shutdown}).
|
|
23
23
|
*/
|
|
24
24
|
import { type DisableThinkingRequestShape, LlamaCppSession, type ReasoningEffortRequestShape, type ToolGrammarFallback } from '@bendyline/gezel/local-loop';
|
|
25
|
+
import type { StartupCrashVerdict } from '@bendyline/gezel/native';
|
|
25
26
|
import type { GpuArbiter } from '../gpu-arbiter.js';
|
|
26
27
|
import type { NativeEngineLifecycleSnapshot, NativeEngineSupervisor } from '../native/supervisor.js';
|
|
27
28
|
import { ProviderQueue } from '../queue.js';
|
|
@@ -55,6 +56,7 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
55
56
|
*/
|
|
56
57
|
private toolGrammarFloor;
|
|
57
58
|
private readonly supervisor?;
|
|
59
|
+
private readonly startupCrashVerdict?;
|
|
58
60
|
/** Explicit base URL when no supervisor is managing the process. */
|
|
59
61
|
private readonly externalBaseUrl?;
|
|
60
62
|
private readonly defaultModel;
|
|
@@ -141,7 +143,9 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
141
143
|
/** Request-scoped effort shape for compatible wrappers such as ds4-server. */
|
|
142
144
|
private readonly reasoningEffortRequestShape;
|
|
143
145
|
/** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
|
|
144
|
-
private
|
|
146
|
+
private batchMaxConcurrency;
|
|
147
|
+
/** See the `reserveBackgroundSlot` constructor opt. */
|
|
148
|
+
private readonly reservesBackgroundLane;
|
|
145
149
|
/**
|
|
146
150
|
* Number of real llama-server request slots (`--parallel`). The provider
|
|
147
151
|
* queue can intentionally be wider than this by one reserved background
|
|
@@ -150,7 +154,7 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
150
154
|
* boundary: cache slot save/restore plus the streamed engine request must
|
|
151
155
|
* never exceed the slots the native server actually owns.
|
|
152
156
|
*/
|
|
153
|
-
private
|
|
157
|
+
private engineRequestWidth;
|
|
154
158
|
private engineRequestsActive;
|
|
155
159
|
private readonly engineRequestWaiters;
|
|
156
160
|
/**
|
|
@@ -242,6 +246,12 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
242
246
|
* `baseUrl`.
|
|
243
247
|
*/
|
|
244
248
|
supervisor?: NativeEngineSupervisor;
|
|
249
|
+
/**
|
|
250
|
+
* What a startup crash did to its build's standing (strike or
|
|
251
|
+
* quarantine), looked up by incident id when a start fails, so the error
|
|
252
|
+
* says what the next request will actually do.
|
|
253
|
+
*/
|
|
254
|
+
startupCrashVerdict?: (incidentId: string) => StartupCrashVerdict | undefined;
|
|
245
255
|
/**
|
|
246
256
|
* Fixed base URL of an already-running llama-server. Used in
|
|
247
257
|
* dev iteration and LAN-shared setups. Mutually exclusive with
|
|
@@ -401,7 +411,7 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
401
411
|
*/
|
|
402
412
|
private cacheAdapter;
|
|
403
413
|
private slotSavePath?;
|
|
404
|
-
private
|
|
414
|
+
private launchedSlots;
|
|
405
415
|
setCacheAdapter(adapter: import('./cache-adapter.js').LlamaCppCacheAdapter): void;
|
|
406
416
|
getCacheAdapter(): import('./cache-adapter.js').LlamaCppCacheAdapter | null;
|
|
407
417
|
/**
|
|
@@ -422,6 +432,15 @@ export declare class LlamaCppProvider implements LLMProvider {
|
|
|
422
432
|
* would 400 silently, and the debug probe's slot narration was fiction.
|
|
423
433
|
*/
|
|
424
434
|
getLaunchedSlots(): number;
|
|
435
|
+
/**
|
|
436
|
+
* Follow a supervised engine that is relaunching with fewer `--parallel`
|
|
437
|
+
* slots because the wider launch ran the GPU out of memory. Runs between
|
|
438
|
+
* the failed start and the retry, while the request that asked for the
|
|
439
|
+
* engine still holds its lease. Refused when more requests hold leases
|
|
440
|
+
* than the narrower engine has slots: two turns on one slot would save and
|
|
441
|
+
* restore it under each other.
|
|
442
|
+
*/
|
|
443
|
+
narrowEngineSlots(slots: number): boolean;
|
|
425
444
|
/**
|
|
426
445
|
* Claim one physical llama-server request slot.
|
|
427
446
|
*
|
|
@@ -25,7 +25,7 @@ import * as os from 'node:os';
|
|
|
25
25
|
import { createLogger } from '@bendyline/gezel';
|
|
26
26
|
import { DEFAULT_NUM_CTX, LlamaCppSession, NativeEngineCrashedError, TOOL_GRAMMAR_FALLBACK_ORDER, constrainedToolNoSignalMsForModel, engineRequestAbortError, parseEnvMs, } from '@bendyline/gezel/local-loop';
|
|
27
27
|
import { ProviderDisposedError } from '../provider-disposal.js';
|
|
28
|
-
import { ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, defaultAmbientQuietMs, } from '../queue.js';
|
|
28
|
+
import { ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, defaultAmbientQuietMs, defaultQueueYieldQuantumMs, } from '../queue.js';
|
|
29
29
|
import { createToolExecutor } from '../tool-executor.js';
|
|
30
30
|
import { classifyStartupLine } from './stdout-parser.js';
|
|
31
31
|
// The session and its helpers live in core so a phone runs the same loop.
|
|
@@ -57,6 +57,7 @@ export class LlamaCppProvider {
|
|
|
57
57
|
*/
|
|
58
58
|
toolGrammarFloor = null;
|
|
59
59
|
supervisor;
|
|
60
|
+
startupCrashVerdict;
|
|
60
61
|
/** Explicit base URL when no supervisor is managing the process. */
|
|
61
62
|
externalBaseUrl;
|
|
62
63
|
defaultModel;
|
|
@@ -146,6 +147,8 @@ export class LlamaCppProvider {
|
|
|
146
147
|
reasoningEffortRequestShape;
|
|
147
148
|
/** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
|
|
148
149
|
batchMaxConcurrency;
|
|
150
|
+
/** See the `reserveBackgroundSlot` constructor opt. */
|
|
151
|
+
reservesBackgroundLane;
|
|
149
152
|
/**
|
|
150
153
|
* Number of real llama-server request slots (`--parallel`). The provider
|
|
151
154
|
* queue can intentionally be wider than this by one reserved background
|
|
@@ -247,6 +250,8 @@ export class LlamaCppProvider {
|
|
|
247
250
|
}
|
|
248
251
|
if (opts.supervisor)
|
|
249
252
|
this.supervisor = opts.supervisor;
|
|
253
|
+
if (opts.startupCrashVerdict)
|
|
254
|
+
this.startupCrashVerdict = opts.startupCrashVerdict;
|
|
250
255
|
if (opts.baseUrl)
|
|
251
256
|
this.externalBaseUrl = opts.baseUrl.replace(/\/+$/, '');
|
|
252
257
|
// Only register an evictor when we own the lifecycle. External-baseUrl
|
|
@@ -338,7 +343,10 @@ export class LlamaCppProvider {
|
|
|
338
343
|
// mid-turn compaction wedges the turn, the same failure the MLX
|
|
339
344
|
// single-slot path hit. See the matching note in the MLX provider.
|
|
340
345
|
const interactiveConcurrency = batchMax;
|
|
341
|
-
|
|
346
|
+
this.reservesBackgroundLane = opts.reserveBackgroundSlot !== false;
|
|
347
|
+
const queueConcurrency = this.reservesBackgroundLane
|
|
348
|
+
? Math.max(slots, interactiveConcurrency + 1)
|
|
349
|
+
: slots;
|
|
342
350
|
this.queue = new ProviderQueue({
|
|
343
351
|
// llama-server is launched with `--parallel ${slots}` (see
|
|
344
352
|
// `buildLlamaCppProvider` in chat/manager.ts) so the engine has matching
|
|
@@ -361,6 +369,9 @@ export class LlamaCppProvider {
|
|
|
361
369
|
// a multi-minute chore turn never lands right before their next
|
|
362
370
|
// move. Applies to ds4 too — its provider wraps this class.
|
|
363
371
|
ambientQuietMs: defaultAmbientQuietMs(),
|
|
372
|
+
// A tool loop hands the slot to a waiting conversation between
|
|
373
|
+
// iterations once it has held it this long (see `QueueLease`).
|
|
374
|
+
yieldQuantumMs: defaultQueueYieldQuantumMs(),
|
|
364
375
|
});
|
|
365
376
|
}
|
|
366
377
|
/**
|
|
@@ -455,6 +466,31 @@ export class LlamaCppProvider {
|
|
|
455
466
|
getLaunchedSlots() {
|
|
456
467
|
return this.launchedSlots;
|
|
457
468
|
}
|
|
469
|
+
/**
|
|
470
|
+
* Follow a supervised engine that is relaunching with fewer `--parallel`
|
|
471
|
+
* slots because the wider launch ran the GPU out of memory. Runs between
|
|
472
|
+
* the failed start and the retry, while the request that asked for the
|
|
473
|
+
* engine still holds its lease. Refused when more requests hold leases
|
|
474
|
+
* than the narrower engine has slots: two turns on one slot would save and
|
|
475
|
+
* restore it under each other.
|
|
476
|
+
*/
|
|
477
|
+
narrowEngineSlots(slots) {
|
|
478
|
+
const next = Math.max(1, Math.floor(slots));
|
|
479
|
+
if (next >= this.launchedSlots || this.engineRequestsActive > next)
|
|
480
|
+
return false;
|
|
481
|
+
this.launchedSlots = next;
|
|
482
|
+
this.engineRequestWidth = next;
|
|
483
|
+
this.batchMaxConcurrency = Math.min(this.batchMaxConcurrency, next);
|
|
484
|
+
this.queue.narrow({
|
|
485
|
+
concurrency: this.reservesBackgroundLane
|
|
486
|
+
? Math.max(next, this.batchMaxConcurrency + 1)
|
|
487
|
+
: next,
|
|
488
|
+
interactiveConcurrency: this.batchMaxConcurrency,
|
|
489
|
+
backgroundConcurrency: backgroundLaneCap(next),
|
|
490
|
+
});
|
|
491
|
+
this.cacheAdapter?.setSlotCount(next);
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
458
494
|
/**
|
|
459
495
|
* Claim one physical llama-server request slot.
|
|
460
496
|
*
|
|
@@ -848,7 +884,7 @@ export class LlamaCppProvider {
|
|
|
848
884
|
catch (err) {
|
|
849
885
|
const nativeExit = this.supervisor.lastExitSnapshot?.();
|
|
850
886
|
if (nativeExit && !nativeExit.expected && nativeExit.exitedAt >= ensureStartedAt) {
|
|
851
|
-
throw new NativeEngineCrashedError(nativeExit, err);
|
|
887
|
+
throw new NativeEngineCrashedError(nativeExit, err, this.startupCrashVerdict?.(nativeExit.incidentId));
|
|
852
888
|
}
|
|
853
889
|
throw err;
|
|
854
890
|
}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
29
29
|
import { randomUUID } from 'node:crypto';
|
|
30
|
-
import { AwakeBudget, autoCompactedNotice, createAwakeTimeout, createLogger, leaksUntaggedReasoning, turnCancelledMessage, } from '@bendyline/gezel';
|
|
30
|
+
import { AwakeBudget, autoCompactedNotice, createAwakeTimeout, createLogger, isProjectStartingCall, leaksUntaggedReasoning, turnCancelledMessage, } from '@bendyline/gezel';
|
|
31
31
|
import { leadingSystemMessages, standaloneTurnMessages, toolSurfaceSize, } from '@bendyline/gezel/local-loop';
|
|
32
32
|
import { computeToolBudgetChars } from '@bendyline/gezel/local-loop';
|
|
33
33
|
import { extractReasoningWithProfile, profileBehaviorConfig, profileHasBehavior, } from '../../model-profile/runtime.js';
|
|
@@ -58,7 +58,7 @@ import { MlxEngineGate } from './engine-gate.js';
|
|
|
58
58
|
import { EngineHold, engineHoldLabelFor } from './engine-hold.js';
|
|
59
59
|
import { EngineLogRouter } from './engine-log-router.js';
|
|
60
60
|
import { MlxEngineStatsSampler } from './engine-stats-sampler.js';
|
|
61
|
-
import { REASONING_OPEN_HEADER, StreamingReasoningSplit, engineOpensReasoning, requestOpensReasoning, } from './reasoning-stream.js';
|
|
61
|
+
import { REASONING_OPEN_HEADER, StreamingReasoningSplit, engineOpensReasoning, reopenTemplateReasoning, requestOpensReasoning, } from './reasoning-stream.js';
|
|
62
62
|
import { applyMlxRequestShape } from './request-shape.js';
|
|
63
63
|
import { PRE_FIRST_BYTE_BASE_MS, buildMidStreamDropMessage, buildPreFirstByteAbortMessage, computePreFirstByteBudgetMs, estimatePromptTokens, formatTps, isMidStreamConnectionDrop, mlxHttpError, } from './runtime-diagnostics.js';
|
|
64
64
|
import { classifyMlxFatalErrorLine, classifyMlxStartupLine, } from './stdout-parser.js';
|
|
@@ -2159,7 +2159,7 @@ class MlxSession extends StreamingSessionBase {
|
|
|
2159
2159
|
// accumulated into `lastTurnReasoning` so the chat bubble can
|
|
2160
2160
|
// render it behind a collapsed expander.
|
|
2161
2161
|
{
|
|
2162
|
-
const split = extractReasoningWithProfile(turnContent, this.deps.profile);
|
|
2162
|
+
const split = extractReasoningWithProfile(reopenTemplateReasoning(turnContent, opensInReasoning), this.deps.profile);
|
|
2163
2163
|
turnContent = split.visible;
|
|
2164
2164
|
if (split.reasoning) {
|
|
2165
2165
|
this.lastTurnReasoning =
|
|
@@ -2656,7 +2656,7 @@ class MlxSession extends StreamingSessionBase {
|
|
|
2656
2656
|
output =
|
|
2657
2657
|
"You already posted a question card to the user earlier in this turn. The second `ask_user_question` call was suppressed so the user only sees one card. END YOUR TURN NOW — the user's answer to the first question will arrive as the next user message; this turn produces no further visible content.";
|
|
2658
2658
|
}
|
|
2659
|
-
else if ((call.function.name
|
|
2659
|
+
else if (isProjectStartingCall(call.function.name, args) &&
|
|
2660
2660
|
startedProjectOrJobThisTurn) {
|
|
2661
2661
|
// Success-led phrasing — wild-caught on gemma4-26b/MLX,
|
|
2662
2662
|
// the previous "DO NOT call..." wording got misread by
|
|
@@ -2753,8 +2753,7 @@ class MlxSession extends StreamingSessionBase {
|
|
|
2753
2753
|
// Successful start_project / start_job → arm the
|
|
2754
2754
|
// per-turn macro guard so subsequent variants get
|
|
2755
2755
|
// intercepted above before reaching the bridge.
|
|
2756
|
-
if ((call.function.name
|
|
2757
|
-
!output.startsWith('ERROR:')) {
|
|
2756
|
+
if (isProjectStartingCall(call.function.name, args) && !output.startsWith('ERROR:')) {
|
|
2758
2757
|
startedProjectOrJobThisTurn = { tool: call.function.name, firstResult: output };
|
|
2759
2758
|
}
|
|
2760
2759
|
}
|
|
@@ -14,7 +14,6 @@ so concurrent replicas cannot observe a half-built view.
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
import fcntl
|
|
18
17
|
import hashlib
|
|
19
18
|
import json
|
|
20
19
|
import os
|
|
@@ -23,6 +22,13 @@ import uuid
|
|
|
23
22
|
from pathlib import Path
|
|
24
23
|
from typing import Callable, Optional, Tuple
|
|
25
24
|
|
|
25
|
+
try:
|
|
26
|
+
import fcntl
|
|
27
|
+
except ImportError:
|
|
28
|
+
# Windows has no fcntl. The MLX engine never runs there, but this module's
|
|
29
|
+
# stdlib suite does (python-suites.test.ts), so it must still import.
|
|
30
|
+
fcntl = None
|
|
31
|
+
|
|
26
32
|
|
|
27
33
|
PLE_MARKER = ".ple.ple_embedding.ngram_embedding.shards."
|
|
28
34
|
VIEW_MARKER = "GEZEL_PLE_VIEW.json"
|
|
@@ -122,7 +128,8 @@ def prepare_external_ple_view(
|
|
|
122
128
|
lock_path = target.parent / f".{target.name}.lock"
|
|
123
129
|
try:
|
|
124
130
|
with lock_path.open("a+b") as lock:
|
|
125
|
-
fcntl
|
|
131
|
+
if fcntl is not None:
|
|
132
|
+
fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
|
|
126
133
|
if _valid_view(target, signature):
|
|
127
134
|
return str(target), "reused", True
|
|
128
135
|
|
|
@@ -56,6 +56,21 @@ export declare function templateTextOpensReasoning(template: string): TemplateRe
|
|
|
56
56
|
* into the reasoning pane. Absent means on, matching the engine's default.
|
|
57
57
|
*/
|
|
58
58
|
export declare function requestOpensReasoning(templateOpen: TemplateReasoningOpen | undefined, body: Record<string, unknown>): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Restore the reasoning opener the chat template supplied, before the
|
|
61
|
+
* end-of-turn reasoning pass.
|
|
62
|
+
*
|
|
63
|
+
* When the rendered prompt left generation inside a reasoning block, the
|
|
64
|
+
* model's text starts mid-thought and carries only the closer. The live split
|
|
65
|
+
* knows that, but `extractReasoning` reads a lone `<channel|>` as stray and
|
|
66
|
+
* keeps the thoughts as the reply: Gemma 4 E4B, after a tool response, saved
|
|
67
|
+
* "The user wants to know…I need to answer in one sentence.The launch is on
|
|
68
|
+
* Friday…", and the stall check then asked it to answer again.
|
|
69
|
+
*
|
|
70
|
+
* Unchanged when the turn did not open in reasoning, when the model opened a
|
|
71
|
+
* block itself, or when no closer arrived.
|
|
72
|
+
*/
|
|
73
|
+
export declare function reopenTemplateReasoning(text: string, opensInReasoning: boolean): string;
|
|
59
74
|
export interface ReasoningSplitChunk {
|
|
60
75
|
visible: string;
|
|
61
76
|
reasoning: string;
|
|
@@ -112,6 +112,41 @@ export function requestOpensReasoning(templateOpen, body) {
|
|
|
112
112
|
return true;
|
|
113
113
|
return kwargs.enable_thinking !== false;
|
|
114
114
|
}
|
|
115
|
+
/** The opener `extractReasoning` pairs with each closer a template-opened turn emits. */
|
|
116
|
+
const OPENER_FOR_CLOSER = [
|
|
117
|
+
['</think>', '<think>'],
|
|
118
|
+
['</reasoning>', '<reasoning>'],
|
|
119
|
+
['[/THINK]', '[THINK]'],
|
|
120
|
+
['<channel|>', '<|channel>thought\n'],
|
|
121
|
+
['<|end|>', '<|channel|>analysis<|message|>'],
|
|
122
|
+
];
|
|
123
|
+
/**
|
|
124
|
+
* Restore the reasoning opener the chat template supplied, before the
|
|
125
|
+
* end-of-turn reasoning pass.
|
|
126
|
+
*
|
|
127
|
+
* When the rendered prompt left generation inside a reasoning block, the
|
|
128
|
+
* model's text starts mid-thought and carries only the closer. The live split
|
|
129
|
+
* knows that, but `extractReasoning` reads a lone `<channel|>` as stray and
|
|
130
|
+
* keeps the thoughts as the reply: Gemma 4 E4B, after a tool response, saved
|
|
131
|
+
* "The user wants to know…I need to answer in one sentence.The launch is on
|
|
132
|
+
* Friday…", and the stall check then asked it to answer again.
|
|
133
|
+
*
|
|
134
|
+
* Unchanged when the turn did not open in reasoning, when the model opened a
|
|
135
|
+
* block itself, or when no closer arrived.
|
|
136
|
+
*/
|
|
137
|
+
export function reopenTemplateReasoning(text, opensInReasoning) {
|
|
138
|
+
if (!opensInReasoning || /^\s*(?:<think>|<reasoning>|\[THINK\]|<\|?channel\|?>)/i.test(text)) {
|
|
139
|
+
return text;
|
|
140
|
+
}
|
|
141
|
+
const lower = text.toLowerCase();
|
|
142
|
+
let first = null;
|
|
143
|
+
for (const [closer, opener] of OPENER_FOR_CLOSER) {
|
|
144
|
+
const index = lower.indexOf(closer.toLowerCase());
|
|
145
|
+
if (index !== -1 && (first === null || index < first.index))
|
|
146
|
+
first = { index, opener };
|
|
147
|
+
}
|
|
148
|
+
return first ? `${first.opener}${text}` : text;
|
|
149
|
+
}
|
|
115
150
|
/**
|
|
116
151
|
* Incremental reasoning splitter for a streamed MLX turn.
|
|
117
152
|
*
|
|
@@ -46,6 +46,14 @@ export interface CapacityBrokerOptions {
|
|
|
46
46
|
* {@link computeCapacityBudget}. Omit to read the last published probe.
|
|
47
47
|
*/
|
|
48
48
|
gpuVramBytes?: number | null;
|
|
49
|
+
/**
|
|
50
|
+
* An integrated GPU's firmware carve-out — see
|
|
51
|
+
* {@link CapacityBudgetInput.reservedGpuBytes}. Travels with
|
|
52
|
+
* `gpuVramBytes`/`unifiedMemory` as one description of the host.
|
|
53
|
+
*/
|
|
54
|
+
reservedGpuBytes?: number | null;
|
|
55
|
+
/** What an integrated GPU can reach — see {@link CapacityBudgetInput.gpuAddressableBytes}. */
|
|
56
|
+
gpuAddressableBytes?: number | null;
|
|
49
57
|
/**
|
|
50
58
|
* May co-resident models spill into system RAM? `null`/omitted follows
|
|
51
59
|
* {@link autoAllowRamSpillover} for this host. See
|
|
@@ -192,6 +200,8 @@ export declare class CapacityBroker {
|
|
|
192
200
|
private readonly systemRamBytes;
|
|
193
201
|
private readonly unifiedMemory;
|
|
194
202
|
private readonly gpuVramBytes;
|
|
203
|
+
private readonly reservedGpuBytes;
|
|
204
|
+
private readonly gpuAddressableBytes;
|
|
195
205
|
private explicitAllowRamSpillover;
|
|
196
206
|
private readonly reservations;
|
|
197
207
|
constructor(opts?: CapacityBrokerOptions);
|
|
@@ -503,11 +513,9 @@ export declare const MIN_VIABLE_LOCAL_CONTEXT_TOKENS = 65536;
|
|
|
503
513
|
/** The same minimum on a host that has to trade context for memory. */
|
|
504
514
|
export declare const MIN_VIABLE_CONSTRAINED_CONTEXT_TOKENS = 32768;
|
|
505
515
|
/**
|
|
506
|
-
* The most KV cache
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
* numeric context, a pinned `swaFull`) are the operator's call and bypass it;
|
|
510
|
-
* it never shortens the ladder-settled base window either.
|
|
516
|
+
* The most KV cache adaptive growth plans for one llama.cpp engine. An
|
|
517
|
+
* explicit numeric context is the operator's call and skips growth
|
|
518
|
+
* altogether, and the ceiling never shortens the ladder-settled base window.
|
|
511
519
|
*
|
|
512
520
|
* Past this a bigger cache buys nothing: llama.cpp's prefill and decode cost
|
|
513
521
|
* follows the tokens actually present, not the reservation, so the rest only
|
|
@@ -650,10 +658,10 @@ export interface CtxMemoryClampInput {
|
|
|
650
658
|
*/
|
|
651
659
|
freeSystemRamBytes?: number;
|
|
652
660
|
/**
|
|
653
|
-
* Usable VRAM on a discrete card
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
661
|
+
* Usable VRAM on a discrete card. On a unified/shared-pool host it MUST be
|
|
662
|
+
* only an integrated GPU's firmware carve-out, which `freeSystemRamBytes`
|
|
663
|
+
* never sees; any "VRAM" that is the same physical RAM would double-count.
|
|
664
|
+
* `computeCapacityBudget` reports exactly that — pass its value.
|
|
657
665
|
*/
|
|
658
666
|
vramBytes: number;
|
|
659
667
|
minPerTurnCtxTokens?: number;
|
|
@@ -751,7 +759,7 @@ export interface AdaptiveCtxGrowthInput {
|
|
|
751
759
|
fastBudgetBytes: number;
|
|
752
760
|
committedOtherBytes?: number;
|
|
753
761
|
budgetKind: CapacityBudget['kind'];
|
|
754
|
-
/** Usable VRAM on a discrete card (`liveBudget.vramBytes`);
|
|
762
|
+
/** Usable VRAM on a discrete card (`liveBudget.vramBytes`); ignored elsewhere. */
|
|
755
763
|
vramBytes: number;
|
|
756
764
|
/**
|
|
757
765
|
* Graphics memory free right now on a discrete card, as device admission
|
|
@@ -796,11 +804,9 @@ export interface AdaptiveCtxGrowthResult {
|
|
|
796
804
|
* settled slots and granted the un-grown request.
|
|
797
805
|
*
|
|
798
806
|
* Deliberately a second clamp pass rather than a bigger first request:
|
|
799
|
-
* the first ladder pass sizes slot ceilings
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
* `--swa-full` for models whose full cache fits at 64K and grow KV into
|
|
803
|
-
* system-RAM spill on discrete cards.
|
|
807
|
+
* the first ladder pass sizes slot ceilings and RAM-spillover admission,
|
|
808
|
+
* both of which must stay anchored on the practical 64K target — growing
|
|
809
|
+
* the request there would grow KV into system-RAM spill on discrete cards.
|
|
804
810
|
*
|
|
805
811
|
* Slot trade: when `allowSlotTrade` is set and the target is out of reach
|
|
806
812
|
* at the settled slot count, growth walks the count down — taking the
|
|
@@ -151,12 +151,16 @@ export class CapacityBroker {
|
|
|
151
151
|
systemRamBytes;
|
|
152
152
|
unifiedMemory;
|
|
153
153
|
gpuVramBytes;
|
|
154
|
+
reservedGpuBytes;
|
|
155
|
+
gpuAddressableBytes;
|
|
154
156
|
explicitAllowRamSpillover;
|
|
155
157
|
reservations = new Map();
|
|
156
158
|
constructor(opts = {}) {
|
|
157
159
|
this.systemRamBytes = (opts.systemRamBytes ?? totalmem)();
|
|
158
160
|
this.unifiedMemory = opts.unifiedMemory;
|
|
159
161
|
this.gpuVramBytes = opts.gpuVramBytes;
|
|
162
|
+
this.reservedGpuBytes = opts.reservedGpuBytes;
|
|
163
|
+
this.gpuAddressableBytes = opts.gpuAddressableBytes;
|
|
160
164
|
this.explicitAllowRamSpillover = opts.allowRamSpillover ?? null;
|
|
161
165
|
this.explicitBudgetBytes = opts.budgetBytes ?? null;
|
|
162
166
|
// Assigned by applyBudget; the definite-assignment dance TS wants for
|
|
@@ -189,6 +193,12 @@ export class CapacityBroker {
|
|
|
189
193
|
: {
|
|
190
194
|
...(this.unifiedMemory === undefined ? {} : { unifiedMemory: this.unifiedMemory }),
|
|
191
195
|
...(this.gpuVramBytes === undefined ? {} : { gpuVramBytes: this.gpuVramBytes }),
|
|
196
|
+
...(this.reservedGpuBytes === undefined
|
|
197
|
+
? {}
|
|
198
|
+
: { reservedGpuBytes: this.reservedGpuBytes }),
|
|
199
|
+
...(this.gpuAddressableBytes === undefined
|
|
200
|
+
? {}
|
|
201
|
+
: { gpuAddressableBytes: this.gpuAddressableBytes }),
|
|
192
202
|
}),
|
|
193
203
|
});
|
|
194
204
|
}
|
|
@@ -714,11 +724,9 @@ function envGrowthCeilingTokens() {
|
|
|
714
724
|
return Number.isFinite(tokens) && tokens > 0 ? tokens : null;
|
|
715
725
|
}
|
|
716
726
|
/**
|
|
717
|
-
* The most KV cache
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
* numeric context, a pinned `swaFull`) are the operator's call and bypass it;
|
|
721
|
-
* it never shortens the ladder-settled base window either.
|
|
727
|
+
* The most KV cache adaptive growth plans for one llama.cpp engine. An
|
|
728
|
+
* explicit numeric context is the operator's call and skips growth
|
|
729
|
+
* altogether, and the ceiling never shortens the ladder-settled base window.
|
|
722
730
|
*
|
|
723
731
|
* Past this a bigger cache buys nothing: llama.cpp's prefill and decode cost
|
|
724
732
|
* follows the tokens actually present, not the reservation, so the rest only
|
|
@@ -806,14 +814,20 @@ export function resolveLlamaCppContextRequirement(opts) {
|
|
|
806
814
|
const strictModelMax = opts.contextSizing === 'model-max' && opts.explicitContextWindow === undefined;
|
|
807
815
|
const requestedContextWindow = opts.explicitContextWindow ??
|
|
808
816
|
(strictModelMax ? opts.modelContextWindow : opts.adaptiveContextWindow);
|
|
817
|
+
// Env, per-model and machine-wide numeric settings all express deliberate
|
|
818
|
+
// operator intent. The automatic host floor must not silently turn a 32K
|
|
819
|
+
// memory-saving request back into 64K. Resolve this here so launch and
|
|
820
|
+
// preview cannot apply different floors to the same explicit request.
|
|
821
|
+
const hostFloor = opts.minViableContextTokens ?? minViableLocalContextTokens();
|
|
822
|
+
const minimum = opts.explicitContextWindow !== undefined && opts.explicitContextWindow > 0
|
|
823
|
+
? Math.min(hostFloor, opts.explicitContextWindow)
|
|
824
|
+
: hostFloor;
|
|
809
825
|
const resolved = resolveLocalContextRequirement({
|
|
810
826
|
...(opts.modelContextWindow !== undefined
|
|
811
827
|
? { modelContextWindow: opts.modelContextWindow }
|
|
812
828
|
: {}),
|
|
813
829
|
...(requestedContextWindow !== undefined ? { requestedContextWindow } : {}),
|
|
814
|
-
|
|
815
|
-
? { minViableContextTokens: opts.minViableContextTokens }
|
|
816
|
-
: {}),
|
|
830
|
+
minViableContextTokens: minimum,
|
|
817
831
|
});
|
|
818
832
|
if (strictModelMax) {
|
|
819
833
|
return {
|
|
@@ -959,11 +973,9 @@ export const ADAPTIVE_GROWTH_TRADE_MIN_GAIN = 1.25;
|
|
|
959
973
|
* settled slots and granted the un-grown request.
|
|
960
974
|
*
|
|
961
975
|
* Deliberately a second clamp pass rather than a bigger first request:
|
|
962
|
-
* the first ladder pass sizes slot ceilings
|
|
963
|
-
*
|
|
964
|
-
*
|
|
965
|
-
* `--swa-full` for models whose full cache fits at 64K and grow KV into
|
|
966
|
-
* system-RAM spill on discrete cards.
|
|
976
|
+
* the first ladder pass sizes slot ceilings and RAM-spillover admission,
|
|
977
|
+
* both of which must stay anchored on the practical 64K target — growing
|
|
978
|
+
* the request there would grow KV into system-RAM spill on discrete cards.
|
|
967
979
|
*
|
|
968
980
|
* Slot trade: when `allowSlotTrade` is set and the target is out of reach
|
|
969
981
|
* at the settled slot count, growth walks the count down — taking the
|
|
@@ -5,7 +5,13 @@
|
|
|
5
5
|
* VRAM and RAM are common on small discrete-GPU machines, so their ratio is
|
|
6
6
|
* not enough to tell a GeForce from a genuinely shared GB10/iGPU pool.
|
|
7
7
|
*/
|
|
8
|
-
export declare function setDetectedGpuVramBytes(bytes: number | null, unifiedMemory?: boolean): void;
|
|
8
|
+
export declare function setDetectedGpuVramBytes(bytes: number | null, unifiedMemory?: boolean, reservedGpuBytes?: number | null, gpuAddressableBytes?: number | null): void;
|
|
9
|
+
/**
|
|
10
|
+
* What engines may hold of memory an integrated GPU owns or can reach — its
|
|
11
|
+
* carve-out, or carve-out plus GTT — after the share the desktop it also
|
|
12
|
+
* drives needs.
|
|
13
|
+
*/
|
|
14
|
+
export declare function usableReservedGpuBytes(reservedGpuBytes: number | null | undefined): number;
|
|
9
15
|
/** The published accelerator-memory figure, or null when none was measured. */
|
|
10
16
|
export declare function getDetectedGpuVramBytes(): number | null;
|
|
11
17
|
/**
|
|
@@ -26,13 +32,19 @@ export interface CapacityBudget {
|
|
|
26
32
|
budgetBytes: number;
|
|
27
33
|
/**
|
|
28
34
|
* The FAST pool inside that budget: usable VRAM on a discrete card, the
|
|
29
|
-
* whole budget on unified / CPU hosts
|
|
35
|
+
* whole budget on unified / CPU hosts — except an integrated GPU that can
|
|
36
|
+
* reach less than that (Linux GTT; see
|
|
37
|
+
* {@link CapacityBudgetInput.gpuAddressableBytes}). Size KV slots and prompt caches
|
|
30
38
|
* against this, not against {@link budgetBytes} — on a discrete card the
|
|
31
39
|
* rest of the budget is system RAM that weights stream from, and putting
|
|
32
40
|
* more KV there than the card holds is how a GPU OOMs.
|
|
33
41
|
*/
|
|
34
42
|
fastBytes: number;
|
|
35
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Usable VRAM on a discrete card. On a unified host, the usable part of an
|
|
45
|
+
* integrated GPU's firmware carve-out — memory the GPU owns that free-RAM
|
|
46
|
+
* readings never include — and 0 when there is none. 0 on CPU-only hosts.
|
|
47
|
+
*/
|
|
36
48
|
vramBytes: number;
|
|
37
49
|
/** The system-RAM share of the budget. */
|
|
38
50
|
ramShareBytes: number;
|
|
@@ -59,6 +71,26 @@ export interface CapacityBudgetInput {
|
|
|
59
71
|
*/
|
|
60
72
|
gpuVramBytes?: number | null;
|
|
61
73
|
unifiedMemory?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Memory firmware sets aside for an integrated GPU (an AMD "UMA frame
|
|
76
|
+
* buffer"): carved out before the OS counts RAM, so it is NOT inside
|
|
77
|
+
* `systemRamBytes`, and only the GPU can use it. Credited on a unified host
|
|
78
|
+
* only — an engine on the CPU build cannot reach it. Without this, raising
|
|
79
|
+
* the carve-out shrank the budget: the bytes left the RAM figure and were
|
|
80
|
+
* counted nowhere. Omit to fall back to the last published probe, under the
|
|
81
|
+
* same rule as `gpuVramBytes`.
|
|
82
|
+
*/
|
|
83
|
+
reservedGpuBytes?: number | null;
|
|
84
|
+
/**
|
|
85
|
+
* The most memory an integrated GPU can reach: on Linux amdgpu, its
|
|
86
|
+
* carve-out plus GTT, the window of system RAM the kernel lets it map
|
|
87
|
+
* (half of RAM by default). Caps the FAST pool on a unified host — the GPU
|
|
88
|
+
* cannot hold more KV or weights than this, whatever the RAM share says —
|
|
89
|
+
* while the admission budget keeps the rest for layers the CPU runs. Omit
|
|
90
|
+
* to fall back to the last published probe, under the same rule as
|
|
91
|
+
* `gpuVramBytes`.
|
|
92
|
+
*/
|
|
93
|
+
gpuAddressableBytes?: number | null;
|
|
62
94
|
}
|
|
63
95
|
/**
|
|
64
96
|
* Resolve the memory a host can give resident local engines, per pool.
|
|
@@ -67,6 +67,13 @@ const VRAM_USABLE_FRACTION = 0.95;
|
|
|
67
67
|
* bytes, so those hosts take the unified curve instead.
|
|
68
68
|
*/
|
|
69
69
|
const UNIFIED_VRAM_RATIO = 0.75;
|
|
70
|
+
/**
|
|
71
|
+
* Held back from an integrated GPU's firmware carve-out (see
|
|
72
|
+
* {@link CapacityBudgetInput.reservedGpuBytes}) for the desktop it also
|
|
73
|
+
* drives. The discrete card's 5% margin is too thin here: on a 512 MiB
|
|
74
|
+
* carve-out it would leave the compositor 25 MiB.
|
|
75
|
+
*/
|
|
76
|
+
const CARVE_OUT_DISPLAY_RESERVE_BYTES = 512 * 1024 ** 2;
|
|
70
77
|
/**
|
|
71
78
|
* Last accelerator-memory figure `detectMemoryProfile` measured on this host,
|
|
72
79
|
* or null when nothing has probed yet / no GPU memory figure was published.
|
|
@@ -81,6 +88,8 @@ const UNIFIED_VRAM_RATIO = 0.75;
|
|
|
81
88
|
*/
|
|
82
89
|
let detectedGpuVramBytes = null;
|
|
83
90
|
let detectedGpuUnifiedMemory;
|
|
91
|
+
let detectedGpuReservedBytes = null;
|
|
92
|
+
let detectedGpuAddressableBytes = null;
|
|
84
93
|
/**
|
|
85
94
|
* Publish the measured accelerator pool. Called by `detectMemoryProfile`.
|
|
86
95
|
*
|
|
@@ -88,10 +97,26 @@ let detectedGpuUnifiedMemory;
|
|
|
88
97
|
* VRAM and RAM are common on small discrete-GPU machines, so their ratio is
|
|
89
98
|
* not enough to tell a GeForce from a genuinely shared GB10/iGPU pool.
|
|
90
99
|
*/
|
|
91
|
-
export function setDetectedGpuVramBytes(bytes, unifiedMemory) {
|
|
92
|
-
detectedGpuVramBytes =
|
|
93
|
-
typeof bytes === 'number' && Number.isFinite(bytes) && bytes > 0 ? bytes : null;
|
|
100
|
+
export function setDetectedGpuVramBytes(bytes, unifiedMemory, reservedGpuBytes, gpuAddressableBytes) {
|
|
101
|
+
detectedGpuVramBytes = positiveOrNull(bytes);
|
|
94
102
|
detectedGpuUnifiedMemory = unifiedMemory;
|
|
103
|
+
detectedGpuReservedBytes = positiveOrNull(reservedGpuBytes);
|
|
104
|
+
detectedGpuAddressableBytes = positiveOrNull(gpuAddressableBytes);
|
|
105
|
+
}
|
|
106
|
+
function positiveOrNull(bytes) {
|
|
107
|
+
return typeof bytes === 'number' && Number.isFinite(bytes) && bytes > 0 ? bytes : null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* What engines may hold of memory an integrated GPU owns or can reach — its
|
|
111
|
+
* carve-out, or carve-out plus GTT — after the share the desktop it also
|
|
112
|
+
* drives needs.
|
|
113
|
+
*/
|
|
114
|
+
export function usableReservedGpuBytes(reservedGpuBytes) {
|
|
115
|
+
const reserved = positiveOrNull(reservedGpuBytes);
|
|
116
|
+
if (reserved === null)
|
|
117
|
+
return 0;
|
|
118
|
+
const display = Math.max(CARVE_OUT_DISPLAY_RESERVE_BYTES, Math.ceil(reserved * (1 - VRAM_USABLE_FRACTION)));
|
|
119
|
+
return Math.max(0, reserved - display);
|
|
95
120
|
}
|
|
96
121
|
/** The published accelerator-memory figure, or null when none was measured. */
|
|
97
122
|
export function getDetectedGpuVramBytes() {
|
|
@@ -144,6 +169,16 @@ export function computeCapacityBudget(input = {}) {
|
|
|
144
169
|
const sharedPool = hasCard && measuredVram >= systemRamBytes * UNIFIED_VRAM_RATIO;
|
|
145
170
|
const unified = measuredUnifiedMemory ?? (isUnifiedMemoryHost() || sharedPool);
|
|
146
171
|
const discrete = hasCard && !unified;
|
|
172
|
+
const reservedGpuBytes = input.reservedGpuBytes !== undefined
|
|
173
|
+
? input.reservedGpuBytes
|
|
174
|
+
: input.unifiedMemory === undefined && input.gpuVramBytes === undefined
|
|
175
|
+
? detectedGpuReservedBytes
|
|
176
|
+
: null;
|
|
177
|
+
const gpuAddressableBytes = input.gpuAddressableBytes !== undefined
|
|
178
|
+
? input.gpuAddressableBytes
|
|
179
|
+
: input.unifiedMemory === undefined && input.gpuVramBytes === undefined
|
|
180
|
+
? detectedGpuAddressableBytes
|
|
181
|
+
: null;
|
|
147
182
|
const highMemory = systemRamBytes >= HIGH_MEMORY_THRESHOLD_BYTES;
|
|
148
183
|
// Whichever bound leaves the host MORE memory wins between the fraction and
|
|
149
184
|
// the capped reserve, then the 4 GiB floor reserve caps them both. Written
|
|
@@ -153,7 +188,11 @@ export function computeCapacityBudget(input = {}) {
|
|
|
153
188
|
const unifiedShare = Math.max(0, Math.min(Math.max(unifiedFractionShare, systemRamBytes - UNIFIED_OS_RESERVE_MAX_BYTES), systemRamBytes - UNIFIED_OS_RESERVE_BYTES));
|
|
154
189
|
const nonUnifiedShare = Math.min(Math.floor(systemRamBytes * (highMemory ? 0.8 : 0.6)), BUDGET_CAP_BYTES);
|
|
155
190
|
const ramShareBytes = unified ? unifiedShare : nonUnifiedShare;
|
|
156
|
-
const vramBytes = discrete
|
|
191
|
+
const vramBytes = discrete
|
|
192
|
+
? Math.floor(measuredVram * VRAM_USABLE_FRACTION)
|
|
193
|
+
: unified
|
|
194
|
+
? usableReservedGpuBytes(reservedGpuBytes)
|
|
195
|
+
: 0;
|
|
157
196
|
// The pre-cap curve, retained for slot sizing only.
|
|
158
197
|
const concurrencyRamShare = unified
|
|
159
198
|
? Math.max(0, Math.min(unifiedFractionShare, systemRamBytes - UNIFIED_OS_RESERVE_BYTES, BUDGET_CAP_BYTES))
|
|
@@ -175,7 +214,12 @@ export function computeCapacityBudget(input = {}) {
|
|
|
175
214
|
overriddenByEnv: true,
|
|
176
215
|
};
|
|
177
216
|
}
|
|
178
|
-
const
|
|
217
|
+
const addressable = positiveOrNull(gpuAddressableBytes);
|
|
218
|
+
const fastBytes = discrete
|
|
219
|
+
? vramBytes
|
|
220
|
+
: unified && addressable !== null
|
|
221
|
+
? Math.min(auto, usableReservedGpuBytes(addressable))
|
|
222
|
+
: auto;
|
|
179
223
|
return {
|
|
180
224
|
budgetBytes: auto,
|
|
181
225
|
fastBytes,
|
|
@@ -73,7 +73,7 @@ export declare function configuredEngineMemoryBytes(config: {
|
|
|
73
73
|
* download pages hide is exactly one the launch path refuses. Omit
|
|
74
74
|
* `configuredBytes` for the machine's automatic ceilings.
|
|
75
75
|
*/
|
|
76
|
-
export declare function staticCapacityCeilings(budget: Pick<CapacityBudget, 'budgetBytes' | 'fastBytes' | 'kind'>, ramBytes: number, configuredBytes?: number): {
|
|
76
|
+
export declare function staticCapacityCeilings(budget: Pick<CapacityBudget, 'budgetBytes' | 'fastBytes' | 'kind' | 'vramBytes'>, ramBytes: number, configuredBytes?: number, platform?: NodeJS.Platform): {
|
|
77
77
|
budgetBytes: number;
|
|
78
78
|
gpuBudgetBytes: number;
|
|
79
79
|
};
|