@modular-prompt/driver 0.15.0 → 0.17.0

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 (198) hide show
  1. package/README.md +124 -9
  2. package/dist/cache-controller.d.ts +4 -0
  3. package/dist/cache-controller.d.ts.map +1 -1
  4. package/dist/driver-registry/config-based-factory.d.ts.map +1 -1
  5. package/dist/driver-registry/config-based-factory.js +10 -3
  6. package/dist/driver-registry/config-based-factory.js.map +1 -1
  7. package/dist/driver-registry/factory-helper.d.ts.map +1 -1
  8. package/dist/driver-registry/factory-helper.js +10 -2
  9. package/dist/driver-registry/factory-helper.js.map +1 -1
  10. package/dist/driver-registry/index.d.ts +1 -1
  11. package/dist/driver-registry/index.d.ts.map +1 -1
  12. package/dist/driver-registry/types.d.ts +18 -1
  13. package/dist/driver-registry/types.d.ts.map +1 -1
  14. package/dist/formatter/converter.d.ts.map +1 -1
  15. package/dist/formatter/converter.js +31 -2
  16. package/dist/formatter/converter.js.map +1 -1
  17. package/dist/index.d.ts +5 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +5 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/local-inference/adapters.d.ts +6 -0
  22. package/dist/local-inference/adapters.d.ts.map +1 -1
  23. package/dist/local-inference/driver.d.ts.map +1 -1
  24. package/dist/local-inference/driver.js +45 -24
  25. package/dist/local-inference/driver.js.map +1 -1
  26. package/dist/local-inference/process-client.d.ts +4 -2
  27. package/dist/local-inference/process-client.d.ts.map +1 -1
  28. package/dist/local-inference/process-client.js +24 -8
  29. package/dist/local-inference/process-client.js.map +1 -1
  30. package/dist/local-inference/process-communication.d.ts +9 -2
  31. package/dist/local-inference/process-communication.d.ts.map +1 -1
  32. package/dist/local-inference/process-communication.js +37 -5
  33. package/dist/local-inference/process-communication.js.map +1 -1
  34. package/dist/local-inference/protocol.d.ts +4 -0
  35. package/dist/local-inference/protocol.d.ts.map +1 -1
  36. package/dist/local-inference/request-queue.d.ts +1 -1
  37. package/dist/local-inference/request-queue.d.ts.map +1 -1
  38. package/dist/local-inference/request-queue.js +26 -7
  39. package/dist/local-inference/request-queue.js.map +1 -1
  40. package/dist/local-inference/stream-utils.d.ts +6 -0
  41. package/dist/local-inference/stream-utils.d.ts.map +1 -1
  42. package/dist/local-inference/stream-utils.js.map +1 -1
  43. package/dist/mlx-ml/mlx-cache-controller.d.ts +9 -0
  44. package/dist/mlx-ml/mlx-cache-controller.d.ts.map +1 -1
  45. package/dist/mlx-ml/mlx-cache-controller.js +158 -32
  46. package/dist/mlx-ml/mlx-cache-controller.js.map +1 -1
  47. package/dist/mlx-ml/mlx-cache-support.d.ts +2 -2
  48. package/dist/mlx-ml/mlx-cache-support.d.ts.map +1 -1
  49. package/dist/mlx-ml/mlx-cache-support.js +8 -3
  50. package/dist/mlx-ml/mlx-cache-support.js.map +1 -1
  51. package/dist/mlx-ml/mlx-driver.d.ts +0 -1
  52. package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
  53. package/dist/mlx-ml/mlx-driver.js +1 -8
  54. package/dist/mlx-ml/mlx-driver.js.map +1 -1
  55. package/dist/mlx-ml/process/index.d.ts +1 -1
  56. package/dist/mlx-ml/process/index.d.ts.map +1 -1
  57. package/dist/mlx-ml/process/index.js +2 -2
  58. package/dist/mlx-ml/process/index.js.map +1 -1
  59. package/dist/models-config/index.d.ts +2 -2
  60. package/dist/models-config/index.d.ts.map +1 -1
  61. package/dist/models-config/index.js +2 -2
  62. package/dist/models-config/index.js.map +1 -1
  63. package/dist/models-config/paths.d.ts +8 -0
  64. package/dist/models-config/paths.d.ts.map +1 -1
  65. package/dist/models-config/paths.js +16 -1
  66. package/dist/models-config/paths.js.map +1 -1
  67. package/dist/models-config/resolve.d.ts +10 -2
  68. package/dist/models-config/resolve.d.ts.map +1 -1
  69. package/dist/models-config/resolve.js +119 -6
  70. package/dist/models-config/resolve.js.map +1 -1
  71. package/dist/models-config/types.d.ts +5 -1
  72. package/dist/models-config/types.d.ts.map +1 -1
  73. package/dist/pytorch/process/index.d.ts +4 -2
  74. package/dist/pytorch/process/index.d.ts.map +1 -1
  75. package/dist/pytorch/process/index.js +24 -7
  76. package/dist/pytorch/process/index.js.map +1 -1
  77. package/dist/pytorch/pytorch-cache-controller.d.ts +84 -0
  78. package/dist/pytorch/pytorch-cache-controller.d.ts.map +1 -0
  79. package/dist/pytorch/pytorch-cache-controller.js +742 -0
  80. package/dist/pytorch/pytorch-cache-controller.js.map +1 -0
  81. package/dist/pytorch/pytorch-cache-support.d.ts +23 -0
  82. package/dist/pytorch/pytorch-cache-support.d.ts.map +1 -0
  83. package/dist/pytorch/pytorch-cache-support.js +47 -0
  84. package/dist/pytorch/pytorch-cache-support.js.map +1 -0
  85. package/dist/pytorch/pytorch-driver.d.ts +8 -1
  86. package/dist/pytorch/pytorch-driver.d.ts.map +1 -1
  87. package/dist/pytorch/pytorch-driver.js +40 -0
  88. package/dist/pytorch/pytorch-driver.js.map +1 -1
  89. package/dist/runtime/check.d.ts.map +1 -1
  90. package/dist/runtime/check.js +9 -6
  91. package/dist/runtime/check.js.map +1 -1
  92. package/dist/runtime/index.d.ts +2 -1
  93. package/dist/runtime/index.d.ts.map +1 -1
  94. package/dist/runtime/index.js +2 -1
  95. package/dist/runtime/index.js.map +1 -1
  96. package/dist/runtime/manifest-core.d.mts +1 -0
  97. package/dist/runtime/manifest-core.mjs +1 -0
  98. package/dist/runtime/manifest-core.mjs.map +1 -1
  99. package/dist/runtime/manifest.d.ts +2 -0
  100. package/dist/runtime/manifest.d.ts.map +1 -1
  101. package/dist/runtime/manifest.js.map +1 -1
  102. package/dist/runtime/paths-core.d.mts +15 -1
  103. package/dist/runtime/paths-core.d.mts.map +1 -1
  104. package/dist/runtime/paths-core.mjs +50 -5
  105. package/dist/runtime/paths-core.mjs.map +1 -1
  106. package/dist/runtime/paths.d.ts +2 -2
  107. package/dist/runtime/paths.d.ts.map +1 -1
  108. package/dist/runtime/paths.js +2 -2
  109. package/dist/runtime/paths.js.map +1 -1
  110. package/dist/runtime/pytorch-template-core.d.mts +11 -0
  111. package/dist/runtime/pytorch-template-core.d.mts.map +1 -0
  112. package/dist/runtime/pytorch-template-core.mjs +54 -0
  113. package/dist/runtime/pytorch-template-core.mjs.map +1 -0
  114. package/dist/runtime/setup-commands-core.d.mts +16 -0
  115. package/dist/runtime/setup-commands-core.d.mts.map +1 -0
  116. package/dist/runtime/setup-commands-core.mjs +18 -0
  117. package/dist/runtime/setup-commands-core.mjs.map +1 -0
  118. package/dist/runtime/setup-commands.d.ts +2 -0
  119. package/dist/runtime/setup-commands.d.ts.map +1 -0
  120. package/dist/runtime/setup-commands.js +2 -0
  121. package/dist/runtime/setup-commands.js.map +1 -0
  122. package/docs/DRIVER_API.md +455 -0
  123. package/docs/LOCAL_MODEL_SETUP.md +765 -0
  124. package/docs/mlx-api-selection.md +301 -0
  125. package/package.json +12 -5
  126. package/scripts/download-model.js +3 -2
  127. package/scripts/runtime-cli.bin.test.ts +142 -0
  128. package/scripts/runtime-cli.js +322 -47
  129. package/scripts/runtime-cli.test.ts +163 -0
  130. package/src/mlx-ml/python/__main__.py +1 -1
  131. package/src/mlx-ml/python/backends/base.py +88 -18
  132. package/src/mlx-ml/python/backends/cache_archive.py +41 -0
  133. package/src/mlx-ml/python/backends/mlx_lm.py +45 -4
  134. package/src/mlx-ml/python/backends/mlx_vlm.py +679 -2
  135. package/src/mlx-ml/python/handlers/cache.py +4 -0
  136. package/src/mlx-ml/python/handlers/generate.py +33 -10
  137. package/src/mlx-ml/python/handlers/tokenize.py +1 -4
  138. package/src/mlx-ml/python/pyproject.toml +9 -3
  139. package/src/mlx-ml/python/server.py +2 -0
  140. package/src/mlx-ml/python/uv.lock +193 -433
  141. package/src/pytorch/templates/cpu-minimal/backends/base.py +139 -0
  142. package/src/pytorch/templates/cpu-minimal/backends/transformers_lm.py +1167 -0
  143. package/src/pytorch/{python → templates/cpu-minimal}/handlers/__init__.py +1 -0
  144. package/src/pytorch/templates/cpu-minimal/handlers/cache.py +88 -0
  145. package/src/pytorch/templates/cpu-minimal/handlers/generate.py +157 -0
  146. package/src/pytorch/{python → templates/cpu-minimal}/pyproject.toml +2 -2
  147. package/src/pytorch/{python → templates/cpu-minimal}/server.py +20 -2
  148. package/src/pytorch/templates/cpu-minimal/tests/test_cache_handler.py +284 -0
  149. package/src/pytorch/templates/cpu-minimal/tests/test_capabilities.py +14 -0
  150. package/src/pytorch/templates/cpu-minimal/tests/test_server.py +141 -0
  151. package/src/pytorch/templates/cpu-minimal/tests/test_transformers_errors.py +89 -0
  152. package/src/pytorch/templates/cpu-minimal/tests/test_transformers_lm_cache.py +554 -0
  153. package/src/pytorch/templates/cpu-minimal/utils/__init__.py +0 -0
  154. package/src/pytorch/{python → templates/cpu-minimal}/utils/token_utils.py +2 -2
  155. package/src/pytorch/templates/cpu-minimal/utils/transformers_errors.py +54 -0
  156. package/src/pytorch/{python → templates/cpu-minimal}/uv.lock +149 -109
  157. package/src/pytorch/templates/cuda/__main__.py +19 -0
  158. package/src/pytorch/templates/cuda/backends/__init__.py +3 -0
  159. package/src/pytorch/{python → templates/cuda}/backends/base.py +54 -6
  160. package/src/pytorch/templates/cuda/backends/transformers_lm.py +379 -0
  161. package/src/pytorch/templates/cuda/handlers/__init__.py +7 -0
  162. package/src/pytorch/templates/cuda/handlers/cache.py +93 -0
  163. package/src/pytorch/templates/cuda/handlers/cancel.py +53 -0
  164. package/src/pytorch/templates/cuda/handlers/capabilities.py +6 -0
  165. package/src/pytorch/templates/cuda/handlers/completion.py +15 -0
  166. package/src/pytorch/templates/cuda/handlers/format_test.py +70 -0
  167. package/src/pytorch/templates/cuda/handlers/generate.py +152 -0
  168. package/src/pytorch/templates/cuda/handlers/render.py +40 -0
  169. package/src/pytorch/templates/cuda/handlers/tokenize.py +63 -0
  170. package/src/pytorch/templates/cuda/pyproject.toml +37 -0
  171. package/src/pytorch/templates/cuda/server.py +158 -0
  172. package/src/pytorch/templates/cuda/tests/__init__.py +0 -0
  173. package/src/pytorch/templates/cuda/tests/test_cache_handler.py +207 -0
  174. package/src/pytorch/templates/cuda/tests/test_capabilities.py +14 -0
  175. package/src/pytorch/templates/cuda/tests/test_server.py +145 -0
  176. package/src/pytorch/templates/cuda/tests/test_transformers_errors.py +89 -0
  177. package/src/pytorch/templates/cuda/tests/test_transformers_lm_cache.py +288 -0
  178. package/src/pytorch/templates/cuda/utils/__init__.py +0 -0
  179. package/src/pytorch/templates/cuda/utils/chat_template_constraints.py +164 -0
  180. package/src/pytorch/templates/cuda/utils/prompt_builder.py +54 -0
  181. package/src/pytorch/templates/cuda/utils/template_render.py +80 -0
  182. package/src/pytorch/templates/cuda/utils/token_utils.py +376 -0
  183. package/src/pytorch/templates/cuda/utils/transformers_errors.py +54 -0
  184. package/src/pytorch/templates/cuda/uv.lock +734 -0
  185. package/src/pytorch/python/backends/transformers_lm.py +0 -127
  186. package/src/pytorch/python/handlers/generate.py +0 -68
  187. /package/src/pytorch/{python → templates/cpu-minimal}/__main__.py +0 -0
  188. /package/src/pytorch/{python → templates/cpu-minimal}/backends/__init__.py +0 -0
  189. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/cancel.py +0 -0
  190. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/capabilities.py +0 -0
  191. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/completion.py +0 -0
  192. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/format_test.py +0 -0
  193. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/render.py +0 -0
  194. /package/src/pytorch/{python → templates/cpu-minimal}/handlers/tokenize.py +0 -0
  195. /package/src/pytorch/{python/utils → templates/cpu-minimal/tests}/__init__.py +0 -0
  196. /package/src/pytorch/{python → templates/cpu-minimal}/utils/chat_template_constraints.py +0 -0
  197. /package/src/pytorch/{python → templates/cpu-minimal}/utils/prompt_builder.py +0 -0
  198. /package/src/pytorch/{python → templates/cpu-minimal}/utils/template_render.py +0 -0
