@atomic-chat/core 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/app-daemon.d.ts +2 -0
- package/dist/app-daemon.js +72 -0
- package/dist/app-daemon.js.map +1 -0
- package/dist/backend/catalog/archive.d.ts +70 -0
- package/dist/backend/catalog/archive.js +138 -0
- package/dist/backend/catalog/archive.js.map +1 -0
- package/dist/backend/catalog/bundled-manifest-baseline.d.ts +2 -0
- package/dist/backend/catalog/bundled-manifest-baseline.js +49 -0
- package/dist/backend/catalog/bundled-manifest-baseline.js.map +1 -0
- package/dist/backend/catalog/cuda-family.d.ts +54 -0
- package/dist/backend/catalog/cuda-family.js +93 -0
- package/dist/backend/catalog/cuda-family.js.map +1 -0
- package/dist/backend/catalog/index.d.ts +6 -0
- package/dist/backend/catalog/index.js +7 -0
- package/dist/backend/catalog/index.js.map +1 -0
- package/dist/backend/catalog/manifest.d.ts +102 -0
- package/dist/backend/catalog/manifest.js +233 -0
- package/dist/backend/catalog/manifest.js.map +1 -0
- package/dist/backend/catalog/migrate.d.ts +40 -0
- package/dist/backend/catalog/migrate.js +135 -0
- package/dist/backend/catalog/migrate.js.map +1 -0
- package/dist/backend/index.d.ts +18 -0
- package/dist/backend/index.js +19 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/install/index.d.ts +3 -0
- package/dist/backend/install/index.js +4 -0
- package/dist/backend/install/index.js.map +1 -0
- package/dist/backend/install/runtime-backend.d.ts +22 -0
- package/dist/backend/install/runtime-backend.js +95 -0
- package/dist/backend/install/runtime-backend.js.map +1 -0
- package/dist/backend/install/service.d.ts +119 -0
- package/dist/backend/install/service.js +218 -0
- package/dist/backend/install/service.js.map +1 -0
- package/dist/backend/installed/index.d.ts +3 -0
- package/dist/backend/installed/index.js +4 -0
- package/dist/backend/installed/index.js.map +1 -0
- package/dist/backend/installed/installed.d.ts +93 -0
- package/dist/backend/installed/installed.js +209 -0
- package/dist/backend/installed/installed.js.map +1 -0
- package/dist/backend/installed/scan.d.ts +39 -0
- package/dist/backend/installed/scan.js +105 -0
- package/dist/backend/installed/scan.js.map +1 -0
- package/dist/backend/optimal/index.d.ts +3 -0
- package/dist/backend/optimal/index.js +4 -0
- package/dist/backend/optimal/index.js.map +1 -0
- package/dist/backend/optimal/optimal-cache.d.ts +90 -0
- package/dist/backend/optimal/optimal-cache.js +198 -0
- package/dist/backend/optimal/optimal-cache.js.map +1 -0
- package/dist/backend/optimal/optimal-store.d.ts +24 -0
- package/dist/backend/optimal/optimal-store.js +103 -0
- package/dist/backend/optimal/optimal-store.js.map +1 -0
- package/dist/backend/select/amd-rocm-pci-ids.d.ts +3 -0
- package/dist/backend/select/amd-rocm-pci-ids.js +57 -0
- package/dist/backend/select/amd-rocm-pci-ids.js.map +1 -0
- package/dist/backend/select/categories.d.ts +49 -0
- package/dist/backend/select/categories.js +178 -0
- package/dist/backend/select/categories.js.map +1 -0
- package/dist/backend/select/features.d.ts +81 -0
- package/dist/backend/select/features.js +221 -0
- package/dist/backend/select/features.js.map +1 -0
- package/dist/backend/select/index.d.ts +9 -0
- package/dist/backend/select/index.js +10 -0
- package/dist/backend/select/index.js.map +1 -0
- package/dist/backend/select/recovery.d.ts +51 -0
- package/dist/backend/select/recovery.js +108 -0
- package/dist/backend/select/recovery.js.map +1 -0
- package/dist/backend/select/tiers.d.ts +76 -0
- package/dist/backend/select/tiers.js +179 -0
- package/dist/backend/select/tiers.js.map +1 -0
- package/dist/backend/turboquant.d.ts +134 -0
- package/dist/backend/turboquant.js +587 -0
- package/dist/backend/turboquant.js.map +1 -0
- package/dist/backend/types.d.ts +139 -0
- package/dist/backend/types.js +13 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/backend/version.d.ts +59 -0
- package/dist/backend/version.js +168 -0
- package/dist/backend/version.js.map +1 -0
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +10 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/cloud.d.ts +13 -0
- package/dist/cli/cloud.js +146 -0
- package/dist/cli/cloud.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +4 -0
- package/dist/cli/commands/daemon.js +88 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/index.d.ts +16 -0
- package/dist/cli/commands/index.js +17 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/models.d.ts +4 -0
- package/dist/cli/commands/models.js +52 -0
- package/dist/cli/commands/models.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +16 -0
- package/dist/cli/commands/serve.js +263 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/server.d.ts +4 -0
- package/dist/cli/commands/server.js +126 -0
- package/dist/cli/commands/server.js.map +1 -0
- package/dist/cli/commands/shared.d.ts +10 -0
- package/dist/cli/commands/shared.js +34 -0
- package/dist/cli/commands/shared.js.map +1 -0
- package/dist/cli/commands/shutdown.d.ts +4 -0
- package/dist/cli/commands/shutdown.js +32 -0
- package/dist/cli/commands/shutdown.js.map +1 -0
- package/dist/cli/commands/telemetry.d.ts +8 -0
- package/dist/cli/commands/telemetry.js +50 -0
- package/dist/cli/commands/telemetry.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/io.d.ts +46 -0
- package/dist/cli/io.js +101 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/launch.d.ts +50 -0
- package/dist/cli/launch.js +327 -0
- package/dist/cli/launch.js.map +1 -0
- package/dist/cli/main.d.ts +10 -0
- package/dist/cli/main.js +109 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/owner.d.ts +39 -0
- package/dist/cli/owner.js +179 -0
- package/dist/cli/owner.js.map +1 -0
- package/dist/client/control-client.d.ts +213 -0
- package/dist/client/control-client.js +368 -0
- package/dist/client/control-client.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/cloud/chatgpt.d.ts +63 -0
- package/dist/cloud/chatgpt.js +233 -0
- package/dist/cloud/chatgpt.js.map +1 -0
- package/dist/cloud/index.d.ts +8 -0
- package/dist/cloud/index.js +9 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/registry.d.ts +51 -0
- package/dist/cloud/registry.js +148 -0
- package/dist/cloud/registry.js.map +1 -0
- package/dist/config/data-folder.d.ts +57 -0
- package/dist/config/data-folder.js +150 -0
- package/dist/config/data-folder.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.js +10 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/paths.d.ts +98 -0
- package/dist/config/paths.js +109 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/contracts/control-api.d.ts +61 -0
- package/dist/contracts/control-api.js +7 -0
- package/dist/contracts/control-api.js.map +1 -0
- package/dist/contracts/diffusion.d.ts +477 -0
- package/dist/contracts/diffusion.js +10 -0
- package/dist/contracts/diffusion.js.map +1 -0
- package/dist/contracts/errors.d.ts +61 -0
- package/dist/contracts/errors.js +70 -0
- package/dist/contracts/errors.js.map +1 -0
- package/dist/contracts/events.d.ts +270 -0
- package/dist/contracts/events.js +7 -0
- package/dist/contracts/events.js.map +1 -0
- package/dist/contracts/hardware.d.ts +53 -0
- package/dist/contracts/hardware.js +12 -0
- package/dist/contracts/hardware.js.map +1 -0
- package/dist/contracts/index.d.ts +12 -0
- package/dist/contracts/index.js +13 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/model-yml.d.ts +28 -0
- package/dist/contracts/model-yml.js +23 -0
- package/dist/contracts/model-yml.js.map +1 -0
- package/dist/contracts/remote-access.d.ts +43 -0
- package/dist/contracts/remote-access.js +12 -0
- package/dist/contracts/remote-access.js.map +1 -0
- package/dist/contracts/session.d.ts +39 -0
- package/dist/contracts/session.js +7 -0
- package/dist/contracts/session.js.map +1 -0
- package/dist/contracts/settings.d.ts +106 -0
- package/dist/contracts/settings.js +17 -0
- package/dist/contracts/settings.js.map +1 -0
- package/dist/core/atomic-core.d.ts +149 -0
- package/dist/core/atomic-core.js +289 -0
- package/dist/core/atomic-core.js.map +1 -0
- package/dist/core/create.d.ts +12 -0
- package/dist/core/create.js +393 -0
- package/dist/core/create.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/public-server.d.ts +76 -0
- package/dist/core/public-server.js +143 -0
- package/dist/core/public-server.js.map +1 -0
- package/dist/core/reap-orphans.d.ts +7 -0
- package/dist/core/reap-orphans.js +40 -0
- package/dist/core/reap-orphans.js.map +1 -0
- package/dist/core/sessions.d.ts +60 -0
- package/dist/core/sessions.js +180 -0
- package/dist/core/sessions.js.map +1 -0
- package/dist/core/types.d.ts +61 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/credentials/api-keys.d.ts +41 -0
- package/dist/credentials/api-keys.js +156 -0
- package/dist/credentials/api-keys.js.map +1 -0
- package/dist/credentials/chatgpt-auth.d.ts +73 -0
- package/dist/credentials/chatgpt-auth.js +167 -0
- package/dist/credentials/chatgpt-auth.js.map +1 -0
- package/dist/credentials/chatgpt-oauth.d.ts +97 -0
- package/dist/credentials/chatgpt-oauth.js +329 -0
- package/dist/credentials/chatgpt-oauth.js.map +1 -0
- package/dist/credentials/chatgpt-store.d.ts +33 -0
- package/dist/credentials/chatgpt-store.js +110 -0
- package/dist/credentials/chatgpt-store.js.map +1 -0
- package/dist/credentials/index.d.ts +11 -0
- package/dist/credentials/index.js +12 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/diffusion/args.d.ts +102 -0
- package/dist/diffusion/args.js +291 -0
- package/dist/diffusion/args.js.map +1 -0
- package/dist/diffusion/compat.d.ts +20 -0
- package/dist/diffusion/compat.js +58 -0
- package/dist/diffusion/compat.js.map +1 -0
- package/dist/diffusion/containment.d.ts +15 -0
- package/dist/diffusion/containment.js +32 -0
- package/dist/diffusion/containment.js.map +1 -0
- package/dist/diffusion/errors.d.ts +28 -0
- package/dist/diffusion/errors.js +63 -0
- package/dist/diffusion/errors.js.map +1 -0
- package/dist/diffusion/gallery.d.ts +76 -0
- package/dist/diffusion/gallery.js +307 -0
- package/dist/diffusion/gallery.js.map +1 -0
- package/dist/diffusion/http.d.ts +16 -0
- package/dist/diffusion/http.js +41 -0
- package/dist/diffusion/http.js.map +1 -0
- package/dist/diffusion/idle.d.ts +23 -0
- package/dist/diffusion/idle.js +45 -0
- package/dist/diffusion/idle.js.map +1 -0
- package/dist/diffusion/image-job.d.ts +25 -0
- package/dist/diffusion/image-job.js +176 -0
- package/dist/diffusion/image-job.js.map +1 -0
- package/dist/diffusion/index.d.ts +35 -0
- package/dist/diffusion/index.js +36 -0
- package/dist/diffusion/index.js.map +1 -0
- package/dist/diffusion/install.d.ts +61 -0
- package/dist/diffusion/install.js +287 -0
- package/dist/diffusion/install.js.map +1 -0
- package/dist/diffusion/job-kind.d.ts +74 -0
- package/dist/diffusion/job-kind.js +7 -0
- package/dist/diffusion/job-kind.js.map +1 -0
- package/dist/diffusion/jobs.d.ts +90 -0
- package/dist/diffusion/jobs.js +433 -0
- package/dist/diffusion/jobs.js.map +1 -0
- package/dist/diffusion/mutex.d.ts +16 -0
- package/dist/diffusion/mutex.js +46 -0
- package/dist/diffusion/mutex.js.map +1 -0
- package/dist/diffusion/parse.d.ts +19 -0
- package/dist/diffusion/parse.js +274 -0
- package/dist/diffusion/parse.js.map +1 -0
- package/dist/diffusion/png.d.ts +77 -0
- package/dist/diffusion/png.js +335 -0
- package/dist/diffusion/png.js.map +1 -0
- package/dist/diffusion/progress.d.ts +74 -0
- package/dist/diffusion/progress.js +223 -0
- package/dist/diffusion/progress.js.map +1 -0
- package/dist/diffusion/recipe.d.ts +26 -0
- package/dist/diffusion/recipe.js +206 -0
- package/dist/diffusion/recipe.js.map +1 -0
- package/dist/diffusion/server-process.d.ts +59 -0
- package/dist/diffusion/server-process.js +235 -0
- package/dist/diffusion/server-process.js.map +1 -0
- package/dist/diffusion/service.d.ts +107 -0
- package/dist/diffusion/service.js +431 -0
- package/dist/diffusion/service.js.map +1 -0
- package/dist/diffusion/session.d.ts +58 -0
- package/dist/diffusion/session.js +226 -0
- package/dist/diffusion/session.js.map +1 -0
- package/dist/diffusion/state.d.ts +90 -0
- package/dist/diffusion/state.js +122 -0
- package/dist/diffusion/state.js.map +1 -0
- package/dist/diffusion/tracker.d.ts +46 -0
- package/dist/diffusion/tracker.js +153 -0
- package/dist/diffusion/tracker.js.map +1 -0
- package/dist/diffusion/types.d.ts +62 -0
- package/dist/diffusion/types.js +10 -0
- package/dist/diffusion/types.js.map +1 -0
- package/dist/diffusion/validate.d.ts +36 -0
- package/dist/diffusion/validate.js +166 -0
- package/dist/diffusion/validate.js.map +1 -0
- package/dist/diffusion/video-gallery.d.ts +56 -0
- package/dist/diffusion/video-gallery.js +252 -0
- package/dist/diffusion/video-gallery.js.map +1 -0
- package/dist/diffusion/video-job.d.ts +33 -0
- package/dist/diffusion/video-job.js +150 -0
- package/dist/diffusion/video-job.js.map +1 -0
- package/dist/diffusion/video-recipe.d.ts +12 -0
- package/dist/diffusion/video-recipe.js +141 -0
- package/dist/diffusion/video-recipe.js.map +1 -0
- package/dist/diffusion/wiring.d.ts +24 -0
- package/dist/diffusion/wiring.js +38 -0
- package/dist/diffusion/wiring.js.map +1 -0
- package/dist/diffusion/workflow.d.ts +33 -0
- package/dist/diffusion/workflow.js +78 -0
- package/dist/diffusion/workflow.js.map +1 -0
- package/dist/downloads/archive.d.ts +15 -0
- package/dist/downloads/archive.js +121 -0
- package/dist/downloads/archive.js.map +1 -0
- package/dist/downloads/disk-space.d.ts +18 -0
- package/dist/downloads/disk-space.js +32 -0
- package/dist/downloads/disk-space.js.map +1 -0
- package/dist/downloads/disk.d.ts +38 -0
- package/dist/downloads/disk.js +88 -0
- package/dist/downloads/disk.js.map +1 -0
- package/dist/downloads/downloader.d.ts +75 -0
- package/dist/downloads/downloader.js +479 -0
- package/dist/downloads/downloader.js.map +1 -0
- package/dist/downloads/index.d.ts +14 -0
- package/dist/downloads/index.js +15 -0
- package/dist/downloads/index.js.map +1 -0
- package/dist/downloads/protocol.d.ts +52 -0
- package/dist/downloads/protocol.js +153 -0
- package/dist/downloads/protocol.js.map +1 -0
- package/dist/downloads/proxy-fetch.d.ts +45 -0
- package/dist/downloads/proxy-fetch.js +571 -0
- package/dist/downloads/proxy-fetch.js.map +1 -0
- package/dist/downloads/verify.d.ts +22 -0
- package/dist/downloads/verify.js +74 -0
- package/dist/downloads/verify.js.map +1 -0
- package/dist/events/emitter.d.ts +44 -0
- package/dist/events/emitter.js +104 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/index.d.ts +5 -0
- package/dist/events/index.js +6 -0
- package/dist/events/index.js.map +1 -0
- package/dist/hardware/index.d.ts +7 -0
- package/dist/hardware/index.js +8 -0
- package/dist/hardware/index.js.map +1 -0
- package/dist/hardware/override.d.ts +46 -0
- package/dist/hardware/override.js +81 -0
- package/dist/hardware/override.js.map +1 -0
- package/dist/host/index.d.ts +15 -0
- package/dist/host/index.js +16 -0
- package/dist/host/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/catalog.d.ts +67 -0
- package/dist/integrations/catalog.js +385 -0
- package/dist/integrations/catalog.js.map +1 -0
- package/dist/integrations/config-io.d.ts +86 -0
- package/dist/integrations/config-io.js +229 -0
- package/dist/integrations/config-io.js.map +1 -0
- package/dist/integrations/configure/atomic-agent.d.ts +33 -0
- package/dist/integrations/configure/atomic-agent.js +127 -0
- package/dist/integrations/configure/atomic-agent.js.map +1 -0
- package/dist/integrations/configure/claude-code.d.ts +16 -0
- package/dist/integrations/configure/claude-code.js +45 -0
- package/dist/integrations/configure/claude-code.js.map +1 -0
- package/dist/integrations/configure/cline.d.ts +28 -0
- package/dist/integrations/configure/cline.js +70 -0
- package/dist/integrations/configure/cline.js.map +1 -0
- package/dist/integrations/configure/codex.d.ts +17 -0
- package/dist/integrations/configure/codex.js +43 -0
- package/dist/integrations/configure/codex.js.map +1 -0
- package/dist/integrations/configure/copilot.d.ts +10 -0
- package/dist/integrations/configure/copilot.js +14 -0
- package/dist/integrations/configure/copilot.js.map +1 -0
- package/dist/integrations/configure/droid.d.ts +12 -0
- package/dist/integrations/configure/droid.js +47 -0
- package/dist/integrations/configure/droid.js.map +1 -0
- package/dist/integrations/configure/dsh.d.ts +34 -0
- package/dist/integrations/configure/dsh.js +146 -0
- package/dist/integrations/configure/dsh.js.map +1 -0
- package/dist/integrations/configure/env-agent.d.ts +26 -0
- package/dist/integrations/configure/env-agent.js +41 -0
- package/dist/integrations/configure/env-agent.js.map +1 -0
- package/dist/integrations/configure/goose.d.ts +12 -0
- package/dist/integrations/configure/goose.js +16 -0
- package/dist/integrations/configure/goose.js.map +1 -0
- package/dist/integrations/configure/hermes.d.ts +41 -0
- package/dist/integrations/configure/hermes.js +247 -0
- package/dist/integrations/configure/hermes.js.map +1 -0
- package/dist/integrations/configure/index.d.ts +25 -0
- package/dist/integrations/configure/index.js +26 -0
- package/dist/integrations/configure/index.js.map +1 -0
- package/dist/integrations/configure/json-tree.d.ts +16 -0
- package/dist/integrations/configure/json-tree.js +19 -0
- package/dist/integrations/configure/json-tree.js.map +1 -0
- package/dist/integrations/configure/kilo.d.ts +9 -0
- package/dist/integrations/configure/kilo.js +19 -0
- package/dist/integrations/configure/kilo.js.map +1 -0
- package/dist/integrations/configure/mimo.d.ts +9 -0
- package/dist/integrations/configure/mimo.js +19 -0
- package/dist/integrations/configure/mimo.js.map +1 -0
- package/dist/integrations/configure/muse.d.ts +9 -0
- package/dist/integrations/configure/muse.js +13 -0
- package/dist/integrations/configure/muse.js.map +1 -0
- package/dist/integrations/configure/openclaude.d.ts +13 -0
- package/dist/integrations/configure/openclaude.js +56 -0
- package/dist/integrations/configure/openclaude.js.map +1 -0
- package/dist/integrations/configure/openclaw.d.ts +24 -0
- package/dist/integrations/configure/openclaw.js +99 -0
- package/dist/integrations/configure/openclaw.js.map +1 -0
- package/dist/integrations/configure/opencode-style.d.ts +25 -0
- package/dist/integrations/configure/opencode-style.js +43 -0
- package/dist/integrations/configure/opencode-style.js.map +1 -0
- package/dist/integrations/configure/opencode.d.ts +9 -0
- package/dist/integrations/configure/opencode.js +19 -0
- package/dist/integrations/configure/opencode.js.map +1 -0
- package/dist/integrations/configure/openhands.d.ts +8 -0
- package/dist/integrations/configure/openhands.js +12 -0
- package/dist/integrations/configure/openhands.js.map +1 -0
- package/dist/integrations/configure/pi.d.ts +14 -0
- package/dist/integrations/configure/pi.js +49 -0
- package/dist/integrations/configure/pi.js.map +1 -0
- package/dist/integrations/configure/poolside.d.ts +8 -0
- package/dist/integrations/configure/poolside.js +12 -0
- package/dist/integrations/configure/poolside.js.map +1 -0
- package/dist/integrations/configure/registry.d.ts +41 -0
- package/dist/integrations/configure/registry.js +50 -0
- package/dist/integrations/configure/registry.js.map +1 -0
- package/dist/integrations/configure/zcode.d.ts +59 -0
- package/dist/integrations/configure/zcode.js +260 -0
- package/dist/integrations/configure/zcode.js.map +1 -0
- package/dist/integrations/configure/zed.d.ts +16 -0
- package/dist/integrations/configure/zed.js +61 -0
- package/dist/integrations/configure/zed.js.map +1 -0
- package/dist/integrations/detect.d.ts +29 -0
- package/dist/integrations/detect.js +43 -0
- package/dist/integrations/detect.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.js +10 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/lock/control-token.d.ts +19 -0
- package/dist/lock/control-token.js +58 -0
- package/dist/lock/control-token.js.map +1 -0
- package/dist/lock/index.d.ts +10 -0
- package/dist/lock/index.js +11 -0
- package/dist/lock/index.js.map +1 -0
- package/dist/lock/instance-lock.d.ts +93 -0
- package/dist/lock/instance-lock.js +244 -0
- package/dist/lock/instance-lock.js.map +1 -0
- package/dist/lock/legacy-guard.d.ts +46 -0
- package/dist/lock/legacy-guard.js +87 -0
- package/dist/lock/legacy-guard.js.map +1 -0
- package/dist/lock/model-claim.d.ts +20 -0
- package/dist/lock/model-claim.js +84 -0
- package/dist/lock/model-claim.js.map +1 -0
- package/dist/lock/process-identity.d.ts +48 -0
- package/dist/lock/process-identity.js +180 -0
- package/dist/lock/process-identity.js.map +1 -0
- package/dist/lock/process-journal.d.ts +56 -0
- package/dist/lock/process-journal.js +113 -0
- package/dist/lock/process-journal.js.map +1 -0
- package/dist/models/capabilities.d.ts +73 -0
- package/dist/models/capabilities.js +123 -0
- package/dist/models/capabilities.js.map +1 -0
- package/dist/models/embed.d.ts +30 -0
- package/dist/models/embed.js +83 -0
- package/dist/models/embed.js.map +1 -0
- package/dist/models/gguf/classify.d.ts +29 -0
- package/dist/models/gguf/classify.js +89 -0
- package/dist/models/gguf/classify.js.map +1 -0
- package/dist/models/gguf/index.d.ts +5 -0
- package/dist/models/gguf/index.js +6 -0
- package/dist/models/gguf/index.js.map +1 -0
- package/dist/models/gguf/kv-cache.d.ts +27 -0
- package/dist/models/gguf/kv-cache.js +101 -0
- package/dist/models/gguf/kv-cache.js.map +1 -0
- package/dist/models/gguf/read-file.d.ts +11 -0
- package/dist/models/gguf/read-file.js +21 -0
- package/dist/models/gguf/read-file.js.map +1 -0
- package/dist/models/gguf/reader.d.ts +40 -0
- package/dist/models/gguf/reader.js +271 -0
- package/dist/models/gguf/reader.js.map +1 -0
- package/dist/models/gguf/support.d.ts +47 -0
- package/dist/models/gguf/support.js +48 -0
- package/dist/models/gguf/support.js.map +1 -0
- package/dist/models/hf.d.ts +35 -0
- package/dist/models/hf.js +140 -0
- package/dist/models/hf.js.map +1 -0
- package/dist/models/index.d.ts +14 -0
- package/dist/models/index.js +15 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/model-yml.d.ts +22 -0
- package/dist/models/model-yml.js +63 -0
- package/dist/models/model-yml.js.map +1 -0
- package/dist/models/registry.d.ts +51 -0
- package/dist/models/registry.js +102 -0
- package/dist/models/registry.js.map +1 -0
- package/dist/models/shards.d.ts +20 -0
- package/dist/models/shards.js +46 -0
- package/dist/models/shards.js.map +1 -0
- package/dist/remote-access/cloudflared-args.d.ts +41 -0
- package/dist/remote-access/cloudflared-args.js +59 -0
- package/dist/remote-access/cloudflared-args.js.map +1 -0
- package/dist/remote-access/cloudflared-output.d.ts +26 -0
- package/dist/remote-access/cloudflared-output.js +51 -0
- package/dist/remote-access/cloudflared-output.js.map +1 -0
- package/dist/remote-access/index.d.ts +16 -0
- package/dist/remote-access/index.js +17 -0
- package/dist/remote-access/index.js.map +1 -0
- package/dist/remote-access/journal.d.ts +63 -0
- package/dist/remote-access/journal.js +140 -0
- package/dist/remote-access/journal.js.map +1 -0
- package/dist/remote-access/lan-probe.d.ts +28 -0
- package/dist/remote-access/lan-probe.js +63 -0
- package/dist/remote-access/lan-probe.js.map +1 -0
- package/dist/remote-access/lan.d.ts +31 -0
- package/dist/remote-access/lan.js +90 -0
- package/dist/remote-access/lan.js.map +1 -0
- package/dist/remote-access/manager.d.ts +111 -0
- package/dist/remote-access/manager.js +316 -0
- package/dist/remote-access/manager.js.map +1 -0
- package/dist/remote-access/probe.d.ts +92 -0
- package/dist/remote-access/probe.js +186 -0
- package/dist/remote-access/probe.js.map +1 -0
- package/dist/remote-access/process.d.ts +66 -0
- package/dist/remote-access/process.js +160 -0
- package/dist/remote-access/process.js.map +1 -0
- package/dist/remote-access/spawner.d.ts +25 -0
- package/dist/remote-access/spawner.js +49 -0
- package/dist/remote-access/spawner.js.map +1 -0
- package/dist/remote-access/status.d.ts +39 -0
- package/dist/remote-access/status.js +49 -0
- package/dist/remote-access/status.js.map +1 -0
- package/dist/remote-access/wiring.d.ts +34 -0
- package/dist/remote-access/wiring.js +47 -0
- package/dist/remote-access/wiring.js.map +1 -0
- package/dist/router/index.d.ts +7 -0
- package/dist/router/index.js +8 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/resolve.d.ts +41 -0
- package/dist/router/resolve.js +53 -0
- package/dist/router/resolve.js.map +1 -0
- package/dist/runtime/foundation-models/errors.d.ts +28 -0
- package/dist/runtime/foundation-models/errors.js +48 -0
- package/dist/runtime/foundation-models/errors.js.map +1 -0
- package/dist/runtime/foundation-models/index.d.ts +8 -0
- package/dist/runtime/foundation-models/index.js +9 -0
- package/dist/runtime/foundation-models/index.js.map +1 -0
- package/dist/runtime/foundation-models/runtime.d.ts +73 -0
- package/dist/runtime/foundation-models/runtime.js +186 -0
- package/dist/runtime/foundation-models/runtime.js.map +1 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.js +6 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/llamacpp/args.d.ts +90 -0
- package/dist/runtime/llamacpp/args.js +379 -0
- package/dist/runtime/llamacpp/args.js.map +1 -0
- package/dist/runtime/llamacpp/ctx-ladder.d.ts +16 -0
- package/dist/runtime/llamacpp/ctx-ladder.js +28 -0
- package/dist/runtime/llamacpp/ctx-ladder.js.map +1 -0
- package/dist/runtime/llamacpp/devices.d.ts +26 -0
- package/dist/runtime/llamacpp/devices.js +86 -0
- package/dist/runtime/llamacpp/devices.js.map +1 -0
- package/dist/runtime/llamacpp/errors.d.ts +34 -0
- package/dist/runtime/llamacpp/errors.js +137 -0
- package/dist/runtime/llamacpp/errors.js.map +1 -0
- package/dist/runtime/llamacpp/index.d.ts +14 -0
- package/dist/runtime/llamacpp/index.js +15 -0
- package/dist/runtime/llamacpp/index.js.map +1 -0
- package/dist/runtime/llamacpp/load-plan.d.ts +113 -0
- package/dist/runtime/llamacpp/load-plan.js +259 -0
- package/dist/runtime/llamacpp/load-plan.js.map +1 -0
- package/dist/runtime/llamacpp/policy.d.ts +70 -0
- package/dist/runtime/llamacpp/policy.js +191 -0
- package/dist/runtime/llamacpp/policy.js.map +1 -0
- package/dist/runtime/llamacpp/probe.d.ts +13 -0
- package/dist/runtime/llamacpp/probe.js +35 -0
- package/dist/runtime/llamacpp/probe.js.map +1 -0
- package/dist/runtime/llamacpp/runtime-device.d.ts +33 -0
- package/dist/runtime/llamacpp/runtime-device.js +169 -0
- package/dist/runtime/llamacpp/runtime-device.js.map +1 -0
- package/dist/runtime/llamacpp/runtime.d.ts +151 -0
- package/dist/runtime/llamacpp/runtime.js +535 -0
- package/dist/runtime/llamacpp/runtime.js.map +1 -0
- package/dist/runtime/mlx/args.d.ts +10 -0
- package/dist/runtime/mlx/args.js +44 -0
- package/dist/runtime/mlx/args.js.map +1 -0
- package/dist/runtime/mlx/config.d.ts +71 -0
- package/dist/runtime/mlx/config.js +91 -0
- package/dist/runtime/mlx/config.js.map +1 -0
- package/dist/runtime/mlx/errors.d.ts +21 -0
- package/dist/runtime/mlx/errors.js +73 -0
- package/dist/runtime/mlx/errors.js.map +1 -0
- package/dist/runtime/mlx/index.d.ts +12 -0
- package/dist/runtime/mlx/index.js +13 -0
- package/dist/runtime/mlx/index.js.map +1 -0
- package/dist/runtime/mlx/model-files.d.ts +29 -0
- package/dist/runtime/mlx/model-files.js +82 -0
- package/dist/runtime/mlx/model-files.js.map +1 -0
- package/dist/runtime/mlx/runtime.d.ts +77 -0
- package/dist/runtime/mlx/runtime.js +223 -0
- package/dist/runtime/mlx/runtime.js.map +1 -0
- package/dist/runtime/mlx/shard-repair.d.ts +25 -0
- package/dist/runtime/mlx/shard-repair.js +44 -0
- package/dist/runtime/mlx/shard-repair.js.map +1 -0
- package/dist/runtime/shared/env.d.ts +49 -0
- package/dist/runtime/shared/env.js +155 -0
- package/dist/runtime/shared/env.js.map +1 -0
- package/dist/runtime/shared/external-sessions.d.ts +67 -0
- package/dist/runtime/shared/external-sessions.js +155 -0
- package/dist/runtime/shared/external-sessions.js.map +1 -0
- package/dist/runtime/shared/index.d.ts +17 -0
- package/dist/runtime/shared/index.js +18 -0
- package/dist/runtime/shared/index.js.map +1 -0
- package/dist/runtime/shared/load-cancel.d.ts +45 -0
- package/dist/runtime/shared/load-cancel.js +95 -0
- package/dist/runtime/shared/load-cancel.js.map +1 -0
- package/dist/runtime/shared/local-runtime.d.ts +68 -0
- package/dist/runtime/shared/local-runtime.js +12 -0
- package/dist/runtime/shared/local-runtime.js.map +1 -0
- package/dist/runtime/shared/log-stream.d.ts +4 -0
- package/dist/runtime/shared/log-stream.js +28 -0
- package/dist/runtime/shared/log-stream.js.map +1 -0
- package/dist/runtime/shared/paths.d.ts +21 -0
- package/dist/runtime/shared/paths.js +63 -0
- package/dist/runtime/shared/paths.js.map +1 -0
- package/dist/runtime/shared/ports.d.ts +26 -0
- package/dist/runtime/shared/ports.js +45 -0
- package/dist/runtime/shared/ports.js.map +1 -0
- package/dist/runtime/shared/process.d.ts +95 -0
- package/dist/runtime/shared/process.js +224 -0
- package/dist/runtime/shared/process.js.map +1 -0
- package/dist/runtime/shared/sidecar.d.ts +86 -0
- package/dist/runtime/shared/sidecar.js +214 -0
- package/dist/runtime/shared/sidecar.js.map +1 -0
- package/dist/server/clients.d.ts +40 -0
- package/dist/server/clients.js +74 -0
- package/dist/server/clients.js.map +1 -0
- package/dist/server/control/index.d.ts +12 -0
- package/dist/server/control/index.js +12 -0
- package/dist/server/control/index.js.map +1 -0
- package/dist/server/control/router.d.ts +9 -0
- package/dist/server/control/router.js +61 -0
- package/dist/server/control/router.js.map +1 -0
- package/dist/server/control/routes/backends.d.ts +4 -0
- package/dist/server/control/routes/backends.js +47 -0
- package/dist/server/control/routes/backends.js.map +1 -0
- package/dist/server/control/routes/clients.d.ts +4 -0
- package/dist/server/control/routes/clients.js +30 -0
- package/dist/server/control/routes/clients.js.map +1 -0
- package/dist/server/control/routes/cloud.d.ts +4 -0
- package/dist/server/control/routes/cloud.js +32 -0
- package/dist/server/control/routes/cloud.js.map +1 -0
- package/dist/server/control/routes/diffusion-video.d.ts +10 -0
- package/dist/server/control/routes/diffusion-video.js +33 -0
- package/dist/server/control/routes/diffusion-video.js.map +1 -0
- package/dist/server/control/routes/diffusion.d.ts +15 -0
- package/dist/server/control/routes/diffusion.js +71 -0
- package/dist/server/control/routes/diffusion.js.map +1 -0
- package/dist/server/control/routes/disk.d.ts +4 -0
- package/dist/server/control/routes/disk.js +11 -0
- package/dist/server/control/routes/disk.js.map +1 -0
- package/dist/server/control/routes/external-sessions.d.ts +4 -0
- package/dist/server/control/routes/external-sessions.js +27 -0
- package/dist/server/control/routes/external-sessions.js.map +1 -0
- package/dist/server/control/routes/hardware.d.ts +4 -0
- package/dist/server/control/routes/hardware.js +14 -0
- package/dist/server/control/routes/hardware.js.map +1 -0
- package/dist/server/control/routes/lifecycle.d.ts +12 -0
- package/dist/server/control/routes/lifecycle.js +67 -0
- package/dist/server/control/routes/lifecycle.js.map +1 -0
- package/dist/server/control/routes/models.d.ts +7 -0
- package/dist/server/control/routes/models.js +59 -0
- package/dist/server/control/routes/models.js.map +1 -0
- package/dist/server/control/routes/public-server.d.ts +4 -0
- package/dist/server/control/routes/public-server.js +30 -0
- package/dist/server/control/routes/public-server.js.map +1 -0
- package/dist/server/control/routes/remote-access.d.ts +7 -0
- package/dist/server/control/routes/remote-access.js +16 -0
- package/dist/server/control/routes/remote-access.js.map +1 -0
- package/dist/server/control/routes/settings.d.ts +4 -0
- package/dist/server/control/routes/settings.js +58 -0
- package/dist/server/control/routes/settings.js.map +1 -0
- package/dist/server/control/routes/telemetry.d.ts +7 -0
- package/dist/server/control/routes/telemetry.js +46 -0
- package/dist/server/control/routes/telemetry.js.map +1 -0
- package/dist/server/control/server.d.ts +26 -0
- package/dist/server/control/server.js +111 -0
- package/dist/server/control/server.js.map +1 -0
- package/dist/server/control/types.d.ts +271 -0
- package/dist/server/control/types.js +6 -0
- package/dist/server/control/types.js.map +1 -0
- package/dist/server/http.d.ts +62 -0
- package/dist/server/http.js +220 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +10 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/public/ctx.d.ts +23 -0
- package/dist/server/public/ctx.js +42 -0
- package/dist/server/public/ctx.js.map +1 -0
- package/dist/server/public/dynamic-hosts.d.ts +40 -0
- package/dist/server/public/dynamic-hosts.js +117 -0
- package/dist/server/public/dynamic-hosts.js.map +1 -0
- package/dist/server/public/errors.d.ts +36 -0
- package/dist/server/public/errors.js +120 -0
- package/dist/server/public/errors.js.map +1 -0
- package/dist/server/public/exchange.d.ts +42 -0
- package/dist/server/public/exchange.js +85 -0
- package/dist/server/public/exchange.js.map +1 -0
- package/dist/server/public/forward.d.ts +53 -0
- package/dist/server/public/forward.js +448 -0
- package/dist/server/public/forward.js.map +1 -0
- package/dist/server/public/gates.d.ts +49 -0
- package/dist/server/public/gates.js +181 -0
- package/dist/server/public/gates.js.map +1 -0
- package/dist/server/public/images-params.d.ts +50 -0
- package/dist/server/public/images-params.js +162 -0
- package/dist/server/public/images-params.js.map +1 -0
- package/dist/server/public/images.d.ts +12 -0
- package/dist/server/public/images.js +96 -0
- package/dist/server/public/images.js.map +1 -0
- package/dist/server/public/index.d.ts +58 -0
- package/dist/server/public/index.js +253 -0
- package/dist/server/public/index.js.map +1 -0
- package/dist/server/public/listing.d.ts +27 -0
- package/dist/server/public/listing.js +116 -0
- package/dist/server/public/listing.js.map +1 -0
- package/dist/server/public/responses.d.ts +11 -0
- package/dist/server/public/responses.js +158 -0
- package/dist/server/public/responses.js.map +1 -0
- package/dist/server/public/sse.d.ts +33 -0
- package/dist/server/public/sse.js +48 -0
- package/dist/server/public/sse.js.map +1 -0
- package/dist/server/public/static-assets.generated.d.ts +3 -0
- package/dist/server/public/static-assets.generated.js +6 -0
- package/dist/server/public/static-assets.generated.js.map +1 -0
- package/dist/server/public/static.d.ts +13 -0
- package/dist/server/public/static.js +75 -0
- package/dist/server/public/static.js.map +1 -0
- package/dist/server/public/subscription.d.ts +14 -0
- package/dist/server/public/subscription.js +56 -0
- package/dist/server/public/subscription.js.map +1 -0
- package/dist/server/public/telemetry.d.ts +65 -0
- package/dist/server/public/telemetry.js +284 -0
- package/dist/server/public/telemetry.js.map +1 -0
- package/dist/server/public/trace.d.ts +66 -0
- package/dist/server/public/trace.js +223 -0
- package/dist/server/public/trace.js.map +1 -0
- package/dist/server/public/types.d.ts +131 -0
- package/dist/server/public/types.js +9 -0
- package/dist/server/public/types.js.map +1 -0
- package/dist/server/public/videos-params.d.ts +95 -0
- package/dist/server/public/videos-params.js +220 -0
- package/dist/server/public/videos-params.js.map +1 -0
- package/dist/server/public/videos.d.ts +16 -0
- package/dist/server/public/videos.js +188 -0
- package/dist/server/public/videos.js.map +1 -0
- package/dist/server/public/wire.d.ts +53 -0
- package/dist/server/public/wire.js +174 -0
- package/dist/server/public/wire.js.map +1 -0
- package/dist/server/shims/anthropic.d.ts +52 -0
- package/dist/server/shims/anthropic.js +519 -0
- package/dist/server/shims/anthropic.js.map +1 -0
- package/dist/server/shims/chat-to-responses.d.ts +113 -0
- package/dist/server/shims/chat-to-responses.js +557 -0
- package/dist/server/shims/chat-to-responses.js.map +1 -0
- package/dist/server/shims/index.d.ts +8 -0
- package/dist/server/shims/index.js +9 -0
- package/dist/server/shims/index.js.map +1 -0
- package/dist/server/shims/json.d.ts +10 -0
- package/dist/server/shims/json.js +78 -0
- package/dist/server/shims/json.js.map +1 -0
- package/dist/server/shims/responses.d.ts +79 -0
- package/dist/server/shims/responses.js +543 -0
- package/dist/server/shims/responses.js.map +1 -0
- package/dist/server/state-file.d.ts +44 -0
- package/dist/server/state-file.js +107 -0
- package/dist/server/state-file.js.map +1 -0
- package/dist/settings/import.d.ts +61 -0
- package/dist/settings/import.js +104 -0
- package/dist/settings/import.js.map +1 -0
- package/dist/settings/index.d.ts +11 -0
- package/dist/settings/index.js +12 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/schema/foundation-models.json +1 -0
- package/dist/settings/schema/llamacpp-upstream.json +489 -0
- package/dist/settings/schema/llamacpp.json +475 -0
- package/dist/settings/schema/mlx.json +136 -0
- package/dist/settings/schema.d.ts +35 -0
- package/dist/settings/schema.js +196 -0
- package/dist/settings/schema.js.map +1 -0
- package/dist/settings/store.d.ts +168 -0
- package/dist/settings/store.js +350 -0
- package/dist/settings/store.js.map +1 -0
- package/dist/speculative/chat-template-overrides.d.ts +35 -0
- package/dist/speculative/chat-template-overrides.js +142 -0
- package/dist/speculative/chat-template-overrides.js.map +1 -0
- package/dist/speculative/dflash-registry.d.ts +50 -0
- package/dist/speculative/dflash-registry.js +258 -0
- package/dist/speculative/dflash-registry.js.map +1 -0
- package/dist/speculative/gemma-mtp-registry.d.ts +48 -0
- package/dist/speculative/gemma-mtp-registry.js +79 -0
- package/dist/speculative/gemma-mtp-registry.js.map +1 -0
- package/dist/speculative/index.d.ts +18 -0
- package/dist/speculative/index.js +19 -0
- package/dist/speculative/index.js.map +1 -0
- package/dist/speculative/mlx-dflash-registry.d.ts +39 -0
- package/dist/speculative/mlx-dflash-registry.js +230 -0
- package/dist/speculative/mlx-dflash-registry.js.map +1 -0
- package/dist/speculative/mlx-eagle3-registry.d.ts +24 -0
- package/dist/speculative/mlx-eagle3-registry.js +81 -0
- package/dist/speculative/mlx-eagle3-registry.js.map +1 -0
- package/dist/speculative/mlx-mtp-registry.d.ts +31 -0
- package/dist/speculative/mlx-mtp-registry.js +139 -0
- package/dist/speculative/mlx-mtp-registry.js.map +1 -0
- package/dist/speculative/transcription-registry.d.ts +72 -0
- package/dist/speculative/transcription-registry.js +94 -0
- package/dist/speculative/transcription-registry.js.map +1 -0
- package/dist/telemetry/config.d.ts +38 -0
- package/dist/telemetry/config.js +44 -0
- package/dist/telemetry/config.js.map +1 -0
- package/dist/telemetry/consent.d.ts +21 -0
- package/dist/telemetry/consent.js +35 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/core-reporter.d.ts +47 -0
- package/dist/telemetry/core-reporter.js +72 -0
- package/dist/telemetry/core-reporter.js.map +1 -0
- package/dist/telemetry/daemon.d.ts +40 -0
- package/dist/telemetry/daemon.js +67 -0
- package/dist/telemetry/daemon.js.map +1 -0
- package/dist/telemetry/dsn.d.ts +15 -0
- package/dist/telemetry/dsn.js +32 -0
- package/dist/telemetry/dsn.js.map +1 -0
- package/dist/telemetry/envelope.d.ts +97 -0
- package/dist/telemetry/envelope.js +95 -0
- package/dist/telemetry/envelope.js.map +1 -0
- package/dist/telemetry/index.d.ts +18 -0
- package/dist/telemetry/index.js +19 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/policy.d.ts +39 -0
- package/dist/telemetry/policy.js +142 -0
- package/dist/telemetry/policy.js.map +1 -0
- package/dist/telemetry/reporter.d.ts +80 -0
- package/dist/telemetry/reporter.js +0 -0
- package/dist/telemetry/reporter.js.map +1 -0
- package/dist/telemetry/reports.d.ts +68 -0
- package/dist/telemetry/reports.js +212 -0
- package/dist/telemetry/reports.js.map +1 -0
- package/dist/telemetry/scrub.d.ts +19 -0
- package/dist/telemetry/scrub.js +75 -0
- package/dist/telemetry/scrub.js.map +1 -0
- package/dist/telemetry/stack.d.ts +21 -0
- package/dist/telemetry/stack.js +68 -0
- package/dist/telemetry/stack.js.map +1 -0
- package/dist/telemetry/store.d.ts +17 -0
- package/dist/telemetry/store.js +51 -0
- package/dist/telemetry/store.js.map +1 -0
- package/dist/telemetry/subscribe.d.ts +13 -0
- package/dist/telemetry/subscribe.js +19 -0
- package/dist/telemetry/subscribe.js.map +1 -0
- package/dist/telemetry/types.d.ts +40 -0
- package/dist/telemetry/types.js +2 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/util/index.d.ts +5 -0
- package/dist/util/index.js +6 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/rust-number.d.ts +27 -0
- package/dist/util/rust-number.js +101 -0
- package/dist/util/rust-number.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +86 -0
- package/src/settings/schema/foundation-models.json +1 -0
- package/src/settings/schema/llamacpp-upstream.json +489 -0
- package/src/settings/schema/llamacpp.json +475 -0
- package/src/settings/schema/mlx.json +136 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is the process that wrote this file still the process behind that PID?"
|
|
3
|
+
*
|
|
4
|
+
* A PID alone cannot answer it: the OS reuses PIDs, so a dead owner's PID can belong to something
|
|
5
|
+
* else by the time a client looks (PLAN.md §3.4). Every owner therefore records a *start identity*
|
|
6
|
+
* next to its PID, and a taker-over must see that identity gone or different before it may steal
|
|
7
|
+
* the lock. When the identity cannot be established (no procfs, probe refused, unknown platform)
|
|
8
|
+
* the answer is `unknown`, never `mismatch` — an unproven claim must not kill a live owner.
|
|
9
|
+
*
|
|
10
|
+
* No native addons: Linux reads procfs, macOS asks `ps`, Windows asks PowerShell.
|
|
11
|
+
*/
|
|
12
|
+
export type IdentityVerdict = 'match' | 'mismatch' | 'dead' | 'unknown';
|
|
13
|
+
export interface IdentityDeps {
|
|
14
|
+
platform?: NodeJS.Platform;
|
|
15
|
+
/** Read a procfs entry (Linux). */
|
|
16
|
+
readText?: (path: string) => Promise<string>;
|
|
17
|
+
/** Run a probe and return its stdout. */
|
|
18
|
+
run?: (file: string, args: string[]) => Promise<string>;
|
|
19
|
+
/** Signal-0 liveness probe. */
|
|
20
|
+
alive?: (pid: number) => boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* PowerShell on Windows takes several seconds to start cold, and on a loaded CI runner more than
|
|
24
|
+
* five; a probe that is cut short answers `undefined`, which is safe for takeover but leaves a
|
|
25
|
+
* child journalled without its identity. The budget is generous because a slow answer is worth
|
|
26
|
+
* more than a fast "unknown".
|
|
27
|
+
*/
|
|
28
|
+
export declare const IDENTITY_PROBE_TIMEOUT_MS = 15000;
|
|
29
|
+
export declare function isProcessAlive(pid: number): boolean;
|
|
30
|
+
export declare function runProbe(file: string, args: string[]): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* An opaque, comparable token for "this incarnation of this PID", or `undefined` when the platform
|
|
33
|
+
* cannot tell us. Only ever compared for equality, never parsed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function processStartId(pid: number, deps?: IdentityDeps): Promise<string | undefined>;
|
|
36
|
+
/** Cross-language process identity used in files shared with the Rust desktop app. */
|
|
37
|
+
export declare function processStartEpoch(pid: number, deps?: IdentityDeps): Promise<string | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* The executable name of a live process, without its directory (and without `.exe`), or `undefined`
|
|
40
|
+
* when it cannot be read. A second, independent check next to the start identity for a process that
|
|
41
|
+
* is only ever ended by name *and* identity — the remote-access tunnel, because people who want that
|
|
42
|
+
* feature often run a `cloudflared` of their own that must never be touched.
|
|
43
|
+
*/
|
|
44
|
+
export declare function processName(pid: number, deps?: IdentityDeps): Promise<string | undefined>;
|
|
45
|
+
/** Compare a recorded identity with the live process. `unknown` means "cannot prove"; treat as live. */
|
|
46
|
+
export declare function verifyProcessIdentity(pid: number, expected: string | null | undefined, deps?: IdentityDeps): Promise<IdentityVerdict>;
|
|
47
|
+
/** Only a proven-gone process releases what it held. */
|
|
48
|
+
export declare function identityPermitsTakeover(verdict: IdentityVerdict): boolean;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is the process that wrote this file still the process behind that PID?"
|
|
3
|
+
*
|
|
4
|
+
* A PID alone cannot answer it: the OS reuses PIDs, so a dead owner's PID can belong to something
|
|
5
|
+
* else by the time a client looks (PLAN.md §3.4). Every owner therefore records a *start identity*
|
|
6
|
+
* next to its PID, and a taker-over must see that identity gone or different before it may steal
|
|
7
|
+
* the lock. When the identity cannot be established (no procfs, probe refused, unknown platform)
|
|
8
|
+
* the answer is `unknown`, never `mismatch` — an unproven claim must not kill a live owner.
|
|
9
|
+
*
|
|
10
|
+
* No native addons: Linux reads procfs, macOS asks `ps`, Windows asks PowerShell.
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from 'node:child_process';
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
/**
|
|
15
|
+
* PowerShell on Windows takes several seconds to start cold, and on a loaded CI runner more than
|
|
16
|
+
* five; a probe that is cut short answers `undefined`, which is safe for takeover but leaves a
|
|
17
|
+
* child journalled without its identity. The budget is generous because a slow answer is worth
|
|
18
|
+
* more than a fast "unknown".
|
|
19
|
+
*/
|
|
20
|
+
export const IDENTITY_PROBE_TIMEOUT_MS = 15_000;
|
|
21
|
+
const readUtf8 = (path) => readFile(path, 'utf8');
|
|
22
|
+
export function isProcessAlive(pid) {
|
|
23
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
24
|
+
return false;
|
|
25
|
+
try {
|
|
26
|
+
process.kill(pid, 0);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
return e.code === 'EPERM';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function runProbe(file, args) {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
execFile(file, args, { timeout: IDENTITY_PROBE_TIMEOUT_MS, windowsHide: true }, (err, stdout) => {
|
|
36
|
+
if (err)
|
|
37
|
+
reject(err);
|
|
38
|
+
else
|
|
39
|
+
resolve(stdout);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* An opaque, comparable token for "this incarnation of this PID", or `undefined` when the platform
|
|
45
|
+
* cannot tell us. Only ever compared for equality, never parsed.
|
|
46
|
+
*/
|
|
47
|
+
export async function processStartId(pid, deps = {}) {
|
|
48
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
49
|
+
return undefined;
|
|
50
|
+
const platform = deps.platform ?? process.platform;
|
|
51
|
+
const readText = deps.readText ?? readUtf8;
|
|
52
|
+
const run = deps.run ?? runProbe;
|
|
53
|
+
try {
|
|
54
|
+
if (platform === 'linux') {
|
|
55
|
+
// /proc/<pid>/stat field 22 (starttime, in clock ticks since boot). The comm field may contain
|
|
56
|
+
// spaces and parentheses, so fields are counted after the last ')'.
|
|
57
|
+
const stat = await readText(`/proc/${pid}/stat`);
|
|
58
|
+
const tail = stat
|
|
59
|
+
.slice(stat.lastIndexOf(')') + 1)
|
|
60
|
+
.trim()
|
|
61
|
+
.split(/\s+/);
|
|
62
|
+
const startTicks = tail[19]; // field 22 = 3rd after state, which is tail[0]
|
|
63
|
+
return startTicks && /^\d+$/.test(startTicks) ? `linux:${startTicks}` : undefined;
|
|
64
|
+
}
|
|
65
|
+
if (platform === 'darwin') {
|
|
66
|
+
// `lstart` has one-second resolution; a PID reused inside the same second is indistinguishable,
|
|
67
|
+
// which the takeover path treats as "unknown", never as a free lock.
|
|
68
|
+
const out = await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)]);
|
|
69
|
+
const value = out.trim().replace(/\s+/g, ' ');
|
|
70
|
+
return value ? `darwin:${value}` : undefined;
|
|
71
|
+
}
|
|
72
|
+
if (platform === 'win32') {
|
|
73
|
+
const out = await run('powershell.exe', [
|
|
74
|
+
'-NoProfile',
|
|
75
|
+
'-NonInteractive',
|
|
76
|
+
'-Command',
|
|
77
|
+
`(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.Ticks`,
|
|
78
|
+
]);
|
|
79
|
+
const value = out.trim();
|
|
80
|
+
return /^\d+$/.test(value) ? `win32:${value}` : undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return undefined; // process gone, probe missing or refused
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/** Cross-language process identity used in files shared with the Rust desktop app. */
|
|
89
|
+
export async function processStartEpoch(pid, deps = {}) {
|
|
90
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
91
|
+
return undefined;
|
|
92
|
+
const platform = deps.platform ?? process.platform;
|
|
93
|
+
const readText = deps.readText ?? readUtf8;
|
|
94
|
+
const run = deps.run ?? runProbe;
|
|
95
|
+
try {
|
|
96
|
+
if (platform === 'linux') {
|
|
97
|
+
const [stat, procStat] = await Promise.all([readText(`/proc/${pid}/stat`), readText('/proc/stat')]);
|
|
98
|
+
const tail = stat
|
|
99
|
+
.slice(stat.lastIndexOf(')') + 1)
|
|
100
|
+
.trim()
|
|
101
|
+
.split(/\s+/);
|
|
102
|
+
const ticks = Number(tail[19]);
|
|
103
|
+
const boot = Number(/^btime\s+(\d+)$/m.exec(procStat)?.[1]);
|
|
104
|
+
if (!Number.isFinite(ticks) || !Number.isFinite(boot))
|
|
105
|
+
return undefined;
|
|
106
|
+
// Linux USER_HZ is 100 on the desktop targets Atomic Chat supports.
|
|
107
|
+
return `epoch:${Math.floor(boot + ticks / 100)}`;
|
|
108
|
+
}
|
|
109
|
+
if (platform === 'darwin') {
|
|
110
|
+
const out = (await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)])).trim();
|
|
111
|
+
const epoch = Math.floor(Date.parse(out) / 1000);
|
|
112
|
+
return Number.isFinite(epoch) ? `epoch:${epoch}` : undefined;
|
|
113
|
+
}
|
|
114
|
+
if (platform === 'win32') {
|
|
115
|
+
const out = await run('powershell.exe', [
|
|
116
|
+
'-NoProfile',
|
|
117
|
+
'-NonInteractive',
|
|
118
|
+
'-Command',
|
|
119
|
+
`[DateTimeOffset](Get-Process -Id ${pid} -ErrorAction Stop).StartTime | ForEach-Object { $_.ToUnixTimeSeconds() }`,
|
|
120
|
+
]);
|
|
121
|
+
const epoch = Number(out.trim());
|
|
122
|
+
return Number.isInteger(epoch) ? `epoch:${epoch}` : undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The executable name of a live process, without its directory (and without `.exe`), or `undefined`
|
|
132
|
+
* when it cannot be read. A second, independent check next to the start identity for a process that
|
|
133
|
+
* is only ever ended by name *and* identity — the remote-access tunnel, because people who want that
|
|
134
|
+
* feature often run a `cloudflared` of their own that must never be touched.
|
|
135
|
+
*/
|
|
136
|
+
export async function processName(pid, deps = {}) {
|
|
137
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
138
|
+
return undefined;
|
|
139
|
+
const platform = deps.platform ?? process.platform;
|
|
140
|
+
const readText = deps.readText ?? readUtf8;
|
|
141
|
+
const run = deps.run ?? runProbe;
|
|
142
|
+
try {
|
|
143
|
+
let raw;
|
|
144
|
+
if (platform === 'linux')
|
|
145
|
+
raw = await readText(`/proc/${pid}/comm`);
|
|
146
|
+
else if (platform === 'darwin')
|
|
147
|
+
raw = await run('/bin/ps', ['-o', 'comm=', '-p', String(pid)]);
|
|
148
|
+
else if (platform === 'win32')
|
|
149
|
+
raw = await run('powershell.exe', [
|
|
150
|
+
'-NoProfile',
|
|
151
|
+
'-NonInteractive',
|
|
152
|
+
'-Command',
|
|
153
|
+
`(Get-Process -Id ${pid} -ErrorAction Stop).ProcessName`,
|
|
154
|
+
]);
|
|
155
|
+
else
|
|
156
|
+
return undefined;
|
|
157
|
+
const name = (raw.trim().split(/[\\/]/).pop() ?? '').replace(/\.exe$/i, '');
|
|
158
|
+
return name === '' ? undefined : name;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return undefined; // process gone, probe missing or refused
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Compare a recorded identity with the live process. `unknown` means "cannot prove"; treat as live. */
|
|
165
|
+
export async function verifyProcessIdentity(pid, expected, deps = {}) {
|
|
166
|
+
const alive = deps.alive ?? isProcessAlive;
|
|
167
|
+
if (!alive(pid))
|
|
168
|
+
return 'dead';
|
|
169
|
+
if (!expected)
|
|
170
|
+
return 'unknown';
|
|
171
|
+
const actual = await processStartId(pid, deps);
|
|
172
|
+
if (!actual)
|
|
173
|
+
return 'unknown';
|
|
174
|
+
return actual === expected ? 'match' : 'mismatch';
|
|
175
|
+
}
|
|
176
|
+
/** Only a proven-gone process releases what it held. */
|
|
177
|
+
export function identityPermitsTakeover(verdict) {
|
|
178
|
+
return verdict === 'dead' || verdict === 'mismatch';
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=process-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-identity.js","sourceRoot":"","sources":["../../src/lock/process-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<data>/atomic-core/processes.json` — every backend process this core spawned, with the identity
|
|
3
|
+
* needed to recognise it later (PLAN.md §3.4).
|
|
4
|
+
*
|
|
5
|
+
* After a crash the new owner must clean up the previous owner's `llama-server` processes without
|
|
6
|
+
* killing anything else. A PID from a dead owner's journal may have been recycled, so a process is
|
|
7
|
+
* only a *confirmed* orphan when its recorded start identity still matches the live process and the
|
|
8
|
+
* owner that spawned it is provably gone. Anything unproven is left running and reported.
|
|
9
|
+
*/
|
|
10
|
+
import type { LocalProviderId } from '../contracts/index.js';
|
|
11
|
+
import type { DataLayout } from '../config/index.js';
|
|
12
|
+
import type { IdentityDeps } from './process-identity.js';
|
|
13
|
+
export interface ChildProcessRecord {
|
|
14
|
+
/** Core instance that spawned it. */
|
|
15
|
+
instance_id: string;
|
|
16
|
+
pid: number;
|
|
17
|
+
process_start_id: string | null;
|
|
18
|
+
exe: string;
|
|
19
|
+
/** `diffusion` for the image engine, which is not a provider (its `sd-server` is reaped all the same). */
|
|
20
|
+
provider: LocalProviderId | 'diffusion';
|
|
21
|
+
model_id: string;
|
|
22
|
+
port: number;
|
|
23
|
+
started_at: string;
|
|
24
|
+
}
|
|
25
|
+
export interface OrphanScan {
|
|
26
|
+
/** Same process, spawned by an owner that is gone: safe to terminate. */
|
|
27
|
+
confirmed: ChildProcessRecord[];
|
|
28
|
+
/** Alive but unprovable, or owned by the live owner: left alone. */
|
|
29
|
+
skipped: Array<{
|
|
30
|
+
record: ChildProcessRecord;
|
|
31
|
+
reason: 'owner-alive' | 'identity-unproven' | 'current-instance';
|
|
32
|
+
}>;
|
|
33
|
+
/** Already gone: drop from the journal. */
|
|
34
|
+
gone: ChildProcessRecord[];
|
|
35
|
+
}
|
|
36
|
+
export declare class ProcessJournal {
|
|
37
|
+
private readonly path;
|
|
38
|
+
private records;
|
|
39
|
+
private queue;
|
|
40
|
+
private constructor();
|
|
41
|
+
static open(layout: DataLayout): Promise<ProcessJournal>;
|
|
42
|
+
list(): ChildProcessRecord[];
|
|
43
|
+
/** A journal entry must exist before the child can produce work, so this write is awaited. */
|
|
44
|
+
add(record: ChildProcessRecord): Promise<void>;
|
|
45
|
+
remove(pid: number): Promise<void>;
|
|
46
|
+
replace(records: ChildProcessRecord[]): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Classify the journal against reality. `currentInstanceId` is this owner: its own children are
|
|
49
|
+
* never orphans, and an entry from an owner that is still alive belongs to that owner.
|
|
50
|
+
*/
|
|
51
|
+
scanOrphans(currentInstanceId: string, liveOwnerInstanceIds: ReadonlySet<string>, deps?: IdentityDeps): Promise<OrphanScan>;
|
|
52
|
+
/** Forget entries for processes that are gone or were adopted elsewhere. */
|
|
53
|
+
forget(records: ChildProcessRecord[]): Promise<void>;
|
|
54
|
+
/** Serialised so concurrent adds cannot interleave a read-modify-write. */
|
|
55
|
+
private flush;
|
|
56
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<data>/atomic-core/processes.json` — every backend process this core spawned, with the identity
|
|
3
|
+
* needed to recognise it later (PLAN.md §3.4).
|
|
4
|
+
*
|
|
5
|
+
* After a crash the new owner must clean up the previous owner's `llama-server` processes without
|
|
6
|
+
* killing anything else. A PID from a dead owner's journal may have been recycled, so a process is
|
|
7
|
+
* only a *confirmed* orphan when its recorded start identity still matches the live process and the
|
|
8
|
+
* owner that spawned it is provably gone. Anything unproven is left running and reported.
|
|
9
|
+
*/
|
|
10
|
+
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { dirname } from 'node:path';
|
|
12
|
+
import { verifyProcessIdentity } from './process-identity.js';
|
|
13
|
+
export class ProcessJournal {
|
|
14
|
+
path;
|
|
15
|
+
records = [];
|
|
16
|
+
queue = Promise.resolve();
|
|
17
|
+
constructor(path) {
|
|
18
|
+
this.path = path;
|
|
19
|
+
}
|
|
20
|
+
static async open(layout) {
|
|
21
|
+
const journal = new ProcessJournal(layout.core.processes);
|
|
22
|
+
journal.records = await readJournal(layout.core.processes);
|
|
23
|
+
return journal;
|
|
24
|
+
}
|
|
25
|
+
list() {
|
|
26
|
+
return this.records.map((r) => ({ ...r }));
|
|
27
|
+
}
|
|
28
|
+
/** A journal entry must exist before the child can produce work, so this write is awaited. */
|
|
29
|
+
async add(record) {
|
|
30
|
+
this.records = [...this.records.filter((r) => r.pid !== record.pid), record];
|
|
31
|
+
await this.flush();
|
|
32
|
+
}
|
|
33
|
+
async remove(pid) {
|
|
34
|
+
if (!this.records.some((r) => r.pid === pid))
|
|
35
|
+
return;
|
|
36
|
+
this.records = this.records.filter((r) => r.pid !== pid);
|
|
37
|
+
await this.flush();
|
|
38
|
+
}
|
|
39
|
+
async replace(records) {
|
|
40
|
+
this.records = [...records];
|
|
41
|
+
await this.flush();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Classify the journal against reality. `currentInstanceId` is this owner: its own children are
|
|
45
|
+
* never orphans, and an entry from an owner that is still alive belongs to that owner.
|
|
46
|
+
*/
|
|
47
|
+
async scanOrphans(currentInstanceId, liveOwnerInstanceIds, deps = {}) {
|
|
48
|
+
const scan = { confirmed: [], skipped: [], gone: [] };
|
|
49
|
+
for (const record of this.records) {
|
|
50
|
+
if (record.instance_id === currentInstanceId) {
|
|
51
|
+
scan.skipped.push({ record, reason: 'current-instance' });
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (liveOwnerInstanceIds.has(record.instance_id)) {
|
|
55
|
+
scan.skipped.push({ record, reason: 'owner-alive' });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const verdict = await verifyProcessIdentity(record.pid, record.process_start_id, deps);
|
|
59
|
+
if (verdict === 'dead' || verdict === 'mismatch')
|
|
60
|
+
scan.gone.push(record);
|
|
61
|
+
else if (verdict === 'match')
|
|
62
|
+
scan.confirmed.push(record);
|
|
63
|
+
else
|
|
64
|
+
scan.skipped.push({ record, reason: 'identity-unproven' });
|
|
65
|
+
}
|
|
66
|
+
return scan;
|
|
67
|
+
}
|
|
68
|
+
/** Forget entries for processes that are gone or were adopted elsewhere. */
|
|
69
|
+
async forget(records) {
|
|
70
|
+
if (records.length === 0)
|
|
71
|
+
return;
|
|
72
|
+
const drop = new Set(records.map((r) => r.pid));
|
|
73
|
+
this.records = this.records.filter((r) => !drop.has(r.pid));
|
|
74
|
+
await this.flush();
|
|
75
|
+
}
|
|
76
|
+
/** Serialised so concurrent adds cannot interleave a read-modify-write. */
|
|
77
|
+
flush() {
|
|
78
|
+
this.queue = this.queue.then(() => writeJournal(this.path, this.records));
|
|
79
|
+
return this.queue;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function readJournal(path) {
|
|
83
|
+
const text = await readFile(path, 'utf8').catch(() => '');
|
|
84
|
+
if (!text.trim())
|
|
85
|
+
return [];
|
|
86
|
+
let raw;
|
|
87
|
+
try {
|
|
88
|
+
raw = JSON.parse(text);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return []; // a truncated journal costs cleanup, not correctness: unknown processes are never killed
|
|
92
|
+
}
|
|
93
|
+
const list = Array.isArray(raw) ? raw : raw?.processes;
|
|
94
|
+
if (!Array.isArray(list))
|
|
95
|
+
return [];
|
|
96
|
+
return list.filter(isChildProcessRecord);
|
|
97
|
+
}
|
|
98
|
+
function isChildProcessRecord(value) {
|
|
99
|
+
if (!value || typeof value !== 'object')
|
|
100
|
+
return false;
|
|
101
|
+
const r = value;
|
|
102
|
+
return typeof r['pid'] === 'number' && typeof r['instance_id'] === 'string' && typeof r['exe'] === 'string';
|
|
103
|
+
}
|
|
104
|
+
async function writeJournal(path, records) {
|
|
105
|
+
await mkdir(dirname(path), { recursive: true });
|
|
106
|
+
const tmp = `${path}.tmp`;
|
|
107
|
+
await writeFile(tmp, `${JSON.stringify({ version: 1, processes: records }, null, 2)}\n`);
|
|
108
|
+
await rename(tmp, path).catch(async (e) => {
|
|
109
|
+
await rm(tmp, { force: true }).catch(() => { });
|
|
110
|
+
throw e;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=process-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-journal.js","sourceRoot":"","sources":["../../src/lock/process-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the app asks about a model without loading it (PLAN.md §4, stage 3d).
|
|
3
|
+
*
|
|
4
|
+
* These are the extension's remaining "off-contract" methods — the ones that are not part of the
|
|
5
|
+
* provider interface but that the app calls anyway: is this file a usable GGUF, does this model
|
|
6
|
+
* have a projector, how large a context was it trained for, can it use speculative decoding. Every
|
|
7
|
+
* one of them is a question about files inside the data folder, which is why they move with the
|
|
8
|
+
* folder's owner rather than staying in a process that may no longer own it.
|
|
9
|
+
*
|
|
10
|
+
* All of them answer rather than throw. "This file is not a model" is the answer to a question the
|
|
11
|
+
* user asked by pointing at a file, not a failure of the core; the caller renders it.
|
|
12
|
+
*/
|
|
13
|
+
import type { DataLayout } from '../config/index.js';
|
|
14
|
+
import type { LocalProviderId } from '../contracts/index.js';
|
|
15
|
+
import type { ModelRegistry } from './registry.js';
|
|
16
|
+
export interface GgufValidation {
|
|
17
|
+
isValid: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
metadata?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
export interface ModelCapabilities {
|
|
22
|
+
modelId: string;
|
|
23
|
+
/** `{general.architecture}.context_length` — the ceiling for the context ladder. */
|
|
24
|
+
maxCtxTrain?: number;
|
|
25
|
+
/** A projector file exists, so this model can be given images. */
|
|
26
|
+
mmprojExists: boolean;
|
|
27
|
+
isEmbedding: boolean;
|
|
28
|
+
vision: boolean;
|
|
29
|
+
audio: boolean;
|
|
30
|
+
/** Speculative decoding this model id is known to support. */
|
|
31
|
+
gemmaMtp: boolean;
|
|
32
|
+
dflash: boolean;
|
|
33
|
+
dflashDrafts: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface CapabilitiesDeps {
|
|
36
|
+
layout: DataLayout;
|
|
37
|
+
registry: (provider: LocalProviderId) => ModelRegistry;
|
|
38
|
+
/** Test seam; production reads the file. */
|
|
39
|
+
readMetadata?: (path: string) => Promise<Record<string, string>>;
|
|
40
|
+
exists?: (path: string) => Promise<boolean>;
|
|
41
|
+
}
|
|
42
|
+
export declare class ModelCapabilityService {
|
|
43
|
+
private readonly deps;
|
|
44
|
+
constructor(deps: CapabilitiesDeps);
|
|
45
|
+
/**
|
|
46
|
+
* Whether a file can be imported as a text-generation model.
|
|
47
|
+
*
|
|
48
|
+
* The one rejection that matters is a CLIP architecture: those files are projectors, they parse
|
|
49
|
+
* as perfectly good GGUF, and importing one as a model produces a session that answers every
|
|
50
|
+
* prompt with nothing. The app has always named this case specifically, so the core does too.
|
|
51
|
+
*/
|
|
52
|
+
validateGguf(filePath: string): Promise<GgufValidation>;
|
|
53
|
+
/**
|
|
54
|
+
* Everything the app wants to know about an installed model.
|
|
55
|
+
*
|
|
56
|
+
* Answered from `model.yml` and the GGUF header together: the yml says where the files are and
|
|
57
|
+
* may name a projector explicitly, and the header says what the model is. A model whose files
|
|
58
|
+
* cannot be read still gets an answer — every capability false — because the caller is deciding
|
|
59
|
+
* what to show in a list, not whether to load it.
|
|
60
|
+
*/
|
|
61
|
+
capabilities(provider: LocalProviderId, modelId: string): Promise<ModelCapabilities>;
|
|
62
|
+
/**
|
|
63
|
+
* A projector for this model.
|
|
64
|
+
*
|
|
65
|
+
* `model.yml` may name one; when it does not, the conventional `mmproj.gguf` beside the model is
|
|
66
|
+
* still a projector — the app has always looked for both, and a model imported before the yml
|
|
67
|
+
* carried the field would otherwise lose its vision.
|
|
68
|
+
*/
|
|
69
|
+
mmprojExists(provider: LocalProviderId, modelId: string, declared?: string): Promise<boolean>;
|
|
70
|
+
/** Where this model's projector is, if it has one. */
|
|
71
|
+
private projectorPath;
|
|
72
|
+
private readMetadata;
|
|
73
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the app asks about a model without loading it (PLAN.md §4, stage 3d).
|
|
3
|
+
*
|
|
4
|
+
* These are the extension's remaining "off-contract" methods — the ones that are not part of the
|
|
5
|
+
* provider interface but that the app calls anyway: is this file a usable GGUF, does this model
|
|
6
|
+
* have a projector, how large a context was it trained for, can it use speculative decoding. Every
|
|
7
|
+
* one of them is a question about files inside the data folder, which is why they move with the
|
|
8
|
+
* folder's owner rather than staying in a process that may no longer own it.
|
|
9
|
+
*
|
|
10
|
+
* All of them answer rather than throw. "This file is not a model" is the answer to a question the
|
|
11
|
+
* user asked by pointing at a file, not a failure of the core; the caller renders it.
|
|
12
|
+
*/
|
|
13
|
+
import { stat } from 'node:fs/promises';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { checkDflashSupport, checkGemmaMtpSupport, listDflashDrafts } from '../speculative/index.js';
|
|
16
|
+
import { classifyProjector, ggufContextLength, isEmbeddingGguf } from './gguf/index.js';
|
|
17
|
+
import { readGgufMetadataFromFile } from './gguf/read-file.js';
|
|
18
|
+
const defaultExists = (path) => stat(path).then(() => true, () => false);
|
|
19
|
+
export class ModelCapabilityService {
|
|
20
|
+
deps;
|
|
21
|
+
constructor(deps) {
|
|
22
|
+
this.deps = deps;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether a file can be imported as a text-generation model.
|
|
26
|
+
*
|
|
27
|
+
* The one rejection that matters is a CLIP architecture: those files are projectors, they parse
|
|
28
|
+
* as perfectly good GGUF, and importing one as a model produces a session that answers every
|
|
29
|
+
* prompt with nothing. The app has always named this case specifically, so the core does too.
|
|
30
|
+
*/
|
|
31
|
+
async validateGguf(filePath) {
|
|
32
|
+
let metadata;
|
|
33
|
+
try {
|
|
34
|
+
metadata = await this.readMetadata(filePath);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
return { isValid: false, error: e.message };
|
|
38
|
+
}
|
|
39
|
+
const architecture = metadata['general.architecture'];
|
|
40
|
+
if (architecture === 'clip') {
|
|
41
|
+
return {
|
|
42
|
+
isValid: false,
|
|
43
|
+
error: 'This model has CLIP architecture and cannot be imported as a text generation model. ' +
|
|
44
|
+
'CLIP models are designed for vision tasks and require different handling.',
|
|
45
|
+
metadata,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return { isValid: true, metadata };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Everything the app wants to know about an installed model.
|
|
52
|
+
*
|
|
53
|
+
* Answered from `model.yml` and the GGUF header together: the yml says where the files are and
|
|
54
|
+
* may name a projector explicitly, and the header says what the model is. A model whose files
|
|
55
|
+
* cannot be read still gets an answer — every capability false — because the caller is deciding
|
|
56
|
+
* what to show in a list, not whether to load it.
|
|
57
|
+
*/
|
|
58
|
+
async capabilities(provider, modelId) {
|
|
59
|
+
const base = {
|
|
60
|
+
modelId,
|
|
61
|
+
mmprojExists: false,
|
|
62
|
+
isEmbedding: false,
|
|
63
|
+
vision: false,
|
|
64
|
+
audio: false,
|
|
65
|
+
gemmaMtp: checkGemmaMtpSupport(modelId),
|
|
66
|
+
dflash: checkDflashSupport(modelId),
|
|
67
|
+
dflashDrafts: listDflashDrafts(modelId).map((draft) => draft.quant),
|
|
68
|
+
};
|
|
69
|
+
const registry = this.deps.registry(provider);
|
|
70
|
+
const yml = await registry.read(modelId).catch(() => undefined);
|
|
71
|
+
if (!yml)
|
|
72
|
+
return base;
|
|
73
|
+
const paths = registry.resolvePaths(yml);
|
|
74
|
+
const projectorPath = await this.projectorPath(provider, modelId, paths.mmprojPath);
|
|
75
|
+
base.mmprojExists = projectorPath !== undefined;
|
|
76
|
+
// What a model can be given comes from the *projector's* header, not the model's:
|
|
77
|
+
// `classifyProjector` answers "vision" for metadata with no clip keys at all, because a file
|
|
78
|
+
// that is a projector and says nothing else is a vision projector. Asked about a text model it
|
|
79
|
+
// would therefore claim every one of them takes images.
|
|
80
|
+
if (projectorPath) {
|
|
81
|
+
const projectorMeta = await this.readMetadata(projectorPath).catch(() => undefined);
|
|
82
|
+
if (projectorMeta) {
|
|
83
|
+
const projector = classifyProjector(projectorMeta);
|
|
84
|
+
base.vision = projector.vision;
|
|
85
|
+
base.audio = projector.audio;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const metadata = await this.readMetadata(paths.modelPath).catch(() => undefined);
|
|
89
|
+
if (!metadata)
|
|
90
|
+
return base;
|
|
91
|
+
const maxCtxTrain = ggufContextLength(metadata);
|
|
92
|
+
return {
|
|
93
|
+
...base,
|
|
94
|
+
...(maxCtxTrain !== undefined ? { maxCtxTrain } : {}),
|
|
95
|
+
isEmbedding: isEmbeddingGguf(metadata),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A projector for this model.
|
|
100
|
+
*
|
|
101
|
+
* `model.yml` may name one; when it does not, the conventional `mmproj.gguf` beside the model is
|
|
102
|
+
* still a projector — the app has always looked for both, and a model imported before the yml
|
|
103
|
+
* carried the field would otherwise lose its vision.
|
|
104
|
+
*/
|
|
105
|
+
async mmprojExists(provider, modelId, declared) {
|
|
106
|
+
return (await this.projectorPath(provider, modelId, declared)) !== undefined;
|
|
107
|
+
}
|
|
108
|
+
/** Where this model's projector is, if it has one. */
|
|
109
|
+
async projectorPath(provider, modelId, declared) {
|
|
110
|
+
const exists = this.deps.exists ?? defaultExists;
|
|
111
|
+
// An absolute path already: `resolvePaths` resolved it against the data folder.
|
|
112
|
+
if (declared && (await exists(declared)))
|
|
113
|
+
return declared;
|
|
114
|
+
const conventional = join(this.deps.layout.provider(provider).modelsDir, modelId, 'mmproj.gguf');
|
|
115
|
+
return (await exists(conventional)) ? conventional : undefined;
|
|
116
|
+
}
|
|
117
|
+
async readMetadata(path) {
|
|
118
|
+
if (this.deps.readMetadata)
|
|
119
|
+
return this.deps.readMetadata(path);
|
|
120
|
+
return (await readGgufMetadataFromFile(path)).metadata;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/models/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LocalProviderId, SessionInfo } from '../contracts/index.js';
|
|
2
|
+
export interface EmbeddingResponse {
|
|
3
|
+
model: string;
|
|
4
|
+
object: 'list';
|
|
5
|
+
usage: {
|
|
6
|
+
prompt_tokens: number;
|
|
7
|
+
total_tokens: number;
|
|
8
|
+
};
|
|
9
|
+
data: Array<{
|
|
10
|
+
embedding: number[];
|
|
11
|
+
index: number;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export interface EmbedDeps {
|
|
15
|
+
findSession: (provider: LocalProviderId, modelId: string) => SessionInfo | undefined;
|
|
16
|
+
load: (provider: LocalProviderId, modelId: string) => Promise<SessionInfo>;
|
|
17
|
+
unload: (provider: LocalProviderId, modelId: string) => Promise<unknown>;
|
|
18
|
+
fetch?: typeof fetch;
|
|
19
|
+
}
|
|
20
|
+
export declare class EmbedService {
|
|
21
|
+
private readonly deps;
|
|
22
|
+
constructor(deps: EmbedDeps);
|
|
23
|
+
embed(provider: LocalProviderId, modelId: string, input: string[], ubatchSize: number): Promise<EmbeddingResponse>;
|
|
24
|
+
private request;
|
|
25
|
+
}
|
|
26
|
+
/** Same 3-chars/token, 50% safety-margin packing the legacy extension uses. */
|
|
27
|
+
export declare function buildEmbedBatches(input: string[], ubatchSize: number): Array<{
|
|
28
|
+
batch: string[];
|
|
29
|
+
offset: number;
|
|
30
|
+
}>;
|