@mlx-node/server 0.0.9 → 0.0.12
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/chat-session-warm-reuse.d.ts +10 -12
- package/dist/chat-session-warm-reuse.d.ts.map +1 -1
- package/dist/chat-session-warm-reuse.js +10 -12
- package/dist/endpoints/messages.d.ts +2 -2
- package/dist/endpoints/messages.d.ts.map +1 -1
- package/dist/endpoints/messages.js +492 -349
- package/dist/endpoints/responses.d.ts +1 -1
- package/dist/endpoints/responses.d.ts.map +1 -1
- package/dist/endpoints/responses.js +1149 -1055
- package/dist/handler.d.ts.map +1 -1
- package/dist/handler.js +1 -1
- package/dist/health.d.ts +4 -6
- package/dist/health.d.ts.map +1 -1
- package/dist/host/discover.d.ts +1 -2
- package/dist/host/discover.d.ts.map +1 -1
- package/dist/host/discover.js +3 -6
- package/dist/host/index.d.ts +6 -1
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +3 -2
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -9
- package/dist/mappers/anthropic-request.d.ts.map +1 -1
- package/dist/mappers/anthropic-request.js +5 -1
- package/dist/mappers/request.d.ts +12 -2
- package/dist/mappers/request.d.ts.map +1 -1
- package/dist/mappers/request.js +26 -2
- package/dist/model-work-coordinator.d.ts +50 -0
- package/dist/model-work-coordinator.d.ts.map +1 -1
- package/dist/model-work-coordinator.js +161 -0
- package/dist/registry.d.ts +15 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +51 -0
- package/dist/server.d.ts +21 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +30 -6
- package/dist/session-registry.d.ts +266 -86
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +421 -107
- package/dist/streaming.d.ts +37 -2
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +122 -1
- package/dist/transport-visibility.d.ts +5 -4
- package/dist/transport-visibility.d.ts.map +1 -1
- package/dist/transport-visibility.js +5 -4
- package/dist/types-anthropic.d.ts +7 -0
- package/dist/types-anthropic.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/presets.d.ts +0 -82
- package/dist/presets.d.ts.map +0 -1
- package/dist/presets.js +0 -98
package/dist/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,gBAAgB,EAAE,CAAC;IACtC;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,cAAc,GACvB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,gBAAgB,EAAE,CAAC;IACtC;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,cAAc,GACvB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAiF9D"}
|
package/dist/handler.js
CHANGED
|
@@ -28,7 +28,7 @@ export function createHandler(registry, options) {
|
|
|
28
28
|
const responseRetentionSec = options?.responseRetentionSec;
|
|
29
29
|
const idleSweeper = options?.idleSweeper ?? null;
|
|
30
30
|
const resolveModel = options?.resolveModel;
|
|
31
|
-
const modelWorkCoordinator = options?.modelWorkCoordinator ?? (resolveModel ? new ModelWorkCoordinator() : undefined);
|
|
31
|
+
const modelWorkCoordinator = options?.modelWorkCoordinator ?? (resolveModel ? new ModelWorkCoordinator(registry.queueDepthLimit) : undefined);
|
|
32
32
|
const listModels = options?.listModels;
|
|
33
33
|
const health = options?.health ?? createHealthReporter({ registry, idleSweeper, modelWorkCoordinator: modelWorkCoordinator });
|
|
34
34
|
return async (req, res) => {
|
package/dist/health.d.ts
CHANGED
|
@@ -39,12 +39,10 @@ export type ServerHealthStatus = 'ok' | 'loading' | 'degraded' | 'error';
|
|
|
39
39
|
* dropped — a supervisor polling after the fact had no way to learn WHY the
|
|
40
40
|
* server had no resident model.
|
|
41
41
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* additionally gated on "no resident models" — a server that is answering
|
|
47
|
-
* requests is not in an error state regardless of what the last bracket did.
|
|
42
|
+
* Resident HTTP requests bypass the load writer and do not overwrite this
|
|
43
|
+
* record with a no-op. The `'error'` rung is nevertheless gated on "no
|
|
44
|
+
* resident models": a server that is answering requests is not in an error
|
|
45
|
+
* state regardless of what the last load bracket did.
|
|
48
46
|
*/
|
|
49
47
|
export interface ModelLoadRecord {
|
|
50
48
|
/** Caller-supplied label, normally the model name. `null` when unlabelled. */
|
package/dist/health.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzE
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,0FAA0F;AAC1F,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;IACtB,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oFAAoF;IACpF,cAAc,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAClC;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,2CAA2C;QAC3C,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,oEAAoE;QACpE,YAAY,EAAE,OAAO,CAAC;QACtB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,KAAK,EAAE;QACL,oEAAoE;QACpE,KAAK,EAAE,MAAM,CAAC;QACd,iEAAiE;QACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,kBAAkB,CAShF;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,mBAAmB,CAEzE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,aAAa,CAAC;IACxB,kFAAkF;IAClF,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnD,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,YAAY,CAiDjF"}
|
package/dist/host/discover.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** Discover locally-downloaded generative models under a given directory. */
|
|
2
|
-
import { type ModelType } from '@mlx-node/lm';
|
|
3
|
-
import { type LaunchPreset } from '../presets.js';
|
|
2
|
+
import { type LaunchPreset, type ModelType } from '@mlx-node/lm';
|
|
4
3
|
/** A locally-downloaded model paired with its sampling preset. */
|
|
5
4
|
export interface DiscoveredModel {
|
|
6
5
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/host/discover.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAM7E,OAAO,
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/host/discover.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAM7E,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAoC5E"}
|
package/dist/host/discover.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/** Discover locally-downloaded generative models under a given directory. */
|
|
2
2
|
import { readdir } from 'node:fs/promises';
|
|
3
3
|
import { basename, join } from 'node:path';
|
|
4
|
-
import { detectModelType } from '@mlx-node/lm';
|
|
5
|
-
import { LAUNCH_PRESETS } from '../presets.js';
|
|
6
|
-
// Non-generative detection results that cannot back a chat endpoint.
|
|
7
|
-
const NON_GENERATIVE = new Set(['harrier', 'qianfan-ocr', 'internvl_chat']);
|
|
4
|
+
import { detectModelType, NON_GENERATIVE_FAMILY_IDS, launchPresetFor, } from '@mlx-node/lm';
|
|
8
5
|
/**
|
|
9
6
|
* Scan `dir` for model subdirectories. Each subdirectory with a recognized
|
|
10
7
|
* `config.json` is returned with its inferred `ModelType` and `LaunchPreset`.
|
|
@@ -35,9 +32,9 @@ export async function discoverModels(dir) {
|
|
|
35
32
|
console.warn(`[mlx] skip ${full}: ${err.message}`);
|
|
36
33
|
continue;
|
|
37
34
|
}
|
|
38
|
-
if (
|
|
35
|
+
if (NON_GENERATIVE_FAMILY_IDS.has(modelType))
|
|
39
36
|
continue;
|
|
40
|
-
const preset =
|
|
37
|
+
const preset = launchPresetFor(modelType);
|
|
41
38
|
if (!preset) {
|
|
42
39
|
if (debug)
|
|
43
40
|
console.warn(`[mlx] skip ${full}: no LAUNCH_PRESETS entry for ${modelType}`);
|
package/dist/host/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { type DiscoveredModel } from './discover.js';
|
|
|
45
45
|
import { type EnginePolicy } from './env-policy.js';
|
|
46
46
|
import { type Logger } from './logger.js';
|
|
47
47
|
/** Families `mlx launch claude` has historically forced onto the paged path. */
|
|
48
|
-
export declare const DEFAULT_PAGED_MODEL_TYPES: readonly [
|
|
48
|
+
export declare const DEFAULT_PAGED_MODEL_TYPES: readonly ["qwen3_5", "qwen3_5_moe"];
|
|
49
49
|
/** Thrown when `modelsDir` holds nothing servable. Carries the dir for the caller's message. */
|
|
50
50
|
export declare class NoModelsDiscoveredError extends Error {
|
|
51
51
|
readonly modelsDir: string;
|
|
@@ -121,6 +121,11 @@ export interface InferenceHostOptions {
|
|
|
121
121
|
storePath?: string;
|
|
122
122
|
/** Disable response persistence entirely. See `ServerConfig.disableStore`. */
|
|
123
123
|
disableStore?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Per-model waiter cap forwarded to `createServer`. Default 16; pass
|
|
126
|
+
* `'unbounded'` for an explicitly uncapped embedded host.
|
|
127
|
+
*/
|
|
128
|
+
maxQueueDepthPerModel?: number | 'unbounded';
|
|
124
129
|
/**
|
|
125
130
|
* Remove temp roots left behind by hosts that were killed without running
|
|
126
131
|
* `close()`. Default `true`; a supervisor that runs several hosts under one
|
package/dist/host/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"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"}
|
package/dist/host/index.js
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
* independently guarded — one failing disposer must not strand the ones
|
|
38
38
|
* after it.
|
|
39
39
|
*/
|
|
40
|
-
import { loadModel as loadModelNative, PagedConfigOverrideManager } from '@mlx-node/lm';
|
|
40
|
+
import { loadModel as loadModelNative, PagedConfigOverrideManager, QWEN35_PAGED_MODEL_TYPES, } from '@mlx-node/lm';
|
|
41
41
|
import { createServer, resolveAuthToken } from '../server.js';
|
|
42
42
|
import { discoverModels } from './discover.js';
|
|
43
43
|
import { applyEnginePolicy } from './env-policy.js';
|
|
@@ -47,7 +47,7 @@ import { resolveModelsDir } from './paths.js';
|
|
|
47
47
|
import { makeSwapController } from './swap.js';
|
|
48
48
|
import { hostTempDirPrefix, sweepOrphanHostTempRoots } from './temp-root.js';
|
|
49
49
|
/** Families `mlx launch claude` has historically forced onto the paged path. */
|
|
50
|
-
export const DEFAULT_PAGED_MODEL_TYPES =
|
|
50
|
+
export const DEFAULT_PAGED_MODEL_TYPES = QWEN35_PAGED_MODEL_TYPES;
|
|
51
51
|
/** Thrown when `modelsDir` holds nothing servable. Carries the dir for the caller's message. */
|
|
52
52
|
export class NoModelsDiscoveredError extends Error {
|
|
53
53
|
modelsDir;
|
|
@@ -166,6 +166,7 @@ export async function createInferenceHost(opts = {}) {
|
|
|
166
166
|
...(opts.authToken !== undefined ? { authToken: opts.authToken } : {}),
|
|
167
167
|
...(opts.storePath !== undefined ? { storePath: opts.storePath } : {}),
|
|
168
168
|
...(opts.disableStore !== undefined ? { disableStore: opts.disableStore } : {}),
|
|
169
|
+
...(opts.maxQueueDepthPerModel !== undefined ? { maxQueueDepthPerModel: opts.maxQueueDepthPerModel } : {}),
|
|
169
170
|
};
|
|
170
171
|
const server = await createServer(serverConfig);
|
|
171
172
|
// Wrap the loader so managed families get `use_block_paged_cache: true`
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Exposes loaded models via `POST /v1/responses`, `POST /v1/messages`, and
|
|
5
5
|
* `GET /v1/models`, in both streaming (SSE) and non-streaming modes.
|
|
6
6
|
*/
|
|
7
|
-
export { createServer } from './server.js';
|
|
7
|
+
export { createServer, DEFAULT_MAX_QUEUE_DEPTH_PER_MODEL } from './server.js';
|
|
8
8
|
export type { CloseOptions, CloseResult, ServerConfig, ServerInstance } from './server.js';
|
|
9
9
|
/**
|
|
10
10
|
* Readiness reporting. `deriveHealthStatus` is pure — a supervisor can reuse
|
|
@@ -27,10 +27,8 @@ export type { HandlerOptions } from './handler.js';
|
|
|
27
27
|
export { ModelRegistry } from './registry.js';
|
|
28
28
|
export type { ServableModel, ModelEntry, ModelRegistryOptions, RegisterOptions } from './registry.js';
|
|
29
29
|
export { QueueFullError, SessionRegistry } from './session-registry.js';
|
|
30
|
-
export type { SessionLookupResult, SessionRegistryOptions } from './session-registry.js';
|
|
30
|
+
export type { PreDispatchAdmission, SessionLookupResult, SessionRegistryOptions } from './session-registry.js';
|
|
31
31
|
export { resolveServerTuningForUsage } from './timing.js';
|
|
32
|
-
export { QWEN_SAMPLING_DEFAULTS, GEMMA4_SAMPLING_DEFAULTS, LFM2_SAMPLING_DEFAULTS, LAUNCH_PRESETS } from './presets.js';
|
|
33
|
-
export type { LaunchPreset } from './presets.js';
|
|
34
32
|
export type { PublicModelEntry } from './handler.js';
|
|
35
33
|
export type { ResponsesAPIRequest, ResponseObject, ResponseUsage, ResponseError, InputItem, InputMessage, InputFunctionCall, InputFunctionCallOutput, OutputItem, MessageOutputItem, ReasoningOutputItem, FunctionCallOutputItem, OutputTextPart, SummaryTextPart, ResponsesToolDefinition, ContentPart, InputTextPart, StreamEvent, } from './types.js';
|
|
36
34
|
export type { AnthropicCountTokensRequest, AnthropicCountTokensResponse, AnthropicMessagesRequest, AnthropicMessagesResponse, AnthropicMessage, AnthropicContentBlock, AnthropicTextContentBlock, AnthropicImageContentBlock, AnthropicToolResultContentBlock, AnthropicToolUseContentBlock, AnthropicThinkingContentBlock, AnthropicToolDefinition, AnthropicToolChoice, AnthropicResponseContent, AnthropicResponseTextBlock, AnthropicResponseThinkingBlock, AnthropicResponseToolUseBlock, AnthropicUsage, AnthropicStreamEvent, AnthropicMessageStartEvent, AnthropicContentBlockStartEvent, AnthropicContentBlockDeltaEvent, AnthropicContentBlockStopEvent, AnthropicMessageDeltaEvent, AnthropicMessageStopEvent, AnthropicDelta, AnthropicTextDelta, AnthropicThinkingDelta, AnthropicInputJsonDelta, SystemBlock, } from './types-anthropic.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3F;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACxF,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEzE;;;GAGG;AACH,OAAO,EAAE,eAAe,IAAI,iBAAiB,EAAE,mBAAmB,IAAI,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACjH,OAAO,EACL,iBAAiB,IAAI,mBAAmB,EACxC,sBAAsB,IAAI,wBAAwB,EAClD,2BAA2B,IAAI,6BAA6B,GAC7D,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEtG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAS1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,aAAa,EACb,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAC1B,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,8BAA8B,EAC9B,6BAA6B,EAC7B,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Exposes loaded models via `POST /v1/responses`, `POST /v1/messages`, and
|
|
5
5
|
* `GET /v1/models`, in both streaming (SSE) and non-streaming modes.
|
|
6
6
|
*/
|
|
7
|
-
export { createServer } from './server.js';
|
|
7
|
+
export { createServer, DEFAULT_MAX_QUEUE_DEPTH_PER_MODEL } from './server.js';
|
|
8
8
|
/**
|
|
9
9
|
* Readiness reporting. `deriveHealthStatus` is pure — a supervisor can reuse
|
|
10
10
|
* it to classify a `ServerHealth` body fetched over HTTP.
|
|
@@ -21,12 +21,4 @@ export { createHandler } from './handler.js';
|
|
|
21
21
|
export { ModelRegistry } from './registry.js';
|
|
22
22
|
export { QueueFullError, SessionRegistry } from './session-registry.js';
|
|
23
23
|
export { resolveServerTuningForUsage } from './timing.js';
|
|
24
|
-
// NOTE: `__resetPromptCacheKeyNonceForTests` is intentionally NOT
|
|
25
|
-
// re-exported here. It is a test-only helper that nukes the module-
|
|
26
|
-
// scoped HMAC nonce (and the once-per-process single-tenant warning
|
|
27
|
-
// flag); exposing it on the public surface would let downstream
|
|
28
|
-
// consumers invalidate every live tier-2 entry with one call. Tests
|
|
29
|
-
// import it from the deep path
|
|
30
|
-
// `packages/server/src/session-registry.js` instead.
|
|
31
|
-
export { QWEN_SAMPLING_DEFAULTS, GEMMA4_SAMPLING_DEFAULTS, LFM2_SAMPLING_DEFAULTS, LAUNCH_PRESETS } from './presets.js';
|
|
32
24
|
export { writeSSEEvent, beginSSE, endSSE, activeSSEStreamCount } from './streaming.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-request.d.ts","sourceRoot":"","sources":["../../src/mappers/anthropic-request.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAE9E,OAAO,KAAK,EAEV,2BAA2B,EAE3B,wBAAwB,EAIzB,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB;;;;;OAKG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,IAAI,CAoBvG;AAiDD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,wBAAwB,GAAG,2BAA2B,GAC1D,sBAAsB,
|
|
1
|
+
{"version":3,"file":"anthropic-request.d.ts","sourceRoot":"","sources":["../../src/mappers/anthropic-request.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAE9E,OAAO,KAAK,EAEV,2BAA2B,EAE3B,wBAAwB,EAIzB,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB;;;;;OAKG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,IAAI,CAoBvG;AAiDD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,wBAAwB,GAAG,2BAA2B,GAC1D,sBAAsB,CAkWxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Anthropic Messages API request → internal `ChatMessage[]` + `ChatConfig`. */
|
|
2
2
|
import { anthropicToolUseIdToInternal } from './anthropic-response.js';
|
|
3
|
-
import { applyExtraBodyMtpOverrides } from './request.js';
|
|
3
|
+
import { applyExtraBodyMtpOverrides, validateCacheSalt } from './request.js';
|
|
4
4
|
/**
|
|
5
5
|
* Anthropic billing/attribution header prefix. Claude Code injects a leading
|
|
6
6
|
* system block of the shape `"x-anthropic-billing-header: cc_version=...; cch=<token>;"`
|
|
@@ -390,6 +390,10 @@ export function mapAnthropicRequest(req) {
|
|
|
390
390
|
const config = {
|
|
391
391
|
reportPerformance: true,
|
|
392
392
|
};
|
|
393
|
+
if (req.cache_salt != null) {
|
|
394
|
+
validateCacheSalt(req.cache_salt);
|
|
395
|
+
config.cacheSalt = req.cache_salt;
|
|
396
|
+
}
|
|
393
397
|
if (req.max_tokens != null) {
|
|
394
398
|
config.maxNewTokens = req.max_tokens;
|
|
395
399
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** OpenAI Responses API request → internal `ChatMessage[]` + `ChatConfig`. */
|
|
2
2
|
import type { ChatConfig, ChatMessage } from '@mlx-node/core';
|
|
3
3
|
import type { ResponsesAPIRequest } from '../types.js';
|
|
4
|
+
export declare const MAX_CACHE_SALT_BYTES = 256;
|
|
5
|
+
export declare function validateCacheSalt(cacheSalt: unknown): asserts cacheSalt is string;
|
|
4
6
|
export interface MappedRequest {
|
|
5
7
|
messages: ChatMessage[];
|
|
6
8
|
config: ChatConfig;
|
|
@@ -13,8 +15,16 @@ export interface MappedRequest {
|
|
|
13
15
|
* * `generation_mode: "mtp"` → `enableMtp = true`
|
|
14
16
|
* * `generation_mode: "ar"` → `enableMtp = false`
|
|
15
17
|
* * any other / absent value → `enableMtp` untouched, so the
|
|
16
|
-
* downstream `ChatSession.mergeConfig` auto-default
|
|
17
|
-
*
|
|
18
|
+
* downstream `ChatSession.mergeConfig` auto-default applies.
|
|
19
|
+
* That default is two-part, not just "has a head": the model
|
|
20
|
+
* must report `hasMtpWeights()` AND opt in through
|
|
21
|
+
* `ChatSession#mtpAutoDefaultAllowed`, which prefers the native
|
|
22
|
+
* `mtpAutoEnabled()` getter when present and otherwise falls
|
|
23
|
+
* back to the `MTP_AUTO_DEFAULT_SUPPRESSED_MODELS` class-name
|
|
24
|
+
* list (both in `packages/lm/src/chat-session.ts`). NemotronH
|
|
25
|
+
* is currently suppressed — its head is a measured throughput
|
|
26
|
+
* loss — so `generation_mode: "mtp"` (or an explicit
|
|
27
|
+
* `enableMtp: true`) is the only way to speculate on it here.
|
|
18
28
|
*
|
|
19
29
|
* * `mtp_depth: <positive int ≤ 64>` → `mtpDepth = value`
|
|
20
30
|
* * non-integer, out-of-range, or absent → `mtpDepth` untouched.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/mappers/request.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAE9E,OAAO,KAAK,EAAe,mBAAmB,EAA2B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/mappers/request.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAE9E,OAAO,KAAK,EAAe,mBAAmB,EAA2B,MAAM,aAAa,CAAC;AAE7F,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAUjF;AA2GD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,SAAS,GACpF,IAAI,CAcN;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,GAAG,aAAa,CAuIjG;AAwBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAgB5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,WAAW,EAAE,CAyE9G"}
|
package/dist/mappers/request.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
/** OpenAI Responses API request → internal `ChatMessage[]` + `ChatConfig`. */
|
|
2
|
+
export const MAX_CACHE_SALT_BYTES = 256;
|
|
3
|
+
export function validateCacheSalt(cacheSalt) {
|
|
4
|
+
if (typeof cacheSalt !== 'string') {
|
|
5
|
+
throw new Error('cache_salt must be a string');
|
|
6
|
+
}
|
|
7
|
+
if (cacheSalt.length === 0) {
|
|
8
|
+
throw new Error('cache_salt must not be empty');
|
|
9
|
+
}
|
|
10
|
+
if (Buffer.byteLength(cacheSalt, 'utf8') > MAX_CACHE_SALT_BYTES) {
|
|
11
|
+
throw new Error(`cache_salt must be at most ${MAX_CACHE_SALT_BYTES} UTF-8 bytes`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
15
|
* Resolve a message's `content` array into text + optional image bytes.
|
|
4
16
|
*
|
|
@@ -103,8 +115,16 @@ function mapTool(tool) {
|
|
|
103
115
|
* * `generation_mode: "mtp"` → `enableMtp = true`
|
|
104
116
|
* * `generation_mode: "ar"` → `enableMtp = false`
|
|
105
117
|
* * any other / absent value → `enableMtp` untouched, so the
|
|
106
|
-
* downstream `ChatSession.mergeConfig` auto-default
|
|
107
|
-
*
|
|
118
|
+
* downstream `ChatSession.mergeConfig` auto-default applies.
|
|
119
|
+
* That default is two-part, not just "has a head": the model
|
|
120
|
+
* must report `hasMtpWeights()` AND opt in through
|
|
121
|
+
* `ChatSession#mtpAutoDefaultAllowed`, which prefers the native
|
|
122
|
+
* `mtpAutoEnabled()` getter when present and otherwise falls
|
|
123
|
+
* back to the `MTP_AUTO_DEFAULT_SUPPRESSED_MODELS` class-name
|
|
124
|
+
* list (both in `packages/lm/src/chat-session.ts`). NemotronH
|
|
125
|
+
* is currently suppressed — its head is a measured throughput
|
|
126
|
+
* loss — so `generation_mode: "mtp"` (or an explicit
|
|
127
|
+
* `enableMtp: true`) is the only way to speculate on it here.
|
|
108
128
|
*
|
|
109
129
|
* * `mtp_depth: <positive int ≤ 64>` → `mtpDepth = value`
|
|
110
130
|
* * non-integer, out-of-range, or absent → `mtpDepth` untouched.
|
|
@@ -231,6 +251,10 @@ export function mapRequest(req, priorMessages) {
|
|
|
231
251
|
const config = {
|
|
232
252
|
reportPerformance: true,
|
|
233
253
|
};
|
|
254
|
+
if (req.cache_salt != null) {
|
|
255
|
+
validateCacheSalt(req.cache_salt);
|
|
256
|
+
config.cacheSalt = req.cache_salt;
|
|
257
|
+
}
|
|
234
258
|
if (req.max_output_tokens != null) {
|
|
235
259
|
config.maxNewTokens = req.max_output_tokens;
|
|
236
260
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ModelLoadRecord } from './health.js';
|
|
2
|
+
import type { PreDispatchAdmission, SessionRegistry } from './session-registry.js';
|
|
2
3
|
/**
|
|
3
4
|
* Result of a `withModelLoad` call that surfaces who actually drove the load
|
|
4
5
|
* vs. who merely parked behind one that was already in flight. Callers use
|
|
@@ -31,6 +32,24 @@ export interface ModelLoadOutcome<T> {
|
|
|
31
32
|
waitMs: number;
|
|
32
33
|
ownMs: number;
|
|
33
34
|
}
|
|
35
|
+
/** A bounded request admission transferred into the resident FIFO budget. */
|
|
36
|
+
export interface ModelLoadAdmission {
|
|
37
|
+
/**
|
|
38
|
+
* Atomically move this request from the cold-load budget into the
|
|
39
|
+
* resident model's ordinary pre-dispatch budget. Idempotent for the same
|
|
40
|
+
* registry; transferring after a hot-swap releases the old reservation
|
|
41
|
+
* before charging the new binding.
|
|
42
|
+
*/
|
|
43
|
+
transferToResident(registry: SessionRegistry): PreDispatchAdmission;
|
|
44
|
+
/** Idempotently release this request's current cold or resident unit. */
|
|
45
|
+
release(): void;
|
|
46
|
+
}
|
|
47
|
+
/** Raised synchronously when unresolved model-load traffic is over capacity. */
|
|
48
|
+
export declare class ModelLoadQueueFullError extends Error {
|
|
49
|
+
readonly admissionFootprint: number;
|
|
50
|
+
readonly limit: number;
|
|
51
|
+
constructor(admissionFootprint: number, limit: number);
|
|
52
|
+
}
|
|
34
53
|
/**
|
|
35
54
|
* Process-local gate for native MLX work.
|
|
36
55
|
*
|
|
@@ -46,6 +65,16 @@ export declare class ModelWorkCoordinator {
|
|
|
46
65
|
private queuedWriters;
|
|
47
66
|
private readonly readerWaiters;
|
|
48
67
|
private readonly writerWaiters;
|
|
68
|
+
private requestLoadAdmissions;
|
|
69
|
+
/** Outstanding permits grouped by the requested model name. */
|
|
70
|
+
private readonly requestLoadAdmissionsByModel;
|
|
71
|
+
/**
|
|
72
|
+
* Resident bindings published synchronously by `ModelRegistry.register`.
|
|
73
|
+
* Publishing transfers every already-admitted cold request before another
|
|
74
|
+
* request can spend the resident budget independently.
|
|
75
|
+
*/
|
|
76
|
+
private readonly residentRegistriesByModel;
|
|
77
|
+
private readonly maxRequestLoadQueueDepth;
|
|
49
78
|
/**
|
|
50
79
|
* Most recent settled load bracket. Retained here because the coordinator
|
|
51
80
|
* is the ONE place that brackets every load: a `resolveModel` failure in
|
|
@@ -55,6 +84,27 @@ export declare class ModelWorkCoordinator {
|
|
|
55
84
|
* an earlier failure" caveat.
|
|
56
85
|
*/
|
|
57
86
|
private lastLoadRecord;
|
|
87
|
+
constructor(maxRequestLoadQueueDepth?: number);
|
|
88
|
+
/**
|
|
89
|
+
* Bound requests that arrive before a model has a resident
|
|
90
|
+
* `SessionRegistry`. The capacity mirrors the resident FIFO: `limit`
|
|
91
|
+
* waiters plus one owner/runner. Callers retain the permit through every
|
|
92
|
+
* pre-lock await; registration synchronously transfers it into the resident
|
|
93
|
+
* `SessionRegistry` budget before any later arrival can spend that capacity.
|
|
94
|
+
*/
|
|
95
|
+
beginRequestLoadAdmission(modelId: string): ModelLoadAdmission;
|
|
96
|
+
/**
|
|
97
|
+
* Publish a requested model name's resident admission lane. Called
|
|
98
|
+
* synchronously from `ModelRegistry.register`, so every outstanding cold
|
|
99
|
+
* permit moves into the registry before a later arrival can be admitted
|
|
100
|
+
* against an apparently empty resident budget.
|
|
101
|
+
*/
|
|
102
|
+
bindRequestLoadAdmissions(modelId: string, registry: SessionRegistry): void;
|
|
103
|
+
/** Forget a name only when it still points at the supplied binding. */
|
|
104
|
+
unbindRequestLoadAdmissions(modelId: string, registry: SessionRegistry): void;
|
|
105
|
+
private transferAdmission;
|
|
106
|
+
/** Read-only unresolved/pre-FIFO request footprint for diagnostics/tests. */
|
|
107
|
+
get requestLoadAdmissionCount(): number;
|
|
58
108
|
/** Read-only: `true` while a load holds the exclusive writer slot. */
|
|
59
109
|
get writerActive(): boolean;
|
|
60
110
|
/** Read-only: loads parked in `acquireWrite()` waiting for the slot. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-work-coordinator.d.ts","sourceRoot":"","sources":["../src/model-work-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"model-work-coordinator.d.ts","sourceRoot":"","sources":["../src/model-work-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,17 @@ function describeLoadFailure(error) {
|
|
|
20
20
|
return 'unknown error';
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
/** Raised synchronously when unresolved model-load traffic is over capacity. */
|
|
24
|
+
export class ModelLoadQueueFullError extends Error {
|
|
25
|
+
admissionFootprint;
|
|
26
|
+
limit;
|
|
27
|
+
constructor(admissionFootprint, limit) {
|
|
28
|
+
super(`Model load queue full: admission footprint ${admissionFootprint} (waiter limit ${limit})`);
|
|
29
|
+
this.name = 'ModelLoadQueueFullError';
|
|
30
|
+
this.admissionFootprint = admissionFootprint;
|
|
31
|
+
this.limit = limit;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
23
34
|
/**
|
|
24
35
|
* Process-local gate for native MLX work.
|
|
25
36
|
*
|
|
@@ -35,6 +46,16 @@ export class ModelWorkCoordinator {
|
|
|
35
46
|
queuedWriters = 0;
|
|
36
47
|
readerWaiters = [];
|
|
37
48
|
writerWaiters = [];
|
|
49
|
+
requestLoadAdmissions = 0;
|
|
50
|
+
/** Outstanding permits grouped by the requested model name. */
|
|
51
|
+
requestLoadAdmissionsByModel = new Map();
|
|
52
|
+
/**
|
|
53
|
+
* Resident bindings published synchronously by `ModelRegistry.register`.
|
|
54
|
+
* Publishing transfers every already-admitted cold request before another
|
|
55
|
+
* request can spend the resident budget independently.
|
|
56
|
+
*/
|
|
57
|
+
residentRegistriesByModel = new Map();
|
|
58
|
+
maxRequestLoadQueueDepth;
|
|
38
59
|
/**
|
|
39
60
|
* Most recent settled load bracket. Retained here because the coordinator
|
|
40
61
|
* is the ONE place that brackets every load: a `resolveModel` failure in
|
|
@@ -44,6 +65,146 @@ export class ModelWorkCoordinator {
|
|
|
44
65
|
* an earlier failure" caveat.
|
|
45
66
|
*/
|
|
46
67
|
lastLoadRecord = null;
|
|
68
|
+
constructor(maxRequestLoadQueueDepth) {
|
|
69
|
+
this.maxRequestLoadQueueDepth = maxRequestLoadQueueDepth;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Bound requests that arrive before a model has a resident
|
|
73
|
+
* `SessionRegistry`. The capacity mirrors the resident FIFO: `limit`
|
|
74
|
+
* waiters plus one owner/runner. Callers retain the permit through every
|
|
75
|
+
* pre-lock await; registration synchronously transfers it into the resident
|
|
76
|
+
* `SessionRegistry` budget before any later arrival can spend that capacity.
|
|
77
|
+
*/
|
|
78
|
+
beginRequestLoadAdmission(modelId) {
|
|
79
|
+
const limit = this.maxRequestLoadQueueDepth;
|
|
80
|
+
const admissions = this.requestLoadAdmissionsByModel.get(modelId) ?? new Set();
|
|
81
|
+
let coldFootprint = 0;
|
|
82
|
+
for (const admission of admissions) {
|
|
83
|
+
if (!admission.released && admission.coldCounted)
|
|
84
|
+
coldFootprint += 1;
|
|
85
|
+
}
|
|
86
|
+
if (limit !== undefined && coldFootprint >= limit + 1) {
|
|
87
|
+
throw new ModelLoadQueueFullError(coldFootprint, limit);
|
|
88
|
+
}
|
|
89
|
+
if (!this.requestLoadAdmissionsByModel.has(modelId)) {
|
|
90
|
+
this.requestLoadAdmissionsByModel.set(modelId, admissions);
|
|
91
|
+
}
|
|
92
|
+
const state = {
|
|
93
|
+
released: false,
|
|
94
|
+
coldCounted: true,
|
|
95
|
+
};
|
|
96
|
+
admissions.add(state);
|
|
97
|
+
this.requestLoadAdmissions += 1;
|
|
98
|
+
const admission = {
|
|
99
|
+
transferToResident: (registry) => this.transferAdmission(state, registry),
|
|
100
|
+
release: () => {
|
|
101
|
+
if (state.released)
|
|
102
|
+
return;
|
|
103
|
+
state.released = true;
|
|
104
|
+
state.residentAdmission?.release();
|
|
105
|
+
state.residentAdmission = undefined;
|
|
106
|
+
state.residentRegistry = undefined;
|
|
107
|
+
if (state.coldCounted) {
|
|
108
|
+
state.coldCounted = false;
|
|
109
|
+
this.requestLoadAdmissions -= 1;
|
|
110
|
+
if (this.requestLoadAdmissions < 0)
|
|
111
|
+
this.requestLoadAdmissions = 0;
|
|
112
|
+
}
|
|
113
|
+
const active = this.requestLoadAdmissionsByModel.get(modelId);
|
|
114
|
+
active?.delete(state);
|
|
115
|
+
if (active?.size === 0)
|
|
116
|
+
this.requestLoadAdmissionsByModel.delete(modelId);
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
const resident = this.residentRegistriesByModel.get(modelId);
|
|
120
|
+
if (resident) {
|
|
121
|
+
try {
|
|
122
|
+
this.transferAdmission(state, resident);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Preserve the failure on `state`; the handler observes it from its
|
|
126
|
+
// explicit transfer after resolving the binding and returns 429.
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return admission;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Publish a requested model name's resident admission lane. Called
|
|
133
|
+
* synchronously from `ModelRegistry.register`, so every outstanding cold
|
|
134
|
+
* permit moves into the registry before a later arrival can be admitted
|
|
135
|
+
* against an apparently empty resident budget.
|
|
136
|
+
*/
|
|
137
|
+
bindRequestLoadAdmissions(modelId, registry) {
|
|
138
|
+
this.residentRegistriesByModel.set(modelId, registry);
|
|
139
|
+
const admissions = this.requestLoadAdmissionsByModel.get(modelId);
|
|
140
|
+
if (!admissions)
|
|
141
|
+
return;
|
|
142
|
+
for (const admission of admissions) {
|
|
143
|
+
if (admission.released)
|
|
144
|
+
continue;
|
|
145
|
+
try {
|
|
146
|
+
this.transferAdmission(admission, registry);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// A cold request that cannot fit after an alias/hot-swap transition is
|
|
150
|
+
// marked fail-closed. Its handler will surface the stored QueueFullError
|
|
151
|
+
// rather than running outside either budget.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Forget a name only when it still points at the supplied binding. */
|
|
156
|
+
unbindRequestLoadAdmissions(modelId, registry) {
|
|
157
|
+
if (this.residentRegistriesByModel.get(modelId) === registry) {
|
|
158
|
+
this.residentRegistriesByModel.delete(modelId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
transferAdmission(state, registry) {
|
|
162
|
+
if (state.released) {
|
|
163
|
+
throw new Error('Model load admission has already been released');
|
|
164
|
+
}
|
|
165
|
+
if (state.residentRegistry === registry && state.transferError !== undefined) {
|
|
166
|
+
throw state.transferError;
|
|
167
|
+
}
|
|
168
|
+
if (state.residentRegistry === registry && state.residentAdmission) {
|
|
169
|
+
return state.residentAdmission;
|
|
170
|
+
}
|
|
171
|
+
if (state.residentAdmission) {
|
|
172
|
+
state.residentAdmission.release();
|
|
173
|
+
state.residentAdmission = undefined;
|
|
174
|
+
state.residentRegistry = undefined;
|
|
175
|
+
}
|
|
176
|
+
state.transferError = undefined;
|
|
177
|
+
try {
|
|
178
|
+
const residentAdmission = registry.beginPreDispatchAdmission();
|
|
179
|
+
state.residentRegistry = registry;
|
|
180
|
+
state.residentAdmission = residentAdmission;
|
|
181
|
+
if (state.coldCounted) {
|
|
182
|
+
state.coldCounted = false;
|
|
183
|
+
this.requestLoadAdmissions -= 1;
|
|
184
|
+
if (this.requestLoadAdmissions < 0)
|
|
185
|
+
this.requestLoadAdmissions = 0;
|
|
186
|
+
}
|
|
187
|
+
return residentAdmission;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
// This permit is now a rejected resident transition, not an invisible
|
|
191
|
+
// cold unit. Remove its cold charge; `transferToResident` rethrows the
|
|
192
|
+
// exact resident error when the owning request resumes.
|
|
193
|
+
if (state.coldCounted) {
|
|
194
|
+
state.coldCounted = false;
|
|
195
|
+
this.requestLoadAdmissions -= 1;
|
|
196
|
+
if (this.requestLoadAdmissions < 0)
|
|
197
|
+
this.requestLoadAdmissions = 0;
|
|
198
|
+
}
|
|
199
|
+
state.transferError = error;
|
|
200
|
+
state.residentRegistry = registry;
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** Read-only unresolved/pre-FIFO request footprint for diagnostics/tests. */
|
|
205
|
+
get requestLoadAdmissionCount() {
|
|
206
|
+
return this.requestLoadAdmissions;
|
|
207
|
+
}
|
|
47
208
|
/** Read-only: `true` while a load holds the exclusive writer slot. */
|
|
48
209
|
get writerActive() {
|
|
49
210
|
return this.writerHeld;
|
package/dist/registry.d.ts
CHANGED
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
import type { ChatConfig } from '@mlx-node/core';
|
|
40
40
|
import type { SessionCapableModel } from '@mlx-node/lm';
|
|
41
41
|
import { SessionRegistry } from './session-registry.js';
|
|
42
|
+
interface ModelLoadAdmissionCoordinator {
|
|
43
|
+
bindRequestLoadAdmissions(modelId: string, registry: SessionRegistry): void;
|
|
44
|
+
unbindRequestLoadAdmissions(modelId: string, registry: SessionRegistry): void;
|
|
45
|
+
}
|
|
42
46
|
/** Minimal contract for a model that can be served via chat sessions. */
|
|
43
47
|
export type ServableModel = SessionCapableModel;
|
|
44
48
|
/** Model entry stored in the registry. */
|
|
@@ -145,7 +149,17 @@ export declare class ModelRegistry {
|
|
|
145
149
|
* hard-timeouts have fired.
|
|
146
150
|
*/
|
|
147
151
|
private readonly retiredInstanceIds;
|
|
152
|
+
private modelLoadAdmissionCoordinator;
|
|
148
153
|
constructor(opts?: ModelRegistryOptions);
|
|
154
|
+
/** Configured per-model waiter cap, or `undefined` when unbounded. */
|
|
155
|
+
get queueDepthLimit(): number | undefined;
|
|
156
|
+
/**
|
|
157
|
+
* Connect cold-load admission to name registration. The coordinator is
|
|
158
|
+
* attached by the HTTP handler before dispatch; existing names are
|
|
159
|
+
* published immediately and future `register`/`unregister` calls keep the
|
|
160
|
+
* mapping current.
|
|
161
|
+
*/
|
|
162
|
+
setModelLoadAdmissionCoordinator(coordinator: ModelLoadAdmissionCoordinator | undefined): void;
|
|
149
163
|
/**
|
|
150
164
|
* Register a model under a given name.
|
|
151
165
|
*
|
|
@@ -390,4 +404,5 @@ export declare class ModelRegistry {
|
|
|
390
404
|
*/
|
|
391
405
|
hasStreamSupport(model: ServableModel): boolean;
|
|
392
406
|
}
|
|
407
|
+
export {};
|
|
393
408
|
//# sourceMappingURL=registry.d.ts.map
|