mtplx 2.2.0__tar.gz → 2.4.0__tar.gz
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.
- {mtplx-2.2.0 → mtplx-2.4.0}/CHANGELOG.md +189 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/NOTICE +4 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/PKG-INFO +23 -3
- {mtplx-2.2.0 → mtplx-2.4.0}/README.md +20 -1
- mtplx-2.4.0/mtplx/a3b_compiled_target_prefix.py +981 -0
- mtplx-2.4.0/mtplx/a3b_whole_moe.py +1224 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/artifacts.py +121 -8
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/descriptors.py +66 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/hy_v3_mtp.py +3 -3
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/registry.py +83 -11
- mtplx-2.4.0/mtplx/batched_decode.py +1322 -0
- mtplx-2.4.0/mtplx/benchmarks/code_eval.py +405 -0
- mtplx-2.4.0/mtplx/benchmarks/programming_prompts.py +246 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/cache_state.py +198 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/cli.py +18 -5
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/commands/public.py +260 -54
- mtplx-2.4.0/mtplx/compile_state.py +39 -0
- mtplx-2.4.0/mtplx/compiled_forward.py +144 -0
- mtplx-2.4.0/mtplx/constrained.py +544 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/context_copy.py +39 -2
- mtplx-2.2.0/mtplx/dashboard/_static/assets/index-COqTDxL-.js → mtplx-2.4.0/mtplx/dashboard/_static/assets/index-CRP90ECi.js +36 -36
- mtplx-2.4.0/mtplx/dashboard/_static/assets/index-DYvLRZ33.css +1 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/dashboard/_static/index.html +2 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/deepseek_mtp_patch.py +29 -1
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/engine_session.py +77 -5
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/gdn_capture.py +895 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/generation.py +1141 -161
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/graphbank.py +23 -8
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/hf_loader.py +173 -5
- mtplx-2.4.0/mtplx/hy_v3_mtp_patch.py +355 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernel_selfcheck.py +275 -1
- mtplx-2.4.0/mtplx/kernels/a3b_whole_moe.py +2673 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/fused_norm.py +116 -3
- mtplx-2.4.0/mtplx/kernels/laguna_decode.py +1224 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kv_quant.py +19 -12
- mtplx-2.4.0/mtplx/laguna_compiled_step.py +829 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/loop_guard.py +16 -3
- mtplx-2.4.0/mtplx/metadata_scrub.py +125 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/mimo_mtp_patch.py +30 -1
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/model_catalog.py +17 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/model_scheduler.py +28 -2
- mtplx-2.4.0/mtplx/models/__init__.py +1 -0
- mtplx-2.4.0/mtplx/models/laguna.py +529 -0
- mtplx-2.4.0/mtplx/models/laguna_config.py +299 -0
- mtplx-2.4.0/mtplx/models/laguna_fused.py +1336 -0
- mtplx-2.4.0/mtplx/moe_packed_projections.py +396 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/mtp_patch.py +9 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/nemotron_h_mtp_patch.py +26 -1
- mtplx-2.4.0/mtplx/optimization_profiles.py +222 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/profiles.py +3 -0
- mtplx-2.4.0/mtplx/progress_heartbeat.py +23 -0
- mtplx-2.4.0/mtplx/proj_quant.py +156 -0
- mtplx-2.4.0/mtplx/qwen_row_owned_router.py +678 -0
- mtplx-2.4.0/mtplx/ragged_attention.py +105 -0
- mtplx-2.4.0/mtplx/ragged_kv_cache.py +557 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/reasoning_codecs.py +1 -1
- mtplx-2.4.0/mtplx/roofline_profile.py +270 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/runtime.py +463 -28
- mtplx-2.4.0/mtplx/runtime_options.py +210 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/dashboard_state.py +10 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/omlx_bridge/tool_calling.py +122 -3
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/openai.py +1127 -101
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/session_bank.py +8 -4
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/thermal.py +253 -32
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/thermal_sidecar.py +12 -5
- mtplx-2.4.0/mtplx/thinking_guard.py +442 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/version.py +2 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/PKG-INFO +23 -3
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/SOURCES.txt +60 -2
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/requires.txt +2 -1
- {mtplx-2.2.0 → mtplx-2.4.0}/pyproject.toml +6 -2
- mtplx-2.4.0/scripts/code_eval_gate.py +706 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/pillar_gate_qa.py +25 -12
- mtplx-2.4.0/scripts/session_forensics.py +439 -0
- mtplx-2.4.0/scripts/walltime-lab/run_project.py +227 -0
- mtplx-2.4.0/tests/test_a3b_compiled_target_prefix.py +769 -0
- mtplx-2.4.0/tests/test_a3b_whole_moe.py +1584 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_artifacts.py +312 -0
- mtplx-2.4.0/tests/test_batched_decode.py +1197 -0
- mtplx-2.4.0/tests/test_bracket_tool_rescue.py +69 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_cache_state.py +198 -0
- mtplx-2.4.0/tests/test_code_eval.py +259 -0
- mtplx-2.4.0/tests/test_code_eval_gate.py +547 -0
- mtplx-2.4.0/tests/test_compile_state.py +46 -0
- mtplx-2.4.0/tests/test_compiled_ar_wiring.py +116 -0
- mtplx-2.4.0/tests/test_compiled_forward.py +139 -0
- mtplx-2.4.0/tests/test_constrained.py +739 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_context_copy_stats.py +107 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_dashboard_endpoints.py +15 -0
- mtplx-2.4.0/tests/test_env_flag_parsing.py +346 -0
- mtplx-2.4.0/tests/test_gdn_postconv_fusion.py +503 -0
- mtplx-2.4.0/tests/test_gdn_postconv_impl_gate.py +228 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_generation_sustained.py +132 -4
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_graphbank_compiled_verify.py +417 -8
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_hf_loader.py +165 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_hy_v3_mtp_backend.py +36 -5
- mtplx-2.4.0/tests/test_hy_v3_mtp_graft.py +209 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_kernel_selfcheck.py +150 -1
- mtplx-2.4.0/tests/test_laguna_compiled_step.py +1189 -0
- mtplx-2.4.0/tests/test_laguna_fused.py +1179 -0
- mtplx-2.4.0/tests/test_laguna_model.py +1122 -0
- mtplx-2.4.0/tests/test_metadata_scrub.py +153 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_metal_memory_caps.py +94 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_model_catalog.py +4 -4
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_model_scheduler.py +25 -0
- mtplx-2.4.0/tests/test_moe_force_unsorted.py +293 -0
- mtplx-2.4.0/tests/test_moe_packed_projections.py +353 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_mtp_patch.py +72 -0
- mtplx-2.4.0/tests/test_mtp_payload_guards.py +65 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_no_mlx_imports.py +78 -19
- mtplx-2.4.0/tests/test_omlx_bridge.py +334 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_openai_bridge.py +6 -4
- mtplx-2.4.0/tests/test_optimization_profiles.py +63 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_postcommit_prefix_reuse.py +6 -4
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_postcommit_wait_integration.py +58 -0
- mtplx-2.4.0/tests/test_proj_quant.py +107 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_public_cli.py +339 -1
- mtplx-2.4.0/tests/test_qwen_row_owned_router.py +578 -0
- mtplx-2.4.0/tests/test_ragged_kv_cache.py +760 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_reasoning_stream_split.py +23 -1
- mtplx-2.4.0/tests/test_runtime_kpis.py +136 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_server_openai.py +686 -20
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_session_bank.py +22 -0
- mtplx-2.4.0/tests/test_snapshot_free_rejection_repair.py +123 -0
- mtplx-2.4.0/tests/test_stream_guard_env.py +50 -0
- mtplx-2.4.0/tests/test_stream_stall_watchdog.py +66 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_thermal.py +235 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_thermal_sidecar.py +25 -0
- mtplx-2.4.0/tests/test_thinking_guard.py +275 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_tool_aware_stream_translator.py +73 -4
- mtplx-2.4.0/tests/test_tool_nested_args_streaming.py +363 -0
- mtplx-2.2.0/mtplx/dashboard/_static/assets/index-BYd4MFty.css +0 -1
- mtplx-2.2.0/mtplx/hy_v3_mtp_patch.py +0 -165
- mtplx-2.2.0/mtplx/runtime_options.py +0 -88
- mtplx-2.2.0/tests/test_omlx_bridge.py +0 -139
- mtplx-2.2.0/tests/test_runtime_kpis.py +0 -64
- {mtplx-2.2.0 → mtplx-2.4.0}/CITATION.cff +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/LICENSE +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/MANIFEST.in +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/adaptive.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/app_settings.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/attention_context.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/attention_split.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/deepseek_mtp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/gemma4_assistant.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/glm_mtp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/mimo_mtp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/nemotron_h_mtp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/qwen3_next.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/backends/step3p5_mtp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/batching/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/batching/admission.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/batching/buckets.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/batching/scheduler.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/batching/state.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/aime_2026.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/calibration_coding.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/default.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/flappy.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/long_code.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/long_code_uncapped.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/prompts/python_modules_long.jsonl +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/aime.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/batch_equivalence.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/capture_commit_equivalence.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/competitor_baselines.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/contract_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/harness.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp1_gate.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp1_sampler_smoke.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp_adaptive.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp_chain_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp_depth_grid.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp_depth_sweep.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/mtp_tree_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/multi_qmv_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/preflight.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/runtime_smoke.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/session_bank.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/truth.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/verify_profile.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/verify_qmm_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/runners/verify_ratio.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/schema.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/validators/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/validators/aime.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/benchmarks/validators/basic.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/block_attention.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/cache_bank/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/cache_bank/codec.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/cache_bank/cold_tier.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/chat_encoding.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/commands/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/commands/forge.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/compressed_tensors.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/config.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/constants.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/correctors/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/correctors/diagonal_affine.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/correctors/low_rank.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/daemon_client.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/dashboard/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/default_models.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/diagnostics.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/draft_lm_head.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/draft_sampling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/env.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/errors.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/expert_layout.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/fan_mode.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/fast_sampling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/gemma4_pair.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/glm_mtp_patch.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/hardware.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/copy_leaf.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/lm_head_topk.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/logits_topk.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/native_gdn_tail.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/sdpa_2pass.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/sdpa_2pass_paged.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/sdpa_2pass_paged_q8.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/sdpa_gqa_packed.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kernels/verify_mlp_fused.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kpi/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kpi/reference_vllm.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/kpi/runtime_kpis.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/mtp_activation_stats.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/mtp_adapters.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/native_mlp.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/nax_verify.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/opencode.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/pi.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/prefill_bench.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/proposal_reranker.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/qwen3_5_mtp_patch.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/sampling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/omlx_bridge/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/omlx_bridge/adapter.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server/omlx_bridge/thinking.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/server_urls.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/speculative.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/step3p5_mtp_patch.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/swival.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/templates/qwen36_froggeric_v19/chat_template.jinja +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/templates/qwen36_froggeric_v21_3/chat_template.jinja +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/trace_parity.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/turboquant.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/banner.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/chat_printer.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/download_progress.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/onboarding.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/panels.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/ui/progress.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/verify_kernels.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/verify_qmv.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/vision/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/vision/processing.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/vision/qwen3_vl_tower.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx/vision/splice.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/dependency_links.txt +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/entry_points.txt +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/mtplx.egg-info/top_level.txt +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/agent_user_path_qa.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/aime_serve_gate.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/aime_shape_memory_bench.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/collect_mtp_activation_stats.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/collect_mtp_hidden_calib.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/combine_mtp_adapters.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/compiled_verify_exactness.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/convert_step37_to_mtplx_step3p5.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/eval_mtp_corrector.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/filter_mtp_adapter.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/fp16_turbo_exactness_20260707.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/fresh_venv_smoke.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/hygiene_scan.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/install_macos.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/install_preview_global.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/kvcache_exactness_audit_20260703.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/kvcache_soak_20260703.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/kvcache_warm_probe_20260703.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/make_fp16_precision_sibling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/midform_gate.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/abba_final.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/accept_depth_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/arm_runner.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/forward_depth_bisect.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/longgen_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/loop_degradation_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/paired_longgen.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/sdpa_microbench.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/ocspeed-20260703/snapshot_tail.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/opencode_concurrency_qa.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/phase0h_paged_verifier_exactness.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/probe_mlx_pr3026_qsdpa.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/probe_mx_compile_buckets.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/probe_paged_gqa_sdpa_routes.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/candidate_truecold_20260703.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/cold_pair_recheck.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/competitors_20260703.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/decode_gap_matrix.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/hermes_pty_driver.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/omlx_probe.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/pi_pty_driver.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/pillar_ab_20260703.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/prodqa-20260703/tool_gauntlet_20260703.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/quality_fp16_parent_logitdiff_20260707.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/r1_chisquare_verifier_correctness.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/release_macos_v1.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/run_context_degradation_diagnostics.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/serve_openai_mtplx.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/session_cache_followup_qa.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/sparkle_rehearsal_kit.sh +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/step_acceptance.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/step_smoke.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/train_mtp_adapter_c4.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/scripts/validate_step_mtp_injector.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/setup.cfg +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_adaptive.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_aime_serve_gate.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_ar_batch_penalties.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_attention_split.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_background_warmup.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_batching_foundation.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_cache_bank.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_cli_parity_tools.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_cold_tier_write_budget.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_compressed_tensors.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_config.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_config_profile_precedence.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_context_degradation_profiles.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_correctors.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_daemon_client.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_default_models.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_device_draft_core.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_diagnostics.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_download_progress.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_draft_lm_head.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_engine_session_concurrency.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_engine_session_env.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_fast_sampling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_forge_cli.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_gdn_boundary_retention.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_generation_store_on_prefill.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_hygiene_scan.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_idle_postcommit_subagent.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_lazy_snapshot_cow.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_loop_guard.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_max_idle_watchdog.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_max_lifecycle.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_memory_pressure_guard.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_midform_gate.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_mtp_activation_stats.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_mtp_adapters.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_mtp_alias_load_path.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_mtp_depth_sweep.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_nax_verify.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_onboarding.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_opencode.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_orphan_tool_markup.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_penalties.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_penalty_request_wiring.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_persistent_replay.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_phase0h_paged_verifier_exactness.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_policy_fingerprint_stability.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_postcommit_resolve_for_request.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_postcommit_tools_plumbing.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_postcommit_wait.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_prefill_bench.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_prefill_chunk_defaults.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_prefill_tps_regression.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_profiles.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_prompt_encoding.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_qwen3_5_mtp_backend.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_sampling.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_scoped_reasoning_history.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_sdpa_gqa_packed.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_session_bank_env_caps.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_ssd_boundary_repersist.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_step3p5_mtp_patch.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_sustained_long_context_qa.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_trace_parity.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_turboquant.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_turboquant_fallback.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_ui_progress.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_validators.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_vision_session_cache.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_vision_tower.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/tests/test_vllm_reference.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/README.md +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/__init__.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/build.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/constants.py +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/copy_blocks.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/float8.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/gather_kv_cache.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/kv_scale_update.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/pagedattention.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/reshape_and_cache.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v1/utils.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/copy_blocks.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/float8.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/gather_kv_cache.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/gdn_linear_attention.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/kv_scale_update.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/pagedattention.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/reshape_and_cache.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/turboquant.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/kernels_v2/utils.metal +0 -0
- {mtplx-2.2.0 → mtplx-2.4.0}/vllm_metal/metal/paged_ops.cpp +0 -0
|
@@ -4,6 +4,195 @@ All notable user-facing changes to MTPLX. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [2.4.0] - 2026-07-31
|
|
8
|
+
|
|
9
|
+
The 35B speed release: the 35B-A3B MoE gets a compiled decode stack and
|
|
10
|
+
continuous batched serving, the 2.3.0 fan regression is root-caused and
|
|
11
|
+
fixed, tool calling gets another round of contract hardening, and
|
|
12
|
+
structured output can no longer be eaten by an unbounded reasoning
|
|
13
|
+
prelude. Four community contributors landed code in this release.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- 35B-A3B compiled decode stack: target-prefix compiled route, whole-MoE
|
|
18
|
+
fusion, GDN post-conv fusion, and a row-owned router (David Tai, #174).
|
|
19
|
+
- Continuous batched serving for the A3B lane: fixed-shape cohorts,
|
|
20
|
+
ragged KV, fold-in repair, and AR row-packing (David Tai, #200).
|
|
21
|
+
- Laguna S-2.1 support (exact-pin oQ4e, AR-only) with an app catalog
|
|
22
|
+
entry, plus a Poolside `arg_key`/`arg_value` tool-call dialect parser
|
|
23
|
+
(David Tai, #195).
|
|
24
|
+
- Hy3 295B full-residency lane and generic MTP draft-contract hardening
|
|
25
|
+
whose loud recurrent-cache failure also caught a real bug on the Qwen
|
|
26
|
+
lane (David Tai, #208).
|
|
27
|
+
- `/health` now reports smart-fan restore state (`restore_verified`,
|
|
28
|
+
`restore_failures`, `stale_leases_reconciled`) so stuck-fan reports
|
|
29
|
+
are diagnosable from the field (#201).
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Fans no longer stay pinned at max after a request ends (#201). A
|
|
34
|
+
failed fan restore was logged once and then treated as restored, so
|
|
35
|
+
the hardware stayed ramped while the server believed it was clean;
|
|
36
|
+
restores now verify the fan rows are back on the Apple auto curve and
|
|
37
|
+
retry with backoff until they are. The ThermalForge daemon-socket
|
|
38
|
+
restore path no longer trusts the daemon's "ok" reply without
|
|
39
|
+
verifying, and falls back to the CLI in the same call. A stale-lease
|
|
40
|
+
watchdog drops any fan lease held while the engine has been
|
|
41
|
+
continuously idle (default 120s, `MTPLX_SMART_FAN_STALE_LEASE_S`).
|
|
42
|
+
- A generation cut by `max_tokens` mid-tool-call now reports
|
|
43
|
+
`finish_reason: "length"` instead of `"tool_calls"`, so agent clients
|
|
44
|
+
continue the turn instead of executing a truncated call (#196, #197
|
|
45
|
+
layers one and two).
|
|
46
|
+
- The think-splitter no longer leaks reasoning into visible content when
|
|
47
|
+
the text contains bare `function=` or `parameter=` strings (#196/#197
|
|
48
|
+
companion fix).
|
|
49
|
+
- Streaming tool-call parsing handles bracket-style dialects with a
|
|
50
|
+
balanced string/escape-aware scanner, buffers incomplete calls instead
|
|
51
|
+
of double-delivering them, and passes through calls to undeclared
|
|
52
|
+
tools per the OpenAI contract instead of dropping them (David Tai,
|
|
53
|
+
#195).
|
|
54
|
+
- Constrained generation bounds the `<think>` prelude at 4000 characters
|
|
55
|
+
(`MTPLX_THINK_PRELUDE_MAX_CHARS`, 0 restores unbounded), so an
|
|
56
|
+
unclosed think block can no longer consume the entire token budget and
|
|
57
|
+
return no document (Jozef Kristek, #213).
|
|
58
|
+
- Forge model probes recover from slow Hugging Face config responses:
|
|
59
|
+
30s timeout, pinned-SHA retry, positive-MTP-only indexed acceptance,
|
|
60
|
+
and revision-string validation (Philip John Basile, #210).
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- Dependency bumps: pillow 12.3.0, actions/checkout 7.0.1,
|
|
65
|
+
actions/setup-python 7.0.0, pypa/gh-action-pypi-publish 1.14.1.
|
|
66
|
+
|
|
67
|
+
## [2.3.0] - 2026-07-21
|
|
68
|
+
|
|
69
|
+
The agent reliability release: the #170 tool-argument collapse is
|
|
70
|
+
root-caused and fixed, structured output ships with full speculative
|
|
71
|
+
speed (community-contributed), agent sessions keep their warm cache
|
|
72
|
+
through client history rewrites, and eight findings from an independent
|
|
73
|
+
source review of v2.2.0 are fixed, each with a regression test that
|
|
74
|
+
fails on the pre-fix code.
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
|
|
78
|
+
- Agent tool calls with nested arguments no longer collapse to empty `{}`
|
|
79
|
+
arguments (#170). The streaming Qwen-XML tool parser silently discarded
|
|
80
|
+
function-body text that was not wrapped in `<parameter=>` blocks, so a
|
|
81
|
+
model that wrote its arguments as a JSON object inside the
|
|
82
|
+
`<function=...>` envelope — the common slip on nested `edits` arrays —
|
|
83
|
+
produced a schema-valid call with empty arguments on requiredless tools
|
|
84
|
+
and a silently vanished call otherwise. Both the streaming and the final
|
|
85
|
+
parser now accept a pure JSON-object function body as the arguments
|
|
86
|
+
payload, and every unwrapped, lead, or trailing text lane is a loud
|
|
87
|
+
protocol fallback with identical contracts in the two parsers.
|
|
88
|
+
- The injected tool contract no longer shows degenerate `[]` examples for
|
|
89
|
+
array parameters: exemplars are populated from the item schema's own
|
|
90
|
+
keys (an `edits` array renders as
|
|
91
|
+
`[{"search": "ARGUMENT_VALUE", "replace": "ARGUMENT_VALUE"}]`), removing
|
|
92
|
+
an in-prompt template for empty-array emissions.
|
|
93
|
+
- The final tool-call extraction lane (non-stream parsing and the stream
|
|
94
|
+
fallback) no longer fabricates `{}`-argument calls out of function bodies
|
|
95
|
+
it could not read — live-reproduced on v2.2.0 as a `grep` call arriving
|
|
96
|
+
with empty arguments. All extraction dialects now share the strict
|
|
97
|
+
parsers' contract: a pure JSON-object function body is the arguments
|
|
98
|
+
payload, an unreadable body stays visible content, blank-body no-argument
|
|
99
|
+
calls still parse, and partial arguments are delivered exactly as the
|
|
100
|
+
model wrote them (schema validation remains the client's job, per the
|
|
101
|
+
OpenAI protocol).
|
|
102
|
+
- Context-copy speculative rounds now stop accepting at the first
|
|
103
|
+
accepted stop token, exactly like the MTP acceptance loop. Previously
|
|
104
|
+
the copy lane could accept an entire block past a stop, leaving the
|
|
105
|
+
target cache, logits/hidden selection, and MTP history advanced beyond
|
|
106
|
+
the emitted response while the final state was still marked safe to
|
|
107
|
+
commit — a session-cache poisoning risk on recurrent (GDN) models.
|
|
108
|
+
- Context-copy is prompt-only again at the boundary: proposal blocks are
|
|
109
|
+
sliced from the prompt and capped at its edge instead of running into
|
|
110
|
+
the model's own generated output (the self-repetition case the feature
|
|
111
|
+
contract excludes). Boundary-less candidates are skipped inside the
|
|
112
|
+
n-gram index so the best *valid* match still fires.
|
|
113
|
+
- Non-divisor packed MTP quantization widths (5-bit, 3-bit, 6-bit) now
|
|
114
|
+
infer the correct group size via total-bit arithmetic (#182; fix by
|
|
115
|
+
@Jonathangadeaharder in #183). A 5-bit group-64 head previously
|
|
116
|
+
inferred group 60, overwrote the artifact's correct declared contract,
|
|
117
|
+
and made the model unloadable.
|
|
118
|
+
- Long-running daemons no longer accumulate unbounded telemetry: the
|
|
119
|
+
SessionBank eviction log is a bounded ring, the scheduler's
|
|
120
|
+
started-by-batch-key counter collapses per-session key suffixes to
|
|
121
|
+
stable classes, the dashboard per-session TPS map is LRU-bounded, and
|
|
122
|
+
the OpenCode title fast path trims request metrics like every other
|
|
123
|
+
lane (#145-adjacent slow-creep hygiene).
|
|
124
|
+
- The desktop Hugging Face probe now recognizes rootless assistant-pair
|
|
125
|
+
bundles (`mtplx_pair.json` + `target/config.json`) the same way the
|
|
126
|
+
Python runtime does, so the official Gemma4 pair repos classify as
|
|
127
|
+
ready to download instead of unreadable (#107); Forge routes them to
|
|
128
|
+
install-instead-of-rebuild.
|
|
129
|
+
- `mtplx doctor --json` stdout is now guaranteed machine-parseable: the
|
|
130
|
+
report is built with stdout routed to stderr, so third-party lazy
|
|
131
|
+
importers that print() their errors (huggingface_hub does, whenever its
|
|
132
|
+
HTTP dependencies are broken or split across install locations) can no
|
|
133
|
+
longer prefix the JSON document with prose and break `--json` consumers.
|
|
134
|
+
- Agent tool-loop sessions no longer lose their warm cache when the
|
|
135
|
+
client rewrites history (transcript compaction, retroactive tool-result
|
|
136
|
+
digests): a common-prefix identity fallback (≥4096 shared tokens and
|
|
137
|
+
≥25% of the prompt) keeps the session id instead of minting an
|
|
138
|
+
anonymous one, ending the cold full-context re-prefills those
|
|
139
|
+
rotations caused mid-session.
|
|
140
|
+
- Fan restore goes through the ThermalForge daemon socket instead of the
|
|
141
|
+
app-killing CLI path, and `mtplx pull` detects interrupted downloads
|
|
142
|
+
as incomplete instead of treating them as ready (thanks @titan550,
|
|
143
|
+
#178/#179/#180/#181).
|
|
144
|
+
|
|
145
|
+
### Changed
|
|
146
|
+
|
|
147
|
+
- `parallel_tool_calls` is now honored: a request that declares it gets
|
|
148
|
+
the declared behavior in both directions (false → at most one tool
|
|
149
|
+
call per turn), with the previous client-profile heuristic kept only
|
|
150
|
+
as the fallback when the field is absent (thanks @PhilipJohnBasile,
|
|
151
|
+
#190 — Android Studio declares false today and was being ignored).
|
|
152
|
+
- Agent tool contract v13: instructs whole-file reads (the old
|
|
153
|
+
"smallest read range" clause provoked storms of 1-to-5-line
|
|
154
|
+
micro-reads) and forbids echoing file contents into visible text
|
|
155
|
+
(double-emitted file bodies inflated agent turns by tens of
|
|
156
|
+
thousands of characters). Measured on live agent sessions: thinking
|
|
157
|
+
share of generated tokens 75% → 6-29%, double emissions eliminated.
|
|
158
|
+
|
|
159
|
+
### Added
|
|
160
|
+
|
|
161
|
+
- Structured output: `response_format` `json_object` and `json_schema`
|
|
162
|
+
are now enforced with llguidance token masks instead of silently
|
|
163
|
+
ignored — and the grammar composes with the MTP verify loop, so
|
|
164
|
+
constrained requests keep full speculative speed (measured: decode
|
|
165
|
+
parity within noise, under 5ms total mask cost per request). On
|
|
166
|
+
thinking templates a prelude grammar lets reasoning finish before the
|
|
167
|
+
document is forced. Opt-in strict tool-call grammars
|
|
168
|
+
(`MTPLX_TOOL_CALL_STRICT=1`) force every tool call to a declared tool
|
|
169
|
+
name with schema-valid arguments — a real OpenCode session built a
|
|
170
|
+
complete project through the strict lane with zero malformed calls.
|
|
171
|
+
Thanks @PhilipJohnBasile (#186, #187, #188). Requires the `[server]`
|
|
172
|
+
extra, which the desktop app installs by default; bare pip installs
|
|
173
|
+
get a clear 400 with an install hint.
|
|
174
|
+
- Durable per-request telemetry: `--request-log-jsonl` (env
|
|
175
|
+
`MTPLX_REQUEST_LOG_JSONL`) appends every request record as one JSON
|
|
176
|
+
line, and `scripts/session_forensics.py` correlates that log with an
|
|
177
|
+
OpenCode database into a single timeline with detectors for re-prefill
|
|
178
|
+
rewinds, TTFT stalls, thinking marathons, double emissions,
|
|
179
|
+
session-identity rotations, and usage mismatches.
|
|
180
|
+
- An **opt-in** agent-lane reasoning budget (`--agent-thinking-budget`,
|
|
181
|
+
env `MTPLX_THINKING_BUDGET`; OFF by default): at the budget the
|
|
182
|
+
reasoning segment is force-closed with a visible bridge so the turn
|
|
183
|
+
proceeds to its answer or tool call, and every engagement is surfaced
|
|
184
|
+
per-request in telemetry (`thinking_guard`). Below the budget decoding
|
|
185
|
+
is bit-exact; plain chat is never touched.
|
|
186
|
+
- Stream stall watchdog (#86 containment): if a stream receives nothing
|
|
187
|
+
while the model owner's progress heartbeat is frozen for
|
|
188
|
+
`MTPLX_STREAM_STALL_DEADLINE_S` (default 300s, 0 disables), the
|
|
189
|
+
request fails with a structured, diagnosable error and releases its
|
|
190
|
+
slot instead of hanging forever. Healthy long prefills and model loads
|
|
191
|
+
tick the heartbeat and are never affected; the daemon is never killed.
|
|
192
|
+
- `pip install mtplx` now includes Pillow, matching the advertised image
|
|
193
|
+
support in the app and server (#103); previously vision failed at
|
|
194
|
+
import unless the `[server]` extra was installed.
|
|
195
|
+
|
|
7
196
|
## [2.2.0] - 2026-07-19
|
|
8
197
|
|
|
9
198
|
The copy-drafting and small-Mac release. Decoding: context-copy
|
|
@@ -20,3 +20,7 @@ not include or depend on the vLLM serving stack.
|
|
|
20
20
|
This product includes Metal kernel code adapted from dflash-mlx
|
|
21
21
|
(https://github.com/bstnxbt/dflash-mlx), Copyright dflash-mlx contributors,
|
|
22
22
|
licensed under the Apache License 2.0. See mtplx/nax_verify.py for details.
|
|
23
|
+
|
|
24
|
+
This product includes the Apache-2.0 licensed MLX implementation for
|
|
25
|
+
Laguna-S-2.1 from PipeNetwork, Copyright 2026 PipeNetwork, under
|
|
26
|
+
mtplx/models/laguna.py.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mtplx
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Native MTP speculative decoding for Qwen3-Next on Apple Silicon.
|
|
5
5
|
Author-email: Youssof Altoukhi <business@youssofal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,6 +25,7 @@ License-File: LICENSE
|
|
|
25
25
|
License-File: NOTICE
|
|
26
26
|
Requires-Dist: fastapi>=0.136
|
|
27
27
|
Requires-Dist: huggingface-hub>=0.36
|
|
28
|
+
Requires-Dist: pillow>=10
|
|
28
29
|
Requires-Dist: mlx<0.33,>=0.31; sys_platform == "darwin" and platform_machine == "arm64"
|
|
29
30
|
Requires-Dist: mlx-lm<0.32,>=0.31; sys_platform == "darwin" and platform_machine == "arm64"
|
|
30
31
|
Requires-Dist: transformers!=5.13.0,<5.14; sys_platform == "darwin" and platform_machine == "arm64"
|
|
@@ -38,7 +39,7 @@ Provides-Extra: competitors
|
|
|
38
39
|
Requires-Dist: dflash-mlx==0.1.0; extra == "competitors"
|
|
39
40
|
Provides-Extra: server
|
|
40
41
|
Requires-Dist: fastapi>=0.136; extra == "server"
|
|
41
|
-
Requires-Dist:
|
|
42
|
+
Requires-Dist: llguidance>=1.7; extra == "server"
|
|
42
43
|
Requires-Dist: uvicorn>=0.46; extra == "server"
|
|
43
44
|
Provides-Extra: dev
|
|
44
45
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
@@ -153,7 +154,26 @@ Fan-backed modes restore your fans to automatic if MTPLX dies for any reason, in
|
|
|
153
154
|
|
|
154
155
|
## Compatibility, honestly
|
|
155
156
|
|
|
156
|
-
`mtplx inspect` classifies
|
|
157
|
+
`mtplx inspect` classifies models before anything runs: verified, architecture-compatible but unverified, AR-only, incompatible architecture, or no MTP heads at all. Unverified models refuse to run unless you explicitly force them. There are no silent fallbacks: if MTPLX cannot run a model correctly, it tells you instead of running it badly.
|
|
158
|
+
|
|
159
|
+
[Laguna-S-2.1 oQ4e](https://huggingface.co/mlx-community/Laguna-S-2.1-oQ4e) is supported through its exact MLX architecture in target-only AR mode:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
mtplx start cli \
|
|
163
|
+
--model mlx-community/Laguna-S-2.1-oQ4e \
|
|
164
|
+
--download \
|
|
165
|
+
--no-mtp
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
MTPLX pins that model to revision
|
|
169
|
+
`8e3f5cad513746264940c1c4195de48d7ea345a5` and verifies the 13-shard layout,
|
|
170
|
+
tokenizer, generation config, special tokens map, and Poolside chat template
|
|
171
|
+
before admitting it. The checkpoint has no native MTP head, so an MTP launch is
|
|
172
|
+
rejected before weights load instead of falling back during execution. The
|
|
173
|
+
weights occupy 59.72 GiB (64.13 GB); use a Mac with at least 96 GiB unified
|
|
174
|
+
memory (128 GiB is recommended). MTPLX defaults Laguna to a 32,768-token context
|
|
175
|
+
and response cap, and checks larger explicit server contexts against the active
|
|
176
|
+
Metal memory cap.
|
|
157
177
|
|
|
158
178
|
## What MTPLX is not
|
|
159
179
|
|
|
@@ -104,7 +104,26 @@ Fan-backed modes restore your fans to automatic if MTPLX dies for any reason, in
|
|
|
104
104
|
|
|
105
105
|
## Compatibility, honestly
|
|
106
106
|
|
|
107
|
-
`mtplx inspect` classifies
|
|
107
|
+
`mtplx inspect` classifies models before anything runs: verified, architecture-compatible but unverified, AR-only, incompatible architecture, or no MTP heads at all. Unverified models refuse to run unless you explicitly force them. There are no silent fallbacks: if MTPLX cannot run a model correctly, it tells you instead of running it badly.
|
|
108
|
+
|
|
109
|
+
[Laguna-S-2.1 oQ4e](https://huggingface.co/mlx-community/Laguna-S-2.1-oQ4e) is supported through its exact MLX architecture in target-only AR mode:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
mtplx start cli \
|
|
113
|
+
--model mlx-community/Laguna-S-2.1-oQ4e \
|
|
114
|
+
--download \
|
|
115
|
+
--no-mtp
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
MTPLX pins that model to revision
|
|
119
|
+
`8e3f5cad513746264940c1c4195de48d7ea345a5` and verifies the 13-shard layout,
|
|
120
|
+
tokenizer, generation config, special tokens map, and Poolside chat template
|
|
121
|
+
before admitting it. The checkpoint has no native MTP head, so an MTP launch is
|
|
122
|
+
rejected before weights load instead of falling back during execution. The
|
|
123
|
+
weights occupy 59.72 GiB (64.13 GB); use a Mac with at least 96 GiB unified
|
|
124
|
+
memory (128 GiB is recommended). MTPLX defaults Laguna to a 32,768-token context
|
|
125
|
+
and response cap, and checks larger explicit server contexts against the active
|
|
126
|
+
Metal memory cap.
|
|
108
127
|
|
|
109
128
|
## What MTPLX is not
|
|
110
129
|
|