@modular-prompt/driver 0.12.0 → 0.13.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.
Files changed (108) hide show
  1. package/dist/anthropic/anthropic-driver.d.ts +38 -8
  2. package/dist/anthropic/anthropic-driver.d.ts.map +1 -1
  3. package/dist/anthropic/anthropic-driver.js +180 -164
  4. package/dist/anthropic/anthropic-driver.js.map +1 -1
  5. package/dist/cache-controller.d.ts +28 -0
  6. package/dist/cache-controller.d.ts.map +1 -0
  7. package/dist/cache-controller.js +2 -0
  8. package/dist/cache-controller.js.map +1 -0
  9. package/dist/cache-utils.d.ts +20 -0
  10. package/dist/cache-utils.d.ts.map +1 -0
  11. package/dist/cache-utils.js +71 -0
  12. package/dist/cache-utils.js.map +1 -0
  13. package/dist/content-utils.d.ts.map +1 -1
  14. package/dist/content-utils.js +20 -0
  15. package/dist/content-utils.js.map +1 -1
  16. package/dist/driver-registry/config-based-factory.d.ts.map +1 -1
  17. package/dist/driver-registry/config-based-factory.js +7 -0
  18. package/dist/driver-registry/config-based-factory.js.map +1 -1
  19. package/dist/driver-registry/factory-helper.d.ts.map +1 -1
  20. package/dist/driver-registry/factory-helper.js +7 -4
  21. package/dist/driver-registry/factory-helper.js.map +1 -1
  22. package/dist/driver-registry/types.d.ts +6 -0
  23. package/dist/driver-registry/types.d.ts.map +1 -1
  24. package/dist/formatter/converter.js +1 -1
  25. package/dist/formatter/converter.js.map +1 -1
  26. package/dist/google-genai/element-converter.d.ts +11 -0
  27. package/dist/google-genai/element-converter.d.ts.map +1 -0
  28. package/dist/google-genai/element-converter.js +126 -0
  29. package/dist/google-genai/element-converter.js.map +1 -0
  30. package/dist/google-genai/google-genai-cache-controller.d.ts +24 -0
  31. package/dist/google-genai/google-genai-cache-controller.d.ts.map +1 -0
  32. package/dist/google-genai/google-genai-cache-controller.js +127 -0
  33. package/dist/google-genai/google-genai-cache-controller.js.map +1 -0
  34. package/dist/google-genai/google-genai-driver.d.ts +5 -29
  35. package/dist/google-genai/google-genai-driver.d.ts.map +1 -1
  36. package/dist/google-genai/google-genai-driver.js +92 -255
  37. package/dist/google-genai/google-genai-driver.js.map +1 -1
  38. package/dist/index.d.ts +4 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +3 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/mlx-ml/mlx-cache-controller.d.ts +66 -0
  43. package/dist/mlx-ml/mlx-cache-controller.d.ts.map +1 -0
  44. package/dist/mlx-ml/mlx-cache-controller.js +600 -0
  45. package/dist/mlx-ml/mlx-cache-controller.js.map +1 -0
  46. package/dist/mlx-ml/mlx-driver.d.ts +12 -7
  47. package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
  48. package/dist/mlx-ml/mlx-driver.js +192 -124
  49. package/dist/mlx-ml/mlx-driver.js.map +1 -1
  50. package/dist/mlx-ml/mlx-message-utils.d.ts +9 -0
  51. package/dist/mlx-ml/mlx-message-utils.d.ts.map +1 -0
  52. package/dist/mlx-ml/mlx-message-utils.js +71 -0
  53. package/dist/mlx-ml/mlx-message-utils.js.map +1 -0
  54. package/dist/mlx-ml/process/index.d.ts +7 -3
  55. package/dist/mlx-ml/process/index.d.ts.map +1 -1
  56. package/dist/mlx-ml/process/index.js +22 -7
  57. package/dist/mlx-ml/process/index.js.map +1 -1
  58. package/dist/mlx-ml/process/model-handlers.d.ts +4 -59
  59. package/dist/mlx-ml/process/model-handlers.d.ts.map +1 -1
  60. package/dist/mlx-ml/process/model-handlers.js +15 -14
  61. package/dist/mlx-ml/process/model-handlers.js.map +1 -1
  62. package/dist/mlx-ml/process/model-specific.d.ts +7 -0
  63. package/dist/mlx-ml/process/model-specific.d.ts.map +1 -1
  64. package/dist/mlx-ml/process/model-specific.js +3 -0
  65. package/dist/mlx-ml/process/model-specific.js.map +1 -1
  66. package/dist/mlx-ml/process/process-communication.d.ts +3 -0
  67. package/dist/mlx-ml/process/process-communication.d.ts.map +1 -1
  68. package/dist/mlx-ml/process/process-communication.js +13 -0
  69. package/dist/mlx-ml/process/process-communication.js.map +1 -1
  70. package/dist/mlx-ml/process/queue.d.ts +5 -2
  71. package/dist/mlx-ml/process/queue.d.ts.map +1 -1
  72. package/dist/mlx-ml/process/queue.js +101 -14
  73. package/dist/mlx-ml/process/queue.js.map +1 -1
  74. package/dist/mlx-ml/process/response-processor.d.ts +10 -0
  75. package/dist/mlx-ml/process/response-processor.d.ts.map +1 -1
  76. package/dist/mlx-ml/process/response-processor.js +23 -1
  77. package/dist/mlx-ml/process/response-processor.js.map +1 -1
  78. package/dist/mlx-ml/process/types.d.ts +50 -4
  79. package/dist/mlx-ml/process/types.d.ts.map +1 -1
  80. package/dist/mlx-ml/tool-call-parser.d.ts.map +1 -1
  81. package/dist/mlx-ml/tool-call-parser.js +44 -25
  82. package/dist/mlx-ml/tool-call-parser.js.map +1 -1
  83. package/dist/types.d.ts +2 -0
  84. package/dist/types.d.ts.map +1 -1
  85. package/package.json +7 -4
  86. package/src/mlx-ml/python/__main__.py +41 -449
  87. package/src/mlx-ml/python/backends/__init__.py +3 -0
  88. package/src/mlx-ml/python/backends/base.py +84 -0
  89. package/src/mlx-ml/python/backends/mlx_lm.py +202 -0
  90. package/src/mlx-ml/python/backends/mlx_vlm.py +99 -0
  91. package/src/mlx-ml/python/handlers/__init__.py +6 -0
  92. package/src/mlx-ml/python/handlers/cache.py +81 -0
  93. package/src/mlx-ml/python/handlers/capabilities.py +6 -0
  94. package/src/mlx-ml/python/handlers/chat.py +221 -0
  95. package/src/mlx-ml/python/handlers/completion.py +36 -0
  96. package/src/mlx-ml/python/handlers/format_test.py +70 -0
  97. package/src/mlx-ml/python/handlers/tokenize.py +63 -0
  98. package/src/mlx-ml/python/pyproject.toml +13 -3
  99. package/src/mlx-ml/python/server.py +126 -0
  100. package/src/mlx-ml/python/tests/__init__.py +0 -0
  101. package/src/mlx-ml/python/utils/__init__.py +0 -0
  102. package/src/mlx-ml/python/utils/prompt_builder.py +54 -0
  103. package/src/mlx-ml/python/{token_utils.py → utils/token_utils.py} +1 -2
  104. package/src/mlx-ml/python/uv.lock +266 -41
  105. /package/src/mlx-ml/python/{example_basic.py → examples/example_basic.py} +0 -0
  106. /package/src/mlx-ml/python/{example_tool_call.py → examples/example_tool_call.py} +0 -0
  107. /package/src/mlx-ml/python/{chat_template_constraints.py → utils/chat_template_constraints.py} +0 -0
  108. /package/src/mlx-ml/python/{vlm_utils.py → utils/vlm_utils.py} +0 -0