@@ -18,6 +18,8 @@ def handle_cache_prefill(
18
18
  prefix_hashes: list[str] | None = None,
19
19
  tools: list | None = None,
20
20
  reasoning_effort: str | None = None,
21
+ images: list | None = None,
22
+ max_image_size: int = 768,
21
23
  ) -> None:
22
24
  tokenizer = backend.get_tokenizer()
23
25
 
@@ -74,6 +76,8 @@ def handle_cache_prefill(
74
76
  trim_to_tokens=trim_to_tokens,
75
77
  prefix_offsets=prefix_offsets,
76
78
  prefix_hashes=prefix_hashes,
79
+ images=images,
80
+ max_image_size=max_image_size,
77
81
  )
78
82
  if prefix_offsets and prefix_hashes:
79
83
  result["prefix_offsets"] = prefix_offsets
@@ -6,7 +6,6 @@ import re
6
6
  import sys
7
7
 
8
8
  from backends.base import ModelBackend
9
- from mlx_lm.models.cache import trim_prompt_cache
10
9
  from handlers.cancel import poll_cancel
11
10
 
12
11
 
@@ -29,6 +28,7 @@ def _stream_to_stdout(
29
28
  images: list | None = None,
30
29
  primer: str | None = None,
31
30
  prompt_cache: list | None = None,
31
+ cache_loaded: bool | None = None,
32
32
  ) -> None:
