@mlx-node/server 0.0.7 → 0.0.9

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.
Files changed (110) hide show
  1. package/dist/auth.d.ts +56 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +106 -0
  4. package/dist/chat-session-warm-reuse.d.ts +51 -0
  5. package/dist/chat-session-warm-reuse.d.ts.map +1 -0
  6. package/dist/chat-session-warm-reuse.js +72 -0
  7. package/dist/endpoints/messages-count-tokens.d.ts +8 -0
  8. package/dist/endpoints/messages-count-tokens.d.ts.map +1 -0
  9. package/dist/endpoints/messages-count-tokens.js +121 -0
  10. package/dist/endpoints/messages.d.ts +57 -5
  11. package/dist/endpoints/messages.d.ts.map +1 -1
  12. package/dist/endpoints/messages.js +1043 -147
  13. package/dist/endpoints/models.d.ts +2 -1
  14. package/dist/endpoints/models.d.ts.map +1 -1
  15. package/dist/endpoints/models.js +2 -2
  16. package/dist/endpoints/responses.d.ts +22 -7
  17. package/dist/endpoints/responses.d.ts.map +1 -1
  18. package/dist/endpoints/responses.js +608 -85
  19. package/dist/errors.d.ts +1 -0
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +3 -0
  22. package/dist/handler.d.ts +69 -1
  23. package/dist/handler.d.ts.map +1 -1
  24. package/dist/handler.js +70 -16
  25. package/dist/health.d.ts +146 -0
  26. package/dist/health.d.ts.map +1 -0
  27. package/dist/health.js +107 -0
  28. package/dist/host/discover.d.ts +19 -0
  29. package/dist/host/discover.d.ts.map +1 -0
  30. package/dist/host/discover.js +50 -0
  31. package/dist/host/env-policy.d.ts +62 -0
  32. package/dist/host/env-policy.d.ts.map +1 -0
  33. package/dist/host/env-policy.js +69 -0
  34. package/dist/host/index.d.ts +202 -0
  35. package/dist/host/index.d.ts.map +1 -0
  36. package/dist/host/index.js +325 -0
  37. package/dist/host/logger.d.ts +36 -0
  38. package/dist/host/logger.d.ts.map +1 -0
  39. package/dist/host/logger.js +376 -0
  40. package/dist/host/net.d.ts +65 -0
  41. package/dist/host/net.d.ts.map +1 -0
  42. package/dist/host/net.js +97 -0
  43. package/dist/host/paths.d.ts +28 -0
  44. package/dist/host/paths.d.ts.map +1 -0
  45. package/dist/host/paths.js +71 -0
  46. package/dist/host/swap.d.ts +27 -0
  47. package/dist/host/swap.d.ts.map +1 -0
  48. package/dist/host/swap.js +178 -0
  49. package/dist/host/temp-root.d.ts +57 -0
  50. package/dist/host/temp-root.d.ts.map +1 -0
  51. package/dist/host/temp-root.js +99 -0
  52. package/dist/idle-sweeper.d.ts +245 -0
  53. package/dist/idle-sweeper.d.ts.map +1 -0
  54. package/dist/idle-sweeper.js +408 -0
  55. package/dist/index.d.ts +19 -4
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +17 -1
  58. package/dist/load-model.d.ts +69 -0
  59. package/dist/load-model.d.ts.map +1 -0
  60. package/dist/load-model.js +63 -0
  61. package/dist/mappers/anthropic-request.d.ts +24 -2
  62. package/dist/mappers/anthropic-request.d.ts.map +1 -1
  63. package/dist/mappers/anthropic-request.js +222 -24
  64. package/dist/mappers/anthropic-response.d.ts +29 -4
  65. package/dist/mappers/anthropic-response.d.ts.map +1 -1
  66. package/dist/mappers/anthropic-response.js +143 -21
  67. package/dist/mappers/request.d.ts +48 -0
  68. package/dist/mappers/request.d.ts.map +1 -1
  69. package/dist/mappers/request.js +211 -35
  70. package/dist/mappers/response.d.ts.map +1 -1
  71. package/dist/mappers/response.js +13 -1
  72. package/dist/model-work-coordinator.d.ts +95 -0
  73. package/dist/model-work-coordinator.d.ts.map +1 -0
  74. package/dist/model-work-coordinator.js +201 -0
  75. package/dist/pending-writes.d.ts.map +1 -1
  76. package/dist/presets.d.ts +82 -0
  77. package/dist/presets.d.ts.map +1 -0
  78. package/dist/presets.js +98 -0
  79. package/dist/registry.d.ts +31 -1
  80. package/dist/registry.d.ts.map +1 -1
  81. package/dist/registry.js +33 -5
  82. package/dist/router.d.ts +37 -1
  83. package/dist/router.d.ts.map +1 -1
  84. package/dist/router.js +79 -7
  85. package/dist/server.d.ts +193 -3
  86. package/dist/server.d.ts.map +1 -1
  87. package/dist/server.js +173 -10
  88. package/dist/session-registry.d.ts +279 -18
  89. package/dist/session-registry.d.ts.map +1 -1
  90. package/dist/session-registry.js +518 -37
  91. package/dist/stop-sequence-buffer.d.ts +58 -0
  92. package/dist/stop-sequence-buffer.d.ts.map +1 -0
  93. package/dist/stop-sequence-buffer.js +148 -0
  94. package/dist/streaming.d.ts +14 -0
  95. package/dist/streaming.d.ts.map +1 -1
  96. package/dist/streaming.js +45 -0
  97. package/dist/text-recovery.d.ts +35 -0
  98. package/dist/text-recovery.d.ts.map +1 -0
  99. package/dist/text-recovery.js +41 -0
  100. package/dist/timing.d.ts +80 -0
  101. package/dist/timing.d.ts.map +1 -0
  102. package/dist/timing.js +121 -0
  103. package/dist/tool-call-buffer.d.ts +5 -5
  104. package/dist/tool-call-buffer.d.ts.map +1 -1
  105. package/dist/tool-call-buffer.js +28 -8
  106. package/dist/types-anthropic.d.ts +161 -1
  107. package/dist/types-anthropic.d.ts.map +1 -1
  108. package/dist/types.d.ts +172 -2
  109. package/dist/types.d.ts.map +1 -1
  110. package/package.json +15 -3
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Render a thrown value for {@link ModelLoadRecord.error}.
3
+ *
4
+ * Deliberately avoids `String(unknown)`: a rejection carrying a plain object
5
+ * would render as the useless `[object Object]` in the one field a supervisor
6
+ * reads to find out why the model would not load.
7
+ */
8
+ function describeLoadFailure(error) {
9
+ if (error instanceof Error)
10
+ return error.message;
11
+ if (typeof error === 'string')
12
+ return error;
13
+ if (error == null)
14
+ return 'unknown error';
15
+ try {
16
+ return JSON.stringify(error) ?? 'unknown error';
17
+ }
18
+ catch {
19
+ // Circular structure, or a `toJSON` that throws.
20
+ return 'unknown error';
21
+ }
22
+ }
23
+ /**
24
+ * Process-local gate for native MLX work.
25
+ *
26
+ * Individual model instances already have a per-model execution mutex, but a
27
+ * lazy `loadModel()` can still run load-time materialization / warmup Metal
28
+ * work while another model is decoding. MLX's allocator and command queues are
29
+ * process-wide, so model load/swap takes an exclusive writer slot; inference
30
+ * takes shared reader slots.
31
+ */
32
+ export class ModelWorkCoordinator {
33
+ activeReaders = 0;
34
+ writerHeld = false;
35
+ queuedWriters = 0;
36
+ readerWaiters = [];
37
+ writerWaiters = [];
38
+ /**
39
+ * Most recent settled load bracket. Retained here because the coordinator
40
+ * is the ONE place that brackets every load: a `resolveModel` failure in
41
+ * `/v1/messages` becomes a 500 and is otherwise dropped on the floor, so a
42
+ * supervisor polling `/health` afterwards had no way to learn what went
43
+ * wrong. See {@link ModelLoadRecord} for the "successful no-op overwrites
44
+ * an earlier failure" caveat.
45
+ */
46
+ lastLoadRecord = null;
47
+ /** Read-only: `true` while a load holds the exclusive writer slot. */
48
+ get writerActive() {
49
+ return this.writerHeld;
50
+ }
51
+ /** Read-only: loads parked in `acquireWrite()` waiting for the slot. */
52
+ get waitingWriters() {
53
+ return this.queuedWriters;
54
+ }
55
+ /** Read-only: outcome of the most recent settled load bracket, or `null`. */
56
+ get lastLoad() {
57
+ return this.lastLoadRecord;
58
+ }
59
+ /**
60
+ * Record a settled bracket. Called from the `finally` of both load
61
+ * wrappers so a throw is captured just as reliably as a success.
62
+ */
63
+ recordLoad(label, startedAt, error, ok) {
64
+ this.lastLoadRecord = {
65
+ label: label ?? null,
66
+ startedAt,
67
+ finishedAt: Date.now(),
68
+ ok,
69
+ error: ok ? null : describeLoadFailure(error),
70
+ };
71
+ }
72
+ /**
73
+ * @param label Optional identifier (normally the model name) stamped into
74
+ * {@link lastLoad} so `/health` can name what was being loaded.
75
+ */
76
+ async withModelLoad(fn, label) {
77
+ await this.acquireWrite();
78
+ // Measured from lock acquisition, not from arrival: `startedAt` is meant
79
+ // to answer "how long has the actual materialization been running",
80
+ // which is what a supervisor deciding whether to wait needs.
81
+ const startedAt = Date.now();
82
+ let ok = false;
83
+ let failure;
84
+ try {
85
+ const result = await fn();
86
+ ok = true;
87
+ return result;
88
+ }
89
+ catch (err) {
90
+ failure = err;
91
+ throw err;
92
+ }
93
+ finally {
94
+ this.recordLoad(label, startedAt, failure, ok);
95
+ this.releaseWrite();
96
+ }
97
+ }
98
+ /**
99
+ * Like {@link withModelLoad} but reports whether THIS caller owned the
100
+ * load (acquired the writer lock with no contention) or merely waited
101
+ * behind a load that was already in flight when it arrived.
102
+ *
103
+ * Decided at sync-time before any await: if neither a writer is active
104
+ * nor any writer is queued ahead, this caller is the owner; otherwise
105
+ * it is parked behind someone else's load and `owner` is `false`. The
106
+ * distinction is used by `/v1/messages` to split `resolve_ms` (own
107
+ * load + lookup) from `load_wait_ms` (waiting on a peer's load) so a
108
+ * 60-second cold-load does not look like 60 seconds of own work for
109
+ * every concurrent request.
110
+ */
111
+ async withModelLoadInstrumented(fn, label) {
112
+ // `owner` MUST be decided synchronously, before any await, so the
113
+ // signal reflects coordinator state at arrival rather than after
114
+ // any peer transition. The wait/own split is measured around the
115
+ // actual phase boundaries (lock acquisition, fn completion) so the
116
+ // two intervals partition cleanly instead of both reporting total
117
+ // elapsed time — see `ModelLoadOutcome` for the contract.
118
+ const owner = !this.writerHeld && this.queuedWriters === 0;
119
+ const arrivedAt = Date.now();
120
+ await this.acquireWrite();
121
+ const lockAcquiredAt = Date.now();
122
+ let ok = false;
123
+ let failure;
124
+ try {
125
+ const result = await fn();
126
+ ok = true;
127
+ const fnDoneAt = Date.now();
128
+ const waitMs = Math.max(0, lockAcquiredAt - arrivedAt);
129
+ const ownMs = Math.max(0, fnDoneAt - lockAcquiredAt);
130
+ return { result, owner, waitMs, ownMs };
131
+ }
132
+ catch (err) {
133
+ failure = err;
134
+ throw err;
135
+ }
136
+ finally {
137
+ this.recordLoad(label, lockAcquiredAt, failure, ok);
138
+ this.releaseWrite();
139
+ }
140
+ }
141
+ async withInference(fn) {
142
+ await this.acquireRead();
143
+ try {
144
+ return await fn();
145
+ }
146
+ finally {
147
+ this.releaseRead();
148
+ }
149
+ }
150
+ acquireRead() {
151
+ if (!this.writerHeld && this.queuedWriters === 0) {
152
+ this.activeReaders += 1;
153
+ return Promise.resolve();
154
+ }
155
+ return new Promise((resolve) => {
156
+ this.readerWaiters.push(() => {
157
+ this.activeReaders += 1;
158
+ resolve();
159
+ });
160
+ });
161
+ }
162
+ acquireWrite() {
163
+ this.queuedWriters += 1;
164
+ if (!this.writerHeld && this.activeReaders === 0) {
165
+ this.queuedWriters -= 1;
166
+ this.writerHeld = true;
167
+ return Promise.resolve();
168
+ }
169
+ return new Promise((resolve) => {
170
+ this.writerWaiters.push(() => {
171
+ this.queuedWriters -= 1;
172
+ this.writerHeld = true;
173
+ resolve();
174
+ });
175
+ });
176
+ }
177
+ releaseRead() {
178
+ this.activeReaders -= 1;
179
+ if (this.activeReaders < 0)
180
+ this.activeReaders = 0;
181
+ if (this.activeReaders === 0)
182
+ this.drain();
183
+ }
184
+ releaseWrite() {
185
+ this.writerHeld = false;
186
+ this.drain();
187
+ }
188
+ drain() {
189
+ if (this.writerHeld)
190
+ return;
191
+ if (this.activeReaders === 0 && this.writerWaiters.length > 0) {
192
+ this.writerWaiters.shift()?.();
193
+ return;
194
+ }
195
+ if (this.queuedWriters === 0 && this.readerWaiters.length > 0) {
196
+ const readers = this.readerWaiters.splice(0);
197
+ for (const resolve of readers)
198
+ resolve();
199
+ }
200
+ }
201
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"pending-writes.d.ts","sourceRoot":"","sources":["../src/pending-writes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwGG;AAEH;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAkC;IAE3E;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CACjB;IAEZ;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAElD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI;IA0ClF;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;IAInD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAWtD;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO;IAyB/E;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAYpB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAqBnC,iEAAiE;IACjE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAG7B;IAED;;;;;;OAMG;IACH,IAAI,4BAA4B,IAAI,MAAM,CAEzC;CACF;AAYD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAOxE"}
1
+ {"version":3,"file":"pending-writes.d.ts","sourceRoot":"","sources":["../src/pending-writes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwGG;AAEH;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAkC;IAE3E;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CACjB;IAEZ;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAElD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAwCjF;IAED;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAElD;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASrD;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAuB9E;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAYpB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAmBlC;IAED,iEAAiE;IACjE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAG7B;IAED;;;;;;OAMG;IACH,IAAI,4BAA4B,IAAI,MAAM,CAEzC;CACF;AAYD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAOxE"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Sampling presets recommended by third-party model authors, exposed
3
+ * here as `ChatConfig`-shaped objects so an operator can pin them at
4
+ * `ModelRegistry.register(name, model, { samplingDefaults: ... })`
5
+ * time with a single import.
6
+ *
7
+ * Per-request client values (OpenAI `temperature`/`top_p`, Anthropic
8
+ * equivalents) still override these defaults where the client sends
9
+ * them — `ChatSession.mergeConfig` treats per-call config as an
10
+ * overlay on top of `defaultConfig`. These presets only fill in the
11
+ * parameters clients never send (`top_k`, `min_p`, penalties).
12
+ */
13
+ import type { ChatConfig } from '@mlx-node/core';
14
+ /**
15
+ * Sampling defaults from Unsloth's Qwen3.6 guide:
16
+ * https://unsloth.ai/docs/models/qwen3.6#recommended-settings
17
+ *
18
+ * All modes pin `top_k = 20` and `min_p = 0.0`; they differ in
19
+ * `temperature`, `top_p`, and `presence_penalty`.
20
+ *
21
+ * The native anti-repetition cutoff is now disabled by default
22
+ * (vLLM-aligned — vLLM ships no repetition-stop heuristic), so these
23
+ * presets no longer pin `maxConsecutiveTokens` / `maxNgramRepeats` /
24
+ * `ngramSize`. Repetition is shaped by the sampling penalties above and
25
+ * bounded by the per-model `maxOutputTokens`. An operator or client can
26
+ * still opt in by setting those fields explicitly — a per-request config
27
+ * value wins via `ChatSession.mergeConfig`.
28
+ */
29
+ export declare const QWEN_SAMPLING_DEFAULTS: {
30
+ /** Thinking mode for precise coding tasks: temp=0.6, top_p=0.95, pp=0.0 */
31
+ readonly thinkingCoding: {
32
+ temperature: number;
33
+ topP: number;
34
+ topK: number;
35
+ minP: number;
36
+ presencePenalty: number;
37
+ repetitionPenalty: number;
38
+ };
39
+ /** Thinking mode for general tasks: temp=1.0, top_p=0.95, pp=1.5 */
40
+ readonly thinkingGeneral: {
41
+ temperature: number;
42
+ topP: number;
43
+ topK: number;
44
+ minP: number;
45
+ presencePenalty: number;
46
+ repetitionPenalty: number;
47
+ };
48
+ /** Instruct (non-thinking) for general tasks: temp=0.7, top_p=0.8, pp=1.5 */
49
+ readonly instructGeneral: {
50
+ temperature: number;
51
+ topP: number;
52
+ topK: number;
53
+ minP: number;
54
+ presencePenalty: number;
55
+ repetitionPenalty: number;
56
+ };
57
+ /** Instruct (non-thinking) for reasoning tasks: temp=1.0, top_p=0.95, pp=1.5 */
58
+ readonly instructReasoning: {
59
+ temperature: number;
60
+ topP: number;
61
+ topK: number;
62
+ minP: number;
63
+ presencePenalty: number;
64
+ repetitionPenalty: number;
65
+ };
66
+ };
67
+ /** Sampling defaults for Gemma4 Instruct. */
68
+ export declare const GEMMA4_SAMPLING_DEFAULTS: ChatConfig;
69
+ /** Sampling defaults for LFM2.5 Thinking. */
70
+ export declare const LFM2_SAMPLING_DEFAULTS: ChatConfig;
71
+ /** Sampling + per-model output token cap exposed by {@link LAUNCH_PRESETS}. */
72
+ export interface LaunchPreset {
73
+ sampling: ChatConfig;
74
+ maxOutputTokens: number;
75
+ }
76
+ /**
77
+ * Per-`ModelType` presets used by `mlx launch claude` to pre-wire a
78
+ * discovered model with sensible sampling defaults + a max output
79
+ * token budget. Keyed on the string returned by `detectModelType()`.
80
+ */
81
+ export declare const LAUNCH_PRESETS: Record<string, LaunchPreset>;
82
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB;IACjC,2EAA2E;;;;;;;;;IAU3E,oEAAoE;;;;;;;;;IAUpE,6EAA6E;;;;;;;;;IAU7E,gFAAgF;;;;;;;;;CASxE,CAAC;AAEX,6CAA6C;AAC7C,eAAO,MAAM,wBAAwB,EAAE,UAOtC,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,EAAE,UAOpC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,UAAU,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAqBvD,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Sampling defaults from Unsloth's Qwen3.6 guide:
3
+ * https://unsloth.ai/docs/models/qwen3.6#recommended-settings
4
+ *
5
+ * All modes pin `top_k = 20` and `min_p = 0.0`; they differ in
6
+ * `temperature`, `top_p`, and `presence_penalty`.
7
+ *
8
+ * The native anti-repetition cutoff is now disabled by default
9
+ * (vLLM-aligned — vLLM ships no repetition-stop heuristic), so these
10
+ * presets no longer pin `maxConsecutiveTokens` / `maxNgramRepeats` /
11
+ * `ngramSize`. Repetition is shaped by the sampling penalties above and
12
+ * bounded by the per-model `maxOutputTokens`. An operator or client can
13
+ * still opt in by setting those fields explicitly — a per-request config
14
+ * value wins via `ChatSession.mergeConfig`.
15
+ */
16
+ export const QWEN_SAMPLING_DEFAULTS = {
17
+ /** Thinking mode for precise coding tasks: temp=0.6, top_p=0.95, pp=0.0 */
18
+ thinkingCoding: {
19
+ temperature: 0.6,
20
+ topP: 0.95,
21
+ topK: 20,
22
+ minP: 0.0,
23
+ presencePenalty: 0.0,
24
+ repetitionPenalty: 1.0,
25
+ },
26
+ /** Thinking mode for general tasks: temp=1.0, top_p=0.95, pp=1.5 */
27
+ thinkingGeneral: {
28
+ temperature: 1.0,
29
+ topP: 0.95,
30
+ topK: 20,
31
+ minP: 0.0,
32
+ presencePenalty: 1.5,
33
+ repetitionPenalty: 1.0,
34
+ },
35
+ /** Instruct (non-thinking) for general tasks: temp=0.7, top_p=0.8, pp=1.5 */
36
+ instructGeneral: {
37
+ temperature: 0.7,
38
+ topP: 0.8,
39
+ topK: 20,
40
+ minP: 0.0,
41
+ presencePenalty: 1.5,
42
+ repetitionPenalty: 1.0,
43
+ },
44
+ /** Instruct (non-thinking) for reasoning tasks: temp=1.0, top_p=0.95, pp=1.5 */
45
+ instructReasoning: {
46
+ temperature: 1.0,
47
+ topP: 0.95,
48
+ topK: 20,
49
+ minP: 0.0,
50
+ presencePenalty: 1.5,
51
+ repetitionPenalty: 1.0,
52
+ },
53
+ };
54
+ /** Sampling defaults for Gemma4 Instruct. */
55
+ export const GEMMA4_SAMPLING_DEFAULTS = {
56
+ temperature: 0.7,
57
+ topP: 0.95,
58
+ topK: 64,
59
+ minP: 0.0,
60
+ presencePenalty: 0.0,
61
+ repetitionPenalty: 1.0,
62
+ };
63
+ /** Sampling defaults for LFM2.5 Thinking. */
64
+ export const LFM2_SAMPLING_DEFAULTS = {
65
+ temperature: 0.05,
66
+ topP: 1.0,
67
+ topK: 50,
68
+ minP: 0.0,
69
+ presencePenalty: 0.0,
70
+ repetitionPenalty: 1.05,
71
+ };
72
+ /**
73
+ * Per-`ModelType` presets used by `mlx launch claude` to pre-wire a
74
+ * discovered model with sensible sampling defaults + a max output
75
+ * token budget. Keyed on the string returned by `detectModelType()`.
76
+ */
77
+ export const LAUNCH_PRESETS = {
78
+ qwen3: {
79
+ sampling: QWEN_SAMPLING_DEFAULTS.thinkingCoding,
80
+ maxOutputTokens: 38912,
81
+ },
82
+ qwen3_5: {
83
+ sampling: QWEN_SAMPLING_DEFAULTS.thinkingCoding,
84
+ maxOutputTokens: 81920,
85
+ },
86
+ qwen3_5_moe: {
87
+ sampling: QWEN_SAMPLING_DEFAULTS.thinkingCoding,
88
+ maxOutputTokens: 81920,
89
+ },
90
+ gemma4: {
91
+ sampling: GEMMA4_SAMPLING_DEFAULTS,
92
+ maxOutputTokens: 16384,
93
+ },
94
+ lfm2: {
95
+ sampling: LFM2_SAMPLING_DEFAULTS,
96
+ maxOutputTokens: 8192,
97
+ },
98
+ };
@@ -36,6 +36,7 @@
36
36
  * `body.model`. Instance ids recognise them as the same binding
37
37
  * and the continuation is accepted.
38
38
  */
39
+ import type { ChatConfig } from '@mlx-node/core';
39
40
  import type { SessionCapableModel } from '@mlx-node/lm';
40
41
  import { SessionRegistry } from './session-registry.js';
41
42
  /** Minimal contract for a model that can be served via chat sessions. */
@@ -64,6 +65,35 @@ export interface ModelRegistryOptions {
64
65
  */
65
66
  maxQueueDepth?: number;
66
67
  }
68
+ /**
69
+ * Per-registration options for {@link ModelRegistry.register}.
70
+ */
71
+ export interface RegisterOptions {
72
+ /**
73
+ * Per-model sampling defaults forwarded through the bound
74
+ * `SessionRegistry` into every `ChatSession` it allocates (as the
75
+ * session's `defaultConfig`). Clients' per-request sampling values
76
+ * (OpenAI `temperature`/`top_p`, Anthropic equivalents) still win
77
+ * where present because `ChatSession.mergeConfig` treats them as an
78
+ * overlay — these defaults only fill the gaps for parameters the
79
+ * client never sent (`top_k`, `min_p`, penalties, etc.).
80
+ *
81
+ * Re-registering the same name with a fresh `samplingDefaults` value
82
+ * overwrites the binding's defaults in place so the next
83
+ * `ChatSession` allocated out of the registry picks up the new
84
+ * values. Warm sessions already in flight keep the previous defaults
85
+ * until they settle; this matches how the refresh path treats other
86
+ * per-binding state.
87
+ */
88
+ samplingDefaults?: ChatConfig;
89
+ /**
90
+ * Optional per-model upper bound for generated output tokens. This is
91
+ * intentionally separate from `samplingDefaults.maxNewTokens`: client
92
+ * requests still provide the desired length, while endpoint handlers can
93
+ * clamp pathological values before dispatch.
94
+ */
95
+ maxOutputTokens?: number;
96
+ }
67
97
  export declare class ModelRegistry {
68
98
  private readonly maxQueueDepth;
69
99
  private readonly models;
@@ -140,7 +170,7 @@ export declare class ModelRegistry {
140
170
  * preserves the id because `instanceIds.has(model)` is already
141
171
  * true.
142
172
  */
143
- register(name: string, model: ServableModel): void;
173
+ register(name: string, model: ServableModel, opts?: RegisterOptions): void;
144
174
  /**
145
175
  * Unregister a model by name.
146
176
  *
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/registry.js CHANGED
@@ -115,13 +115,23 @@ export class ModelRegistry {
115
115
  * preserves the id because `instanceIds.has(model)` is already
116
116
  * true.
117
117
  */
118
- register(name, model) {
118
+ register(name, model, opts) {
119
+ const samplingDefaults = opts?.samplingDefaults;
120
+ const maxOutputTokens = opts?.maxOutputTokens;
119
121
  const existing = this.models.get(name);
120
122
  if (existing && existing.model === model) {
121
123
  // Same name + same model object: leave the binding and refcount
122
124
  // alone. Refresh createdAt so `/v1/models` surfaces the most
123
- // recent registration time.
125
+ // recent registration time. A fresh `samplingDefaults` from the
126
+ // re-registration is applied in place so the operator can tune
127
+ // per-model knobs without fully unregistering first.
124
128
  existing.createdAt = Math.floor(Date.now() / 1000);
129
+ if (opts && 'samplingDefaults' in opts) {
130
+ existing.sessionRegistry.setSamplingDefaults(samplingDefaults);
131
+ }
132
+ if (opts && 'maxOutputTokens' in opts) {
133
+ existing.sessionRegistry.setMaxOutputTokens(maxOutputTokens);
134
+ }
125
135
  return;
126
136
  }
127
137
  if (existing) {
@@ -138,7 +148,12 @@ export class ModelRegistry {
138
148
  let binding = this.sessionRegistriesByModel.get(model);
139
149
  if (!binding) {
140
150
  binding = {
141
- registry: new SessionRegistry({ model, maxQueueDepth: this.maxQueueDepth }),
151
+ registry: new SessionRegistry({
152
+ model,
153
+ maxQueueDepth: this.maxQueueDepth,
154
+ samplingDefaults,
155
+ maxOutputTokens,
156
+ }),
142
157
  refCount: 0,
143
158
  inFlight: 0,
144
159
  pendingPersists: 0,
@@ -146,8 +161,21 @@ export class ModelRegistry {
146
161
  };
147
162
  this.sessionRegistriesByModel.set(model, binding);
148
163
  }
149
- else if (binding.pendingTeardown) {
150
- binding.pendingTeardown = false;
164
+ else {
165
+ if (binding.pendingTeardown) {
166
+ binding.pendingTeardown = false;
167
+ }
168
+ // Aliasing or reviving an existing binding: if this call passed
169
+ // `samplingDefaults` explicitly, overwrite the shared binding's
170
+ // defaults so the latest registration wins for every alias.
171
+ // Call sites that omit the field leave the existing defaults
172
+ // intact.
173
+ if (opts && 'samplingDefaults' in opts) {
174
+ binding.registry.setSamplingDefaults(samplingDefaults);
175
+ }
176
+ if (opts && 'maxOutputTokens' in opts) {
177
+ binding.registry.setMaxOutputTokens(maxOutputTokens);
178
+ }
151
179
  }
152
180
  binding.refCount += 1;
153
181
  // Allocate a fresh monotonic instance id on first sight of this
package/dist/router.d.ts CHANGED
@@ -1,6 +1,42 @@
1
1
  /** Path-based router for /v1/* endpoints. */
2
2
  import type { IncomingMessage, ServerResponse } from 'node:http';
3
3
  import type { ResponseStore } from '@mlx-node/core';
4
+ import type { PublicModelEntry } from './handler.js';
5
+ import { type ServerHealth } from './health.js';
6
+ import type { IdleSweeper } from './idle-sweeper.js';
7
+ import type { ModelWorkCoordinator } from './model-work-coordinator.js';
4
8
  import type { ModelRegistry } from './registry.js';
5
- export declare function routeRequest(req: IncomingMessage, res: ServerResponse, registry: ModelRegistry, store: ResponseStore | null, responseRetentionSec?: number): Promise<void>;
9
+ /**
10
+ * The request's pathname, parsed against a CONSTANT base.
11
+ *
12
+ * Never against `Host`. That header is attacker-controlled text on every
13
+ * request — `Host: [` makes `new URL()` throw `ERR_INVALID_URL`, and a throw
14
+ * from an async request listener is an unhandled rejection, which under Node's
15
+ * default `--unhandled-rejections=throw` takes the whole process down. One
16
+ * malformed byte from any client that can reach the socket was enough to end
17
+ * inference. A pathname does not depend on the authority anyway, so a fixed
18
+ * base is both safer and equivalent: an absolute-form request URI
19
+ * (`GET http://host/v1/models HTTP/1.1`, legal in HTTP/1.1) still wins over
20
+ * the base and yields the same path it always did.
21
+ *
22
+ * `req.url` itself is guarded too, for the same reason rather than a known
23
+ * input: this function's contract is that no request can make it throw.
24
+ */
25
+ export declare function requestPathname(req: IncomingMessage): string;
26
+ /**
27
+ * Trailing options bag. Added as an object rather than two more positional
28
+ * parameters — `routeRequest` already carries nine, and the two knobs here
29
+ * are unrelated to each other.
30
+ */
31
+ export interface RouteExtras {
32
+ /** Builds the `/health` body. Omitted ⇒ the legacy constant `{ status: 'ok' }`. */
33
+ health?: () => ServerHealth;
34
+ /**
35
+ * Whether the caller presented a valid token. Only consulted by `/health`,
36
+ * which is the one route reachable without one. `true` when no token is
37
+ * configured at all, so an unprotected server keeps serving the full body.
38
+ */
39
+ authenticated?: boolean;
40
+ }
41
+ export declare function routeRequest(req: IncomingMessage, res: ServerResponse, registry: ModelRegistry, store: ResponseStore | null, responseRetentionSec?: number, idleSweeper?: IdleSweeper | null, resolveModel?: (name: string) => Promise<void>, listModels?: () => PublicModelEntry[], modelWorkCoordinator?: ModelWorkCoordinator, extras?: RouteExtras): Promise<void>;
6
42
  //# sourceMappingURL=router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAYpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAyBnD,wBAAsB,YAAY,CAChC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAAC,IAAI,CAAC,CA8Df"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAapD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACjE,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;AAOnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAS5D;AAoBD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,oBAAoB,CAAC,EAAE,MAAM,EAC7B,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,EAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9C,UAAU,CAAC,EAAE,MAAM,gBAAgB,EAAE,EACrC,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAuHf"}