@@ -0,0 +1,600 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { tmpdir } from 'node:os';
3
+ import { basename, join } from 'node:path';
4
+ import { rmSync, existsSync, readFileSync } from 'node:fs';
5
+ import { unlink, mkdir, rm, writeFile } from 'node:fs/promises';
6
+ import { formatPromptAsMessages } from '../formatter/converter.js';
7
+ import { convertMessages, convertToolDefinitions } from './mlx-message-utils.js';
8
+ import { Logger } from '@modular-prompt/utils';
9
+ const logger = new Logger({ prefix: 'MLX', context: 'cache' });
10
+ export class MlxCacheController {
11
+ cacheByHash = new Map();
12
+ inflightRequests = new Map();
13
+ process;
14
+ cacheDir;
15
+ managedDir;
16
+ cacheDirReady = false;
17
+ closed = false;
18
+ bound = false;
19
+ cleanupHandler;
20
+ messageProcessor;
21
+ formatterOptions;
22
+ lastHandle;
23
+ lastElementHashes;
24
+ lastHandleModel;
25
+ lastHandleFormatterOptionsHash;
26
+ lastHandleToolsHash;
27
+ lastHandleReasoningEffort;
28
+ cacheIndex = { version: 1, entries: [] };
29
+ stats = {
30
+ totalQueries: 0,
31
+ memoryHit: 0, diskHit: 0, incremental: 0, fresh: 0,
32
+ prefillTokens: 0,
33
+ prefillReusedTokens: 0,
34
+ totalPromptTokens: 0,
35
+ totalCacheTokensUsed: 0,
36
+ };
37
+ constructor(options) {
38
+ this.formatterOptions = {};
39
+ if (options?.cacheDir) {
40
+ this.cacheDir = options.cacheDir;
41
+ this.managedDir = false;
42
+ }
43
+ else {
44
+ this.cacheDir = '';
45
+ this.managedDir = true;
46
+ }
47
+ }
48
+ bind(process, formatterOptions, messageProcessor) {
49
+ if (this.bound) {
50
+ throw new Error('MlxCacheController is already bound to a process');
51
+ }
52
+ this.process = process;
53
+ this.formatterOptions = formatterOptions;
54
+ this.messageProcessor = messageProcessor;
55
+ if (!this.cacheDir) {
56
+ this.cacheDir = join(tmpdir(), `mlx-prompt-cache-${randomBytes(6).toString('hex')}`);
57
+ }
58
+ if (this.managedDir) {
59
+ this.cleanupHandler = () => {
60
+ try {
61
+ rmSync(this.cacheDir, { recursive: true, force: true });
62
+ }
63
+ catch { /* best-effort */ }
64
+ };
65
+ globalThis.process.on('exit', this.cleanupHandler);
66
+ }
67
+ if (!this.managedDir) {
68
+ this.loadIndexSync();
69
+ }
70
+ this.bound = true;
71
+ }
72
+ async ensureCacheDir() {
73
+ if (this.cacheDirReady)
74
+ return;
75
+ await mkdir(this.cacheDir, { recursive: true, mode: 0o700 });
76
+ this.cacheDirReady = true;
77
+ }
78
+ get indexPath() {
79
+ return join(this.cacheDir, 'cache-index.json');
80
+ }
81
+ readMetaTokenCount(cachePath) {
82
+ try {
83
+ const raw = readFileSync(cachePath + '.meta.json', 'utf-8');
84
+ const meta = JSON.parse(raw);
85
+ return typeof meta.token_count === 'number' ? meta.token_count : 0;
86
+ }
87
+ catch {
88
+ return 0;
89
+ }
90
+ }
91
+ loadIndexSync() {
92
+ try {
93
+ if (existsSync(this.indexPath)) {
94
+ const raw = readFileSync(this.indexPath, 'utf-8');
95
+ const parsed = JSON.parse(raw);
96
+ if (parsed && parsed.version === 1 && Array.isArray(parsed.entries)) {
97
+ this.cacheIndex = parsed;
98
+ }
99
+ }
100
+ }
101
+ catch {
102
+ // corrupt index — start fresh
103
+ }
104
+ }
105
+ async saveIndex() {
106
+ if (this.managedDir)
107
+ return;
108
+ try {
109
+ await this.ensureCacheDir();
110
+ await writeFile(this.indexPath, JSON.stringify(this.cacheIndex, null, 2));
111
+ }
112
+ catch {
113
+ // best-effort
114
+ }
115
+ }
116
+ computeFormatterOptionsHash() {
117
+ if (!this.formatterOptions || Object.keys(this.formatterOptions).length === 0) {
118
+ return '';
119
+ }
120
+ return createHash('sha256').update(JSON.stringify(this.formatterOptions)).digest('hex');
121
+ }
122
+ computeToolsHash(tools) {
123
+ if (!tools || tools.length === 0)
124
+ return '';
125
+ const sorted = [...tools].sort((a, b) => a.name.localeCompare(b.name));
126
+ return createHash('sha256').update(JSON.stringify(sorted)).digest('hex');
127
+ }
128
+ updateLastCache(handle, elementHashes, params) {
129
+ this.lastHandle = handle;
130
+ this.lastElementHashes = elementHashes;
131
+ this.lastHandleModel = params.model;
132
+ this.lastHandleFormatterOptionsHash = this.computeFormatterOptionsHash();
133
+ this.lastHandleToolsHash = this.computeToolsHash(params.tools);
134
+ this.lastHandleReasoningEffort = params.reasoningEffort ?? '';
135
+ }
136
+ clearLastCache() {
137
+ this.lastHandle = undefined;
138
+ this.lastElementHashes = undefined;
139
+ this.lastHandleModel = undefined;
140
+ this.lastHandleFormatterOptionsHash = undefined;
141
+ this.lastHandleToolsHash = undefined;
142
+ this.lastHandleReasoningEffort = undefined;
143
+ }
144
+ computeElementHashes(params) {
145
+ const hashes = [];
146
+ for (const el of params.instructions || []) {
147
+ hashes.push('i:' + createHash('sha256').update(JSON.stringify(el)).digest('hex'));
148
+ }
149
+ for (const el of params.data || []) {
150
+ hashes.push('d:' + createHash('sha256').update(JSON.stringify(el)).digest('hex'));
151
+ }
152
+ return hashes;
153
+ }
154
+ readPrefixMeta(cachePath) {
155
+ try {
156
+ const raw = readFileSync(cachePath + '.meta.json', 'utf-8');
157
+ const meta = JSON.parse(raw);
158
+ if (!Array.isArray(meta.prefix_offsets) || !Array.isArray(meta.prefix_hashes))
159
+ return undefined;
160
+ return {
161
+ tokenCount: typeof meta.token_count === 'number' ? meta.token_count : 0,
162
+ prefixOffsets: meta.prefix_offsets,
163
+ prefixHashes: meta.prefix_hashes,
164
+ };
165
+ }
166
+ catch {
167
+ return undefined;
168
+ }
169
+ }
170
+ computeTokenPrefixHash(tokens, length) {
171
+ const buffer = Buffer.alloc(length * 4);
172
+ for (let i = 0; i < length; i++)
173
+ buffer.writeInt32LE(tokens[i], i * 4);
174
+ return createHash('sha256').update(buffer).digest('hex');
175
+ }
176
+ async computePrefixInfo(params, fullTokens, mlxTools) {
177
+ const instructions = params.instructions || [];
178
+ const data = params.data || [];
179
+ const offsets = [];
180
+ const hashes = [];
181
+ const boundaryIndices = new Set();
182
+ if (instructions.length > 0 && data.length > 0) {
183
+ boundaryIndices.add(instructions.length - 1);
184
+ }
185
+ // data部分を前方から走査し、連続するimmutableの最後の位置を境界にする
186
+ // instructionsはcacheHint不問でsection境界が既にカバーしている
187
+ let lastImmutableIdx = -1;
188
+ for (let i = 0; i < data.length; i++) {
189
+ if (data[i].cacheHint === 'immutable') {
190
+ lastImmutableIdx = instructions.length + i;
191
+ }
192
+ else {
193
+ break;
194
+ }
195
+ }
196
+ if (lastImmutableIdx >= 0) {
197
+ boundaryIndices.add(lastImmutableIdx);
198
+ }
199
+ // SetからArrayに変換してソート(prefixOffsetsが昇順になることを保証)
200
+ const sortedBoundaries = Array.from(boundaryIndices).sort((a, b) => a - b);
201
+ for (const boundaryIdx of sortedBoundaries) {
202
+ const partialInst = boundaryIdx < instructions.length
203
+ ? instructions.slice(0, boundaryIdx + 1)
204
+ : instructions;
205
+ const partialData = boundaryIdx >= instructions.length
206
+ ? data.slice(0, boundaryIdx - instructions.length + 1)
207
+ : [];
208
+ const partialPrompt = {
209
+ instructions: partialInst,
210
+ data: partialData,
211
+ output: [],
212
+ };
213
+ const chatMessages = formatPromptAsMessages(partialPrompt, this.formatterOptions);
214
+ let mlxMessages = convertMessages(chatMessages);
215
+ if (this.messageProcessor) {
216
+ mlxMessages = this.messageProcessor(mlxMessages);
217
+ }
218
+ try {
219
+ const result = await this.process.tokenize(mlxMessages, mlxTools, params.reasoningEffort);
220
+ if (result.error || !result.token_ids)
221
+ continue;
222
+ const partialTokens = result.token_ids;
223
+ let commonLen = 0;
224
+ const maxLen = Math.min(partialTokens.length, fullTokens.length);
225
+ for (let i = 0; i < maxLen; i++) {
226
+ if (partialTokens[i] !== fullTokens[i])
227
+ break;
228
+ commonLen = i + 1;
229
+ }
230
+ if (commonLen > 0) {
231
+ offsets.push(commonLen);
232
+ hashes.push(this.computeTokenPrefixHash(fullTokens, commonLen));
233
+ }
234
+ }
235
+ catch {
236
+ // tokenize failure for this boundary — skip
237
+ }
238
+ }
239
+ // Always include the full sequence hash for base cache verification
240
+ offsets.push(fullTokens.length);
241
+ hashes.push(this.computeTokenPrefixHash(fullTokens, fullTokens.length));
242
+ return { offsets, hashes };
243
+ }
244
+ async findBestBase(params, fullTokens) {
245
+ const newHashes = this.computeElementHashes(params);
246
+ if (newHashes.length === 0)
247
+ return undefined;
248
+ const fmtHash = this.computeFormatterOptionsHash();
249
+ const newToolsHash = this.computeToolsHash(params.tools);
250
+ const candidates = [];
251
+ const staleKeys = [];
252
+ for (const entry of this.cacheIndex.entries) {
253
+ if (entry.model !== params.model || entry.formatterOptionsHash !== fmtHash)
254
+ continue;
255
+ if ((entry.toolsHash ?? '') !== newToolsHash)
256
+ continue;
257
+ if ((entry.reasoningEffort ?? '') !== (params.reasoningEffort ?? ''))
258
+ continue;
259
+ const path = this.generateCachePath(entry.key);
260
+ if (existsSync(path) && this.readMetaTokenCount(path) > 0) {
261
+ candidates.push({ path, elementHashes: entry.elementHashes, label: entry.key.slice(0, 8) });
262
+ }
263
+ else {
264
+ staleKeys.push(entry.key);
265
+ }
266
+ }
267
+ if (this.lastHandle?.ref && this.lastElementHashes && existsSync(this.lastHandle.ref) && this.readMetaTokenCount(this.lastHandle.ref) > 0) {
268
+ const lastCompatible = this.lastHandleModel === params.model &&
269
+ this.lastHandleFormatterOptionsHash === fmtHash &&
270
+ (this.lastHandleToolsHash ?? '') === newToolsHash &&
271
+ (this.lastHandleReasoningEffort ?? '') === (params.reasoningEffort ?? '');
272
+ if (lastCompatible && !candidates.some(c => c.path === this.lastHandle.ref)) {
273
+ candidates.push({
274
+ path: this.lastHandle.ref,
275
+ elementHashes: this.lastElementHashes,
276
+ label: 'lastHandle',
277
+ });
278
+ }
279
+ }
280
+ if (staleKeys.length > 0) {
281
+ this.cacheIndex.entries = this.cacheIndex.entries.filter(e => !staleKeys.includes(e.key));
282
+ this.saveIndex().catch(() => { });
283
+ }
284
+ if (candidates.length === 0)
285
+ return undefined;
286
+ // Filter candidates by element hash prefix match
287
+ const matchedCandidates = [];
288
+ for (const c of candidates) {
289
+ const maxLen = Math.min(c.elementHashes.length, newHashes.length);
290
+ let matchLength = 0;
291
+ for (let i = 0; i < maxLen; i++) {
292
+ if (c.elementHashes[i] !== newHashes[i])
293
+ break;
294
+ matchLength++;
295
+ }
296
+ if (matchLength > 0) {
297
+ matchedCandidates.push({ candidate: c, elementMatchLength: matchLength });
298
+ }
299
+ }
300
+ if (matchedCandidates.length === 0)
301
+ return undefined;
302
+ // Verify token-level prefix match using prefix_hashes
303
+ let bestMatchOffset = 0;
304
+ let bestInfo;
305
+ for (const { candidate: c, elementMatchLength } of matchedCandidates) {
306
+ const meta = this.readPrefixMeta(c.path);
307
+ if (elementMatchLength === c.elementHashes.length && elementMatchLength >= newHashes.length) {
308
+ // All elements match — full cache hit
309
+ const tokenCount = meta?.tokenCount ?? this.readMetaTokenCount(c.path);
310
+ if (tokenCount > bestMatchOffset) {
311
+ bestMatchOffset = tokenCount;
312
+ bestInfo = {
313
+ path: c.path,
314
+ coversAll: true,
315
+ sourceElementHashes: c.elementHashes,
316
+ };
317
+ }
318
+ continue;
319
+ }
320
+ // Partial match — need prefix_hashes to verify token-level prefix
321
+ if (!meta || meta.prefixOffsets.length === 0) {
322
+ logger.debug(`findBestBase: skip ${c.label} (no prefix meta)`);
323
+ continue;
324
+ }
325
+ // Find the longest prefix hash match
326
+ let matchOffset = 0;
327
+ for (let i = 0; i < meta.prefixHashes.length; i++) {
328
+ const offset = meta.prefixOffsets[i];
329
+ if (offset > fullTokens.length)
330
+ break;
331
+ const hash = this.computeTokenPrefixHash(fullTokens, offset);
332
+ if (hash !== meta.prefixHashes[i])
333
+ break;
334
+ matchOffset = offset;
335
+ }
336
+ if (matchOffset > 0 && matchOffset > bestMatchOffset) {
337
+ bestMatchOffset = matchOffset;
338
+ bestInfo = {
339
+ path: c.path,
340
+ trimTokens: matchOffset,
341
+ coversAll: elementMatchLength >= newHashes.length,
342
+ sourceElementHashes: c.elementHashes,
343
+ };
344
+ }
345
+ }
346
+ if (bestInfo) {
347
+ logger.verbose(`findBestBase: match at ${bestMatchOffset} tokens`, bestInfo.trimTokens != null ? `(trim to ${bestInfo.trimTokens} tokens)` : '', bestInfo.coversAll ? '(covers all)' : '');
348
+ }
349
+ return bestInfo;
350
+ }
351
+ addToIndex(params, cacheKey) {
352
+ // avoid duplicates
353
+ if (this.cacheIndex.entries.some(e => e.key === cacheKey))
354
+ return;
355
+ this.cacheIndex.entries.push({
356
+ key: cacheKey,
357
+ model: params.model,
358
+ formatterOptionsHash: this.computeFormatterOptionsHash(),
359
+ elementHashes: this.computeElementHashes(params),
360
+ toolsHash: this.computeToolsHash(params.tools),
361
+ reasoningEffort: params.reasoningEffort,
362
+ createdAt: new Date().toISOString(),
363
+ });
364
+ }
365
+ removeFromIndex(cachePath) {
366
+ const key = basename(cachePath, '.safetensors');
367
+ this.cacheIndex.entries = this.cacheIndex.entries.filter(e => e.key !== key);
368
+ }
369
+ computeCacheKey(params) {
370
+ const payload = { model: params.model };
371
+ if (params.instructions && params.instructions.length > 0) {
372
+ payload.instructions = params.instructions;
373
+ }
374
+ if (params.data && params.data.length > 0) {
375
+ payload.data = params.data;
376
+ }
377
+ if (this.formatterOptions && Object.keys(this.formatterOptions).length > 0) {
378
+ payload.formatterOptions = this.formatterOptions;
379
+ }
380
+ if (params.tools && params.tools.length > 0) {
381
+ payload.tools = [...params.tools].sort((a, b) => a.name.localeCompare(b.name));
382
+ }
383
+ if (params.reasoningEffort) {
384
+ payload.reasoningEffort = params.reasoningEffort;
385
+ }
386
+ return createHash('sha256').update(JSON.stringify(payload)).digest('hex');
387
+ }
388
+ generateCachePath(cacheKey) {
389
+ return join(this.cacheDir, `${cacheKey}.safetensors`);
390
+ }
391
+ recordQuery() {
392
+ this.stats.totalQueries++;
393
+ }
394
+ recordPromptTokens(newPromptTokens, cacheTokensUsed) {
395
+ this.stats.totalPromptTokens += newPromptTokens + cacheTokensUsed;
396
+ this.stats.totalCacheTokensUsed += cacheTokensUsed;
397
+ }
398
+ readCacheTokenCount(cachePath) {
399
+ return this.readMetaTokenCount(cachePath);
400
+ }
401
+ getStats() {
402
+ const s = this.stats;
403
+ return {
404
+ totalQueries: s.totalQueries,
405
+ incremental: s.incremental, fresh: s.fresh,
406
+ totalPromptTokens: s.totalPromptTokens,
407
+ prefillReusedTokens: s.prefillReusedTokens,
408
+ cacheGrowthTokens: s.prefillTokens - s.prefillReusedTokens,
409
+ };
410
+ }
411
+ async prepare(params) {
412
+ if (!this.bound) {
413
+ throw new Error('MlxCacheController is not bound to a process');
414
+ }
415
+ const hasContent = (params.instructions?.length ?? 0) > 0 ||
416
+ (params.data?.length ?? 0) > 0;
417
+ if (!hasContent) {
418
+ throw new Error('Cannot prepare cache with no cacheable content');
419
+ }
420
+ const cacheKey = this.computeCacheKey(params);
421
+ const existing = this.cacheByHash.get(cacheKey);
422
+ if (existing) {
423
+ this.stats.memoryHit++;
424
+ logger.verbose('cache hit', cacheKey.slice(0, 12));
425
+ return existing;
426
+ }
427
+ const inflight = this.inflightRequests.get(cacheKey);
428
+ if (inflight) {
429
+ return inflight;
430
+ }
431
+ const prepareStart = performance.now();
432
+ const promise = this.createCache(params, cacheKey);
433
+ this.inflightRequests.set(cacheKey, promise);
434
+ try {
435
+ const handle = await promise;
436
+ logger.verbose(`prepare total ${(performance.now() - prepareStart).toFixed(0)}ms`, cacheKey.slice(0, 12));
437
+ return handle;
438
+ }
439
+ finally {
440
+ this.inflightRequests.delete(cacheKey);
441
+ }
442
+ }
443
+ static EMPTY_HANDLE = {
444
+ ref: '', includes: { instructions: false, dataElementCount: 0, tools: false }
445
+ };
446
+ async createCache(params, cacheKey) {
447
+ try {
448
+ await this.ensureCacheDir();
449
+ }
450
+ catch (e) {
451
+ logger.verbose('cache dir creation failed, skipping cache:', e instanceof Error ? e.message : String(e));
452
+ return MlxCacheController.EMPTY_HANDLE;
453
+ }
454
+ const cachePath = this.generateCachePath(cacheKey);
455
+ const elementHashes = this.computeElementHashes(params);
456
+ // Disk hit check (exact same cache already exists)
457
+ if (existsSync(cachePath) && existsSync(cachePath + '.meta.json') && this.readMetaTokenCount(cachePath) > 0) {
458
+ this.stats.diskHit++;
459
+ logger.verbose('reusing existing cache file', cacheKey.slice(0, 12));
460
+ }
461
+ else {
462
+ // Build messages early (needed for tokenize + findBestBase)
463
+ const prefillPrompt = {
464
+ instructions: params.instructions || [],
465
+ data: params.data || [],
466
+ output: [],
467
+ };
468
+ const chatMessages = formatPromptAsMessages(prefillPrompt, this.formatterOptions);
469
+ const preMergeMessages = convertMessages(chatMessages);
470
+ let mlxMessages = preMergeMessages;
471
+ if (this.messageProcessor) {
472
+ mlxMessages = this.messageProcessor(mlxMessages);
473
+ }
474
+ const hasTools = params.tools && params.tools.length > 0;
475
+ const mlxTools = hasTools ? convertToolDefinitions(params.tools) : undefined;
476
+ // Tokenize to get full token IDs (for findBestBase + prefix computation)
477
+ let fullTokens = null;
478
+ try {
479
+ const tokenResult = await this.process.tokenize(mlxMessages, mlxTools, params.reasoningEffort);
480
+ if (!tokenResult.error && tokenResult.token_ids) {
481
+ fullTokens = tokenResult.token_ids;
482
+ }
483
+ }
484
+ catch {
485
+ // tokenize failure — proceed without prefix matching
486
+ }
487
+ // Find best base cache
488
+ const base = fullTokens
489
+ ? await this.findBestBase(params, fullTokens)
490
+ : undefined;
491
+ if (base?.coversAll) {
492
+ this.stats.diskHit++;
493
+ logger.verbose('superset reuse', base.path.split('/').pop(), base.trimTokens != null ? `(trim to ${base.trimTokens})` : '');
494
+ const handle = {
495
+ ref: base.path,
496
+ trimTokens: base.trimTokens,
497
+ includes: {
498
+ instructions: (params.instructions?.length ?? 0) > 0,
499
+ dataElementCount: params.data?.length ?? 0,
500
+ tools: (params.tools?.length ?? 0) > 0,
501
+ },
502
+ };
503
+ this.cacheByHash.set(cacheKey, handle);
504
+ this.updateLastCache(handle, base.sourceElementHashes, params);
505
+ return handle;
506
+ }
507
+ if (base) {
508
+ logger.verbose('incremental prefill from', base.path.split('/').pop(), base.trimTokens != null ? `(trim to ${base.trimTokens})` : '');
509
+ }
510
+ // Compute prefix info if we have full tokens
511
+ let prefixOffsets;
512
+ let prefixHashes;
513
+ if (fullTokens) {
514
+ const prefixInfo = await this.computePrefixInfo(params, fullTokens, mlxTools);
515
+ if (prefixInfo.offsets.length > 0) {
516
+ prefixOffsets = prefixInfo.offsets;
517
+ prefixHashes = prefixInfo.hashes;
518
+ }
519
+ }
520
+ logger.debug('prefill', cachePath);
521
+ const prefillStart = performance.now();
522
+ try {
523
+ await this.process.cachePrefill(cachePath, mlxMessages, base?.path, base?.trimTokens, prefixOffsets, prefixHashes, mlxTools, params.reasoningEffort);
524
+ }
525
+ catch (e) {
526
+ logger.verbose('prefill failed, skipping cache:', e instanceof Error ? e.message : String(e));
527
+ return MlxCacheController.EMPTY_HANDLE;
528
+ }
529
+ const prefillMs = performance.now() - prefillStart;
530
+ const newTokens = this.readMetaTokenCount(cachePath);
531
+ this.stats.prefillTokens += newTokens;
532
+ if (base) {
533
+ this.stats.incremental++;
534
+ this.stats.prefillReusedTokens += base.trimTokens ?? this.readMetaTokenCount(base.path);
535
+ }
536
+ else {
537
+ this.stats.fresh++;
538
+ }
539
+ logger.verbose(`prefill ${prefillMs.toFixed(0)}ms`, base ? '(incremental)' : '(fresh)');
540
+ if (this.closed) {
541
+ await unlink(cachePath).catch(() => { });
542
+ await unlink(cachePath + '.meta.json').catch(() => { });
543
+ return MlxCacheController.EMPTY_HANDLE;
544
+ }
545
+ }
546
+ const handle = {
547
+ ref: cachePath,
548
+ includes: {
549
+ instructions: (params.instructions?.length ?? 0) > 0,
550
+ dataElementCount: params.data?.length ?? 0,
551
+ tools: (params.tools?.length ?? 0) > 0,
552
+ },
553
+ };
554
+ this.cacheByHash.set(cacheKey, handle);
555
+ this.updateLastCache(handle, elementHashes, params);
556
+ this.addToIndex(params, cacheKey);
557
+ await this.saveIndex();
558
+ return handle;
559
+ }
560
+ async invalidate(handle) {
561
+ logger.debug('invalidate', handle.ref);
562
+ this.removeFromIndex(handle.ref);
563
+ await unlink(handle.ref).catch(() => { });
564
+ await unlink(handle.ref + '.meta.json').catch(() => { });
565
+ for (const [key, entry] of this.cacheByHash) {
566
+ if (entry.ref === handle.ref) {
567
+ this.cacheByHash.delete(key);
568
+ }
569
+ }
570
+ if (this.lastHandle?.ref === handle.ref) {
571
+ this.clearLastCache();
572
+ }
573
+ await this.saveIndex();
574
+ }
575
+ async close() {
576
+ this.closed = true;
577
+ const timeout = new Promise(resolve => {
578
+ const timer = setTimeout(resolve, 30_000);
579
+ timer.unref();
580
+ });
581
+ await Promise.race([
582
+ Promise.allSettled([...this.inflightRequests.values()]),
583
+ timeout,
584
+ ]);
585
+ this.inflightRequests.clear();
586
+ this.cacheByHash.clear();
587
+ this.clearLastCache();
588
+ if (this.managedDir && this.cacheDir) {
589
+ await rm(this.cacheDir, { recursive: true, force: true }).catch(() => { });
590
+ }
591
+ else {
592
+ await this.saveIndex();
593
+ }
594
+ this.cacheDirReady = false;
595
+ if (this.cleanupHandler) {
596
+ globalThis.process.removeListener('exit', this.cleanupHandler);
597
+ }
598
+ }
599
+ }
600
+ //# sourceMappingURL=mlx-cache-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mlx-cache-controller.js","sourceRoot":"","sources":["../../src/mlx-ml/mlx-cache-controller.ts"],"names":[],"mappings":"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"}