33
33
  if primer is not None:
34
34
  print(primer, end="", flush=True)
@@ -46,6 +46,8 @@ def _stream_to_stdout(
46
46
  meta["prompt_tokens"] = last_response.prompt_tokens
47
47
  if hasattr(last_response, "generation_tokens"):
48
48
  meta["generation_tokens"] = last_response.generation_tokens
49
+ if cache_loaded is not None:
50
+ meta["cache_loaded"] = cache_loaded
49
51
 
50
52
  if meta:
51
53
  print(f"\x1e__META__:{json.dumps(meta)}", end="\0", flush=True)
@@ -84,16 +86,22 @@ def handle_generate(
84
86
  else:
85
87
  sys.stderr.write(f"--- prompt\n{prompt}\n")
86
88
 
87
- # VLM 経路では KV キャッシュを使わない(旧 chat ハンドラと同様)
88
89
  prompt_cache = None
89
90
  cache_tokens = 0
90
- if cache_path and not images:
91
- prompt_cache = backend.load_cache_from_file(cache_path)
91
+ cache_loaded = None
92
+ if cache_path:
93
+ prompt_cache = backend.load_cache_from_file(
94
+ cache_path,
95
+ images=images,
96
+ max_image_size=max_image_size,
97
+ prompt=prompt,
98
+ )
99
+ cache_loaded = prompt_cache is not None
92
100
  if prompt_cache is not None:
93
101
  if cache_trim_tokens is not None:
94
102
  current_offset = backend.get_cache_offset(prompt_cache)
95
103
  if current_offset > cache_trim_tokens:
96
- trim_prompt_cache(prompt_cache, current_offset - cache_trim_tokens)
104
+ backend.trim_cache(prompt_cache, current_offset - cache_trim_tokens)
97
105
  sys.stderr.write(
98
106
  f"KV cache trimmed: {current_offset} → {cache_trim_tokens} tokens\n"
99
107
  )
@@ -101,9 +109,21 @@ def handle_generate(
101
109
  else:
102
110
  cache_tokens = current_offset
103
111
  else:
104
- meta_count = _read_cache_token_count(cache_path) if cache_path else None
112
+ meta_count = (
113
+ _read_cache_token_count(cache_path)
114
+ if cache_path
115
+ else None
116
+ )
105
117
  if meta_count is not None:
106
118
  cache_tokens = meta_count
119
+ elif (
120
+ backend.model_kind == "vlm"
121
+ and cache_path is not None
122
+ and cache_path.startswith("mlx-vlm-memory://")
123
+ ):
124
+ # Keep the Phase 1 in-process ref as a compatibility fallback.
125
+ # Persistent VLM refs always have the sidecar above.
126
+ cache_tokens = backend.get_cache_offset(prompt_cache)
107
127
  else:
108
128
  sys.stderr.write(
109
129
  f"WARNING: Cache file exists but no .meta.json found at {cache_path}. "
@@ -111,6 +131,7 @@ def handle_generate(
111
131
  )
112
132
  prompt_cache = None
113
133
  cache_tokens = 0
134
+ cache_loaded = False
114
135
  if prompt_cache is not None:
115
136
  sys.stderr.write(
116
137
  f"KV cache loaded: {len(prompt_cache)} layers, {cache_tokens} cached tokens\n"
@@ -122,11 +143,11 @@ def handle_generate(
122
143
 
123
144
  effective_prompt = prompt
124
145
  if prompt_cache is not None and cache_tokens > 0 and isinstance(prompt, str):
125
- tokenizer = backend.get_tokenizer()
126
- add_special = tokenizer.bos_token is None or not prompt.startswith(
127
- tokenizer.bos_token
146
+ full_tokens = backend.tokenize_prompt(
147
+ prompt,
148
+ images=images,
149
+ max_image_size=max_image_size,
128
150
  )
129
- full_tokens = tokenizer.encode(prompt, add_special_tokens=add_special)
130
151
 
131
152
  if cache_tokens < len(full_tokens):
132
153
  effective_prompt = full_tokens[cache_tokens:]
@@ -140,6 +161,7 @@ def handle_generate(
140
161
  f"ignoring prefill state\n"
141
162
  )
142
163
  prompt_cache = None
164
+ cache_loaded = False
143
165
 
144
166
  _stream_to_stdout(
145
167
  backend,
@@ -148,4 +170,5 @@ def handle_generate(
148
170
  images=images,
149
171
  primer=primer,
150
172
  prompt_cache=prompt_cache,
173
+ cache_loaded=cache_loaded,
151
174
  )
@@ -50,10 +50,7 @@ def handle_tokenize(
50
50
  prompt = generate_merged_prompt(messages, capabilities)
51
51
 
52
52
  # トークン化
53
- add_special = tokenizer.bos_token is None or not prompt.startswith(
54
- tokenizer.bos_token or ""
55
- )
56
- token_ids = tokenizer.encode(prompt, add_special_tokens=add_special)
53
+ token_ids = backend.tokenize_prompt(prompt)
57
54
 
58
55
  result["token_ids"] = token_ids
59
56
  result["token_count"] = len(token_ids)
@@ -7,14 +7,20 @@ dependencies = [
7
7
  "flex==6.14.1",
8
8
  "hf-xet==1.2.0",
9
9
  "jinja2==3.1.6",
10
- "mlx>=0.31.2; sys_platform == 'darwin'",
10
+ "mlx>=0.32.2; sys_platform == 'darwin'",
11
11
  "mlx-lm==0.31.3; sys_platform == 'darwin'",
12
12
  "mlx-optiq>=0.4.4; sys_platform == 'darwin'",
13
- "mlx-vlm==0.6.4; sys_platform == 'darwin'",
13
+ "mlx-vlm==0.7.0; sys_platform == 'darwin'",
14
14
  "tokenizers==0.22.2",
15
15
  "torch==2.9.1",
16
16
  "torchvision==0.24.1",
17
- "transformers>=5.5.0",
17
+ "transformers>=5.14.0",
18
+ ]
19
+
20
+ [tool.uv]
21
+ # mlx-optiq は transformers<5.13 を要求するが、mlx-vlm>=0.6.5 は 5.14+ が必要
22
+ override-dependencies = [
23
+ "transformers>=5.14.0",
18
24
  ]
19
25
 
20
26
  [dependency-groups]
@@ -100,6 +100,8 @@ class Server:
100
100
  prefix_hashes=req.get('prefix_hashes'),
101
101
  tools=req.get('tools'),
102
102
  reasoning_effort=req.get('reasoning_effort'),
103
+ images=req.get('images'),
104
+ max_image_size=req.get('maxImageSize', 768),
103
105
  )
104
106
 
105
107
  elif method == 'render':