{"repo": "asher/gmlx", "files": {"gmlx/upstream_seams.py": {"3afce85b5122d36ed31555bd123028a8f8d4e558": {"t": 1786068556.8016567, "n": 29063, "h": "91aacd53712d7970", "c": "\"\"\"Contract registry for every upstream symbol gmlx patches or deep-imports.\n\ngmlx monkeypatches ~30 private symbols across mlx-vlm and mlx-lm and\ndeep-imports model internals. Those seams are guarded structurally (try/except\nImportError + idempotence flags), so upstream renames or rewrites fail\nsilently - stock behavior quietly returns, or a confusing error surfaces far\ndownstream (mlx-vlm 0.6.4 vendoring switch_layers turned into a gather_mm\nshape error at MoE prefill). This module makes the contract explicit:\n\n- ``SEAMS`` declares each (module, attr) we touch, why, and whether a missing\n seam must abort install (``critical``) or only costs an acceleration.\n- ``upstream_seams.json`` pins a source fingerprint for each seam, captured\n at the qualified upstream versions. ``tests/test_upstream_seams.py`` fails\n with the symbol's name when upstream drifts under the pin.\n- ``check_upstream_versions()`` is the runtime gate: below-floor upstream\n versions raise with an actionable message (stale venvs resolve pyproject\n constraints exactly once - a floor pin alone cannot catch them); versions\n newer than the qualified set warn once.\n\nOn a deliberate upstream bump: re-audit the drifted seams, then\n``python -m gmlx.upstream_seams --regen`` (see docs/upstream-upgrades.md).\n\"\"\"\nfrom __future__ import annotations\n\nimport hashlib\nimport importlib\nimport inspect\nimport json\nimport os\nimport re\nimport sys\nfrom dataclasses import dataclass\n\n_JSON_PATH = os.path.join(os.path.dirname(__file__), \"upstream_seams.json\")\n\n# Hard floors: below these, core wiring (switch_layers geometry, cache\n# protocol, server engine) predates what gmlx targets; refuse to run.\nFLOORS = {\n \"mlx\": \"0.31\",\n \"mlx-lm\": \"0.31\",\n \"mlx-vlm\": \"0.6.3\",\n}\n\n\n@dataclass(frozen=True)\nclass Seam:\n module: str # upstream import path\n attr: str # dotted attribute path; \"\" = module existence only\n used_by: str # our patch/import site (for the failure message)\n critical: bool = False # True: a missing seam must abort, not degrade\n module_optional: bool = False # module absent on some qualified versions\n attr_optional: bool = False # attr absent on some qualified versions\n\n\nSEAMS: tuple[Seam, ...] = (\n # --- batched serve scheduler + ragged decode (batch_sched / ragged_decode) ---\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator._next\",\n \"batch_sched.install_decode_priority_sched (decode-first tick, \"\n \"prompt-arm structure, _prompt_time_counter contract)\",\n critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator.insert\",\n \"batch_sched arrival-merge (_unprocessed_sequences append/rebind)\"),\n # --- qwen3_5 owned forwards (qwen35_owned/gdn/attn/layers/rope/\n # verify_linear) ---\n # The owned qwen3.5 forward surface carries no pins: its copies and\n # mirrors are certified by source-equality, construction-pair, and\n # identity tests. But ownership lands at construction only on the\n # text MTP load (loader._mtp_target_classes); load_vlm_mtp_model's\n # target is built stock by mlx_vlm.utils, so the multimodal path\n # still installs the patched regime and its symbols stay pinned\n # below.\n Seam(\"mlx_vlm.models.qwen3_5.gated_delta\", \"gated_delta_ops\",\n \"gdn_patches._patch_mlxvlm_gated_delta_tiled_v (stock-built \"\n \"trees only: vlm MTP targets + the GMLX_QWEN_OWNED=0 text \"\n \"fallback; owned GDN routes through mlx-lm gated_delta)\",\n critical=True),\n Seam(\"mlx_vlm.models.qwen3_5.gated_delta\", \"gated_delta_kernel\",\n \"gdn_patches._patch_mlxvlm_gated_delta_tiled_v (stock-built \"\n \"trees only)\", critical=True),\n Seam(\"mlx_vlm.models.qwen3_5.gated_delta\", \"_gated_delta_with_states_ops\",\n \"gdn_patches._patch_mlxvlm_gated_delta_tiled_v (stock-built \"\n \"trees only)\", critical=True),\n Seam(\"mlx_vlm.models.qwen3_5.gated_delta\", \"_gated_delta_state_ops\",\n \"gdn_patches._patch_mlxvlm_gated_delta_tiled_v (stock-built \"\n \"trees only)\", critical=True),\n # --- qwen3_5 stock-path verify patches (vlm MTP targets) ---\n Seam(\"mlx_vlm.models.qwen3_5.language\",\n \"_qwen3_5_ragged_decode_attention\",\n \"ragged_decode.install_unified_ragged_plan (vlm MTP stock path; \"\n \"the owned attention calls the in-tree dispatch directly)\"),\n Seam(\"mlx_vlm.models.qwen3_5.language\",\n \"_target_verify_left_padded_attention\",\n \"gdn_patches._patch_batched_verify_sdpa / qwen35_verify_fold \"\n \"(vlm MTP stock path; the owned attention carries the composed \"\n \"verify routes natively)\"),\n Seam(\"mlx_vlm.models.qwen3_5.language\", \"_target_verify_linear\",\n \"gdn_patches._patch_bf16_verify_linear (vlm MTP stock path; the \"\n \"owned verify-linear family folds the lever into its dispatch)\"),\n Seam(\"mlx_vlm.models.qwen3_5.language\", \"scaled_dot_product_attention\",\n \"qwen35_verify_fold (B>=2 left-padded fold; vlm MTP stock path \"\n \"- the owned attention folds at its own dispatch and calls the \"\n \"base module symbol)\"),\n Seam(\"mlx_vlm.models.qwen3_5.language\", \"Qwen3_5GatedDeltaNet.__call__\",\n \"gdn_patches._patch_gated_delta_fused_verify (vlm MTP stock \"\n \"path; the owned subclass carries the fused dispatch natively)\"),\n # Mirror pin: _owned_model_call deliberately diverges from this\n # body (B=1 shortcut removed, padded prefill hoisted, S=0 guard),\n # so it cannot be substitution-normalized; the fingerprint forces a\n # re-mirror review on upstream change.\n Seam(\"mlx_vlm.models.qwen3_5.language\", \"Qwen3_5Model.__call__\",\n \"qwen35_owned._owned_model_call (forward body mirrored with \"\n \"deliberate divergences; re-mirror on upstream change)\",\n critical=True),\n # --- gemma4 host-sync-free masks/offsets (gemma4_sync carries bodies).\n # Owned gemma4_text MTP trees (gemma4_owned) shadow all three rows by\n # subclass override and mirror the same bodies; the pins stay live for\n # stock-built trees (multimodal construction, GMLX_GEMMA_OWNED=0). ---\n Seam(\"mlx_vlm.models.gemma4.language\", \"Gemma4TextModel._make_masks\",\n \"gemma4_sync.install_gemma4_nosync (body carried, offset probe); \"\n \"gemma4_owned._owned_make_masks (mirror)\"),\n Seam(\"mlx_vlm.models.gemma4.language\", \"Attention.__call__\",\n \"gemma4_sync.install_gemma4_nosync (body carried, offset wrap); \"\n \"gemma4_owned._owned_attention_call (mirror)\"),\n Seam(\"mlx_vlm.models.gemma4.language\", \"scaled_dot_product_attention\",\n \"gemma4_batched_sdpa (hd512 B>1 row route; left-pad tail slices); \"\n \"gemma4_owned._sdpa_dispatch calls the claim directly\"),\n # --- quantized-KV SDPA batch-mask fix (both base modules) ---\n Seam(\"mlx_lm.models.base\", \"quantized_scaled_dot_product_attention\",\n \"quantized_sdpa_fix (5D grouped scores vs 4D batch mask)\"),\n Seam(\"mlx_vlm.models.base\", \"quantized_scaled_dot_product_attention\",\n \"quantized_sdpa_fix (same body as the mlx_lm copy)\"),\n Seam(\"mlx_vlm.models.cache\", \"BatchQuantizedKVCache.make_mask\",\n \"quantized_sdpa_fix._patch_make_mask (starts registration for \"\n \"the fused decode route; left_padding attr contract)\"),\n # --- gemma4 text-only load path (mlx_lm module wrapped in text_only) ---\n Seam(\"mlx_lm.models.gemma4_text\", \"scaled_dot_product_attention\",\n \"gemma4_batched_sdpa (same row route at the text-only seam)\"),\n Seam(\"mlx_lm.models.gemma4_text\", \"Attention.__call__\",\n \"gemma4_batched_sdpa (module-global sdpa call, cache kwarg)\"),\n Seam(\"mlx_lm.models.gemma4_text\", \"Gemma4TextModel._make_masks\",\n \"gemma4_batched_sdpa (one mask object per layer type; the \"\n \"producer->consumer pad relay keys on that identity)\"),\n # --- shared-prefix cascade decode route + APC warm-batch stamp ---\n Seam(\"mlx_lm.models.llama\", \"scaled_dot_product_attention\",\n \"cascade_sdpa (stamped shared-prefix batched decode)\"),\n Seam(\"mlx_vlm.generate.ar\", \"PromptProcessingBatch.__init__\",\n \"cascade_sdpa.install_cascade_stamp (token-prefix stamp at batch \"\n \"formation; rows + caches coexist in matching order here)\",\n critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"_extend_cache\",\n \"cascade_sdpa.install_cascade_stamp (stamp carry across the \"\n \"B=1-to-batch merge lift on admission)\", critical=True),\n # --- speculative / AR batch engine (spec_engine owns these methods) ---\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator.__init__\",\n \"spec_engine._install_apc_manager_stash\", critical=True),\n Seam(\"mlx_vlm.generate.ar\",\n \"PromptProcessingBatch._store_apc_exact_checkpoints\",\n \"spec_engine._install_ckpt_checkpoint_store (ckpt cursor rides \"\n \"the stock store)\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"PromptProcessingBatch.__init__\",\n \"spec_engine.install_full_prompt_mtp_prefill (prefill-step \"\n \"restore + stock-path ckpt arming)\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"GenerationBatch._step\",\n \"spec_engine._install_plain_ckpt_decode (token accounting + \"\n \"decode-time snapshots)\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"GenerationBatch.filter\",\n \"spec_engine._install_plain_ckpt_decode (B=1 retirement at row \"\n \"exit)\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"PromptProcessingBatch.prompt_step\",\n \"spec_engine.install_full_prompt_mtp_prefill\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"PromptProcessingBatch.generate\",\n \"spec_engine.install_full_prompt_mtp_prefill\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"SpeculativeGenerationBatch.next\",\n \"spec_engine.install_continuous_batch_admission\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"run_speculative_server_rounds\",\n \"spec_engine.install_owned_spec_engine\", critical=True),\n Seam(\"mlx_vlm.speculative.utils\", \"make_speculative_prompt_cache\",\n \"spec_engine.install_spec_kv_quant (B=1 KV_BITS)\", critical=True),\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator._apc_pick_for\",\n \"spec_engine._bind_l1_view (L1 APC helpers)\"),\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator._apc_exact_checkpoint_len\",\n \"spec_engine._bind_l1_view (L1 APC helpers)\"),\n Seam(\"mlx_vlm.generate.ar\", \"BatchGenerator._apc_extra_hash\",\n \"spec_engine._bind_l1_view (L1 APC helpers)\"),\n # --- server engine ---\n Seam(\"mlx_vlm.server.generation\", \"run_speculative_server_rounds\",\n \"spec_engine.install_owned_spec_engine\", critical=True),\n Seam(\"mlx_vlm.server.generation\", \"load_model_resources\",\n \"server_bridge_vlm (GGUF model resource loader)\", critical=True),\n Seam(\"mlx_vlm.server.generation\", \"ResponseGenerator._make_sampler\",\n \"server_patches.install_fast_sampler\"),\n Seam(\"mlx_vlm.server.generation\", \"GenerationArguments.to_template_kwargs\",\n \"server_patches (chat_template_kwargs transform)\"),\n Seam(\"mlx_vlm.server.generation\", \"ResponseGenerator._preprocess_request\",\n \"server_patches.install_retire_render_capture (ids hop + \"\n \"tokenize path for the next-turn retirement key)\"),\n Seam(\"mlx_vlm.server.openai\", \"apply_chat_template\",\n \"server_patches.install_retire_render_capture (render-context \"\n \"memo, module attr) + render.install_faithful_history (inner \"\n \"key-merge wrap)\"),\n Seam(\"mlx_vlm.server.anthropic\", \"apply_chat_template\",\n \"server_patches._common._render_target_modules (faithful \"\n \"history, retire capture, and thinking seed wrap every \"\n \"captured render binding)\"),\n Seam(\"mlx_vlm.server.app\", \"_protocol_deps\",\n \"server_patches._common._render_target_modules (deps captures \"\n \"the openai function object at namespace construction)\"),\n Seam(\"mlx_vlm.prompt_utils\", \"apply_chat_template\",\n \"server_patches.render.install_faithful_history \"\n \"(return_messages contract: one rebuilt message per readable \"\n \"input item; tool passthrough branch)\"),\n Seam(\"mlx_vlm.prompt_utils\", \"get_chat_template\",\n \"server_patches.render.install_faithful_history (owned render \"\n \"tail mirrors the stock function's)\"),\n Seam(\"mlx_vlm.server.openai\", \"_split_thinking\",\n \"retire_key.build_assistant_message (response-shape mirror)\"),\n Seam(\"mlx_vlm.server.openai\", \"process_tool_calls\",\n \"retire_key.build_assistant_message (response-shape mirror)\"),\n Seam(\"mlx_vlm.server.openai\", \"_infer_tool_parser_from_processor\",\n \"retire_key.build_assistant_message (response-shape mirror)\"),\n Seam(\"mlx_vlm.server.openai\", \"load_tool_module\",\n \"retire_key.build_assistant_message (response-shape mirror)\"),\n Seam(\"mlx_vlm.server.responses_state\",\n \"ThinkingStreamState._build_open_close_markers\",\n \"retire_key._thinking_markers (splitter default marker pairs \"\n \"for the mid-decode virtual closer)\"),\n Seam(\"mlx_vlm.server.app\", \"_split_thinking_text\",\n \"server_patches.chat_behavior.install_stream_thinking_seed \"\n \"(non-stream truncated-thinking classification, module attr \"\n \"looked up per call by app._split_thinking)\"),\n Seam(\"mlx_vlm.server.runtime\", \"runtime\",\n \"residency._RuntimeProxy wrap\", critical=True),\n Seam(\"mlx_vlm.server.app\", \"app\",\n \"server_patches route surgery / server.py uvicorn root\",\n critical=True),\n Seam(\"mlx_vlm.speculative.drafters\", \"load_drafter\",\n \"server_bridge_vlm (in-memory MTP drafter injection)\", critical=True),\n Seam(\"mlx_vlm.utils\", \"get_model_path\",\n \"server_patches (HF download gate)\", critical=True),\n Seam(\"mlx_vlm.utils\", \"StoppingCriteria.__call__\",\n \"server_patches (ignore-EOS)\"),\n # --- tool-parser registry (hy_v3_tools.ensure_registered) ---\n Seam(\"mlx_vlm.tool_parsers\", \"_TEMPLATE_MARKERS\",\n \"hy_v3_tools.ensure_registered (Hy3 marker prepend)\"),\n Seam(\"mlx_vlm.tool_parsers\", \"load_tool_module\",\n \"hy_v3_tools (sys.modules graft resolves through it)\"),\n # --- APC internals (lone-harvest patch, gmlx manager subclass, apc_pooling) ---\n Seam(\"mlx_vlm.apc\", \"harvest_blocks_from_batch_cache\",\n \"server_patches.install_apc_lone_harvest\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_clone_layer_major_kv_cache_for_apc\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_sequence_hash\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"APCExactCacheEntry\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_hash_tokens\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_DiskLayerMajorBlock\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_copy_mlx_array\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"SEED_PARENT_HASH\",\n \"apc_manager.GmlxAPCManager.store_kv_blocks\", critical=True),\n Seam(\"mlx_vlm.apc\", \"DEFAULT_BLOCK_SIZE\",\n \"apc_manager.build_apc_manager (from_env mirror)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"DEFAULT_NUM_BLOCKS\",\n \"apc_manager.build_apc_manager (from_env mirror)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"DiskBlockStore\",\n \"apc_manager.build_apc_manager (from_env mirror)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_cache_entry_supports_exact_apc\",\n \"apc_pooling (PoolingCache exact-APC predicate)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_merge_exact_cache_entries\",\n \"apc_pooling (PoolingCache merge arm)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_read_safetensors_tensor\",\n \"apc_pooling (disk-tier zero-width spill)\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_clone_cache_entry_for_apc\",\n \"apc_pooling\", critical=True),\n Seam(\"mlx_vlm.apc\", \"_safetensors_dtype_info\",\n \"apc_pooling\", critical=True),\n # <= 0.6.3 the wrapper delegates to this mlx-lm alias; 0.6.4 inlined it.\n Seam(\"mlx_vlm.generate.common\", \"mlx_maybe_quantize_kv_cache\",\n \"apc_pooling (rotating-safe KV-quant replacement, <=0.6.3 arm)\",\n critical=True, attr_optional=True),\n Seam(\"mlx_vlm.generate\", \"maybe_quantize_kv_cache\",\n \"apc_pooling (rotating-safe KV-quant replacement)\", critical=True),\n # --- cache classes (dual-origin via gmlx.cache_compat; on <= 0.6.3\n # the vlm module re-exports mlx-lm's classes, so these fingerprint the\n # same source) ---\n Seam(\"mlx_vlm.models.cache\", \"KVCache\",\n \"cache_compat (ckpt sidecar tails, snapshots)\", critical=True),\n Seam(\"mlx_vlm.models.cache\", \"RotatingKVCache\",\n \"cache_compat (ds4 make_cache, rollback attach, spec_helpers)\",\n critical=True),\n Seam(\"mlx_vlm.models.cache\", \"CacheList\",\n \"cache_compat (ds4 make_cache, prefix_cache snapshots)\",\n critical=True),\n Seam(\"mlx_vlm.models.cache\", \"ArraysCache\",\n \"cache_compat (ckpt_supported, prefix_cache snapshots)\"),\n Seam(\"mlx_vlm.models.cache\", \"BatchKVCache\",\n \"mtp_drafter / cache_snapshot row round-trip\"),\n Seam(\"mlx_vlm.models.cache\", \"BatchRotatingKVCache\",\n \"cache_compat (rollback attach, safe KV-quant exclusion)\"),\n Seam(\"mlx_vlm.models.cache\", \"BufferedRotatingKVCache\",\n \"spec_helpers rollback-slack wrap\", critical=True),\n Seam(\"mlx_vlm.models.cache\", \"make_prompt_cache\",\n \"chat MTP cache construction\", critical=True),\n # 0.6.4 replaced the runtime's model_cache dict with a registry;\n # residency and the wire tests speak both shapes.\n Seam(\"mlx_vlm.server.runtime\", \"ModelCacheRegistry\",\n \"residency pool / test_wire_contract fake loader\",\n attr_optional=True),\n # --- vendored switch_layers (exists only on mlx-vlm >= 0.6.4) ---\n Seam(\"mlx_vlm.models.switch_layers\", \"SwitchLinear.__call__\",\n \"modules.switch_layer_types (dual-origin leaf swap)\",\n critical=True, module_optional=True),\n Seam(\"mlx_vlm.models.switch_layers\", \"SwitchGLU.__call__\",\n \"modules.switch_layer_types (dual-origin fused GLU)\",\n critical=True, module_optional=True),\n # --- mlx-lm seams ---\n Seam(\"mlx_lm.models.switch_layers\", \"SwitchLinear.__call__\",\n \"modules leaf swap + fused subclass signature contract\",\n critical=True),\n Seam(\"mlx_lm.models.switch_layers\", \"SwitchGLU.__call__\",\n \"modules.install_fused_moe_glu / loader.install_expert_streaming\",\n critical=True),\n Seam(\"mlx_lm.server\", \"ModelProvider._load\",\n \"server_bridge_lm (GGUF ModelProvider)\", critical=True),\n Seam(\"mlx_lm.generate\", \"maybe_quantize_kv_cache\",\n \"apc_pooling\", critical=True),\n Seam(\"mlx_lm.models.cache\", \"RotatingKVCache\",\n \"rotating_cache_fix / prefix_cache snapshots\"),\n Seam(\"mlx_lm.models.base\", \"create_causal_mask\", \"rotating_cache_fix\"),\n Seam(\"mlx_lm.models.hunyuan\", \"MoeBlock\",\n \"loader._patch_hunyuan_norm_topk\"),\n Seam(\"mlx_lm.models.deepseek_v32\", \"MoEGate\",\n \"dsv32_patches (fp32 router patch)\"),\n # --- kimi_k3 vendored-module imports (kimi_k3_model) ---\n # The vendored Kimi-K3 class reuses mlx-lm's per-key-channel-decay\n # gated-delta scan (KDA's exact recurrence), the kimi_linear ShortConv1d\n # semantics (reimplemented in-module; the class itself is not imported),\n # and the MLA MultiLinear (absorbed embed_q/unembed_out).\n Seam(\"mlx_lm.models.gated_delta\", \"gated_delta_kernel\",\n \"kimi_k3_model.KimiK3DeltaAttention (metal scan dispatch)\",\n critical=True),\n Seam(\"mlx_lm.models.gated_delta\", \"gated_delta_ops\",\n \"kimi_k3_model.KimiK3DeltaAttention (CPU/fallback scan)\",\n critical=True),\n Seam(\"mlx_lm.models.mla\", \"MultiLinear\",\n \"kimi_k3_model.KimiK3MLAAttention (embed_q/unembed_out -> \"\n \"KQuantMultiLinear)\", critical=True),\n Seam(\"mlx_lm.models.kimi_linear\", \"ShortConv1d\",\n \"kimi_k3_model.ShortConv1d (semantics mirror; re-mirror review \"\n \"on upstream change)\"),\n)\n\n\ndef _resolve(seam: Seam):\n \"\"\"('ok', obj) | ('missing-module', None) | ('missing-attr', None).\n\n Modules resolve through import; ``sys.modules`` wins for already-loaded\n ones, which matters for e.g. mlx_vlm.server.runtime (the package\n __init__ shadows the submodule attribute with the runtime instance).\n \"\"\"\n try:\n mod = sys.modules.get(seam.module) or importlib.import_module(\n seam.module)\n except ImportError:\n return \"missing-module\", None\n obj = mod\n for part in seam.attr.split(\".\") if seam.attr else ():\n try:\n obj = getattr(obj, part)\n except AttributeError:\n return \"missing-attr\", None\n return \"ok\", obj\n\n\ndef _fingerprint(obj) -> str | None:\n \"\"\"sha256 of the object's source, or None when unhashable (constants,\n kernel objects, module-level values).\"\"\"\n try:\n src = inspect.getsource(obj)\n except (TypeError, OSError):\n return None\n return hashlib.sha256(src.encode()).hexdigest()\n\n\ndef _rebound(seam: Seam, obj) -> bool:\n \"\"\"True when the seam currently holds a gmlx replacement - one of\n our installers already ran in this interpreter. Source comparison is\n then meaningless (the patch being present proves the install succeeded);\n existence checks still apply. Upstream's own cross-package from-imports\n (e.g. qwen3_5.gated_delta re-exporting mlx-lm functions) keep their\n original __module__ and are fingerprinted normally.\"\"\"\n mod = getattr(obj, \"__module__\", None) or getattr(\n type(obj), \"__module__\", \"\")\n return bool(mod) and mod.split(\".\")[0] == \"gmlx\"\n\n\ndef _key(seam: Seam) -> str:\n return f\"{seam.module}:{seam.attr}\"\n\n\ndef collect_fingerprints() -> dict[str, str | None]:\n out: dict[str, str | None] = {}\n for seam in SEAMS:\n status, obj = _resolve(seam)\n if status == \"ok\":\n if _rebound(seam, obj):\n raise RuntimeError(\n f\"{_key(seam)} already holds a gmlx patch - \"\n f\"regenerate fingerprints in a fresh interpreter\")\n out[_key(seam)] = _fingerprint(obj)\n elif ((status == \"missing-module\" and seam.module_optional)\n or (status == \"missing-attr\" and seam.attr_optional)):\n continue # not present on this qualified version\n else:\n raise RuntimeError(\n f\"cannot fingerprint {_key(seam)}: {status} \"\n f\"(used by {seam.used_by})\")\n return out\n\n\ndef load_pinned() -> dict:\n with open(_JSON_PATH) as f:\n return json.load(f)\n\n\ndef check_seams() -> list[str]:\n \"\"\"Problems found against the pinned fingerprints; [] when clean.\"\"\"\n pinned = load_pinned()\n fps = pinned[\"fingerprints\"]\n problems = []\n for seam in SEAMS:\n status, obj = _resolve(seam)\n if status == \"missing-module\":\n if not seam.module_optional:\n problems.append(\n f\"{_key(seam)}: module missing (used by {seam.used_by})\")\n continue\n if status == \"missing-attr\":\n if not seam.attr_optional:\n problems.append(\n f\"{_key(seam)}: attribute missing - upstream renamed or \"\n f\"removed it (used by {seam.used_by})\")\n continue\n if _rebound(seam, obj):\n continue # our installer already replaced it in this process\n want = fps.get(_key(seam), \"\")\n got = _fingerprint(obj)\n if want == \"\":\n problems.append(\n f\"{_key(seam)}: no pinned fingerprint - run \"\n f\"`python -m gmlx.upstream_seams --regen`\")\n elif got != want:\n problems.append(\n f\"{_key(seam)}: source changed under the pin - re-audit \"\n f\"{seam.used_by}, then regenerate \"\n f\"(pinned for {pinned.get('generated_with')})\")\n return problems\n\n\ndef vendored_upstream_collisions() -> list[str]:\n \"\"\"Vendored mlx-lm model modules that upstream now ships natively.\n\n Our vendored modules register themselves into ``sys.modules`` under the\n mlx_lm.models namespace, so an upstream module of the same name would be\n silently shadowed; flag it so the vendored copy gets reconciled/dropped.\n \"\"\"\n from .arch_table import _VENDORED_MLX_LM_MODULES\n import mlx_lm.models as lm_models\n root = os.path.dirname(lm_models.__file__)\n hits = []\n for mod_name in _VENDORED_MLX_LM_MODULES:\n leaf = mod_name.rsplit(\".\", 1)[-1]\n if os.path.exists(os.path.join(root, f\"{leaf}.py\")):\n hits.append(\n f\"{mod_name}: upstream mlx-lm now ships this module; the \"\n f\"vendored copy shadows it - reconcile and drop the vendor \"\n f\"entry (arch_table._VENDORED_MLX_LM_MODULES)\")\n return hits\n\n\ndef _parse_version(v: str) -> tuple[int, ...]:\n m = re.match(r\"(\\d+(?:\\.\\d+)*)\", v)\n if not m:\n return ()\n return tuple(int(p) for p in m.group(1).split(\".\"))\n\n\n_VERSION_WARNED = False\n\n\ndef check_upstream_versions(quiet: bool = False) -> list[str]:\n \"\"\"Runtime gate for the mlx / mlx-lm / mlx-vlm environment.\n\n Below a floor: raises RuntimeError (a stale venv resolved pyproject\n constraints once and never again - pip pins cannot catch it). Newer than\n the qualified versions recorded at the last --regen: warns once. Missing\n or unparsable metadata (source installs): warns, never raises. Returns\n the warning lines (also printed unless ``quiet``).\n \"\"\"\n global _VERSION_WARNED\n import importlib.metadata as md\n try:\n tested = load_pinned().get(\"generated_with\", {})\n except (OSError, json.JSONDecodeError):\n tested = {}\n warnings, errors = [], []\n for pkg, floor in FLOORS.items():\n try:\n found = md.version(pkg)\n except md.PackageNotFoundError:\n warnings.append(\n f\"[versions] {pkg}: no package metadata (source install?) - \"\n f\"cannot verify the supported floor >= {floor}\")\n continue\n found_t = _parse_version(found)\n if not found_t:\n warnings.append(\n f\"[versions] {pkg}: unparsable version {found!r} - cannot \"\n f\"verify the supported floor >= {floor}\")\n continue\n floor_t = _parse_version(floor)\n if found_t < floor_t:\n errors.append(\n f\"{pkg} {found} is below the supported floor {floor}; \"\n f\"upgrade it (pip install -U '{pkg}>={floor}') or reinstall \"\n f\"gmlx into a fresh venv\")\n continue\n qual = tested.get(pkg)\n if qual and found_t > _parse_version(qual):\n warnings.append(\n f\"[versions] {pkg} {found} is newer than the qualified \"\n f\"{qual}; untested - see docs/upstream-upgrades.md\")\n if errors:\n raise RuntimeError(\n \"unsupported upstream package versions:\\n \" + \"\\n \".join(errors))\n if warnings and not quiet and not _VERSION_WARNED:\n _VERSION_WARNED = True\n for w in warnings:\n print(w, file=sys.stderr, flush=True)\n return warnings\n\n\ndef regen(path: str = _JSON_PATH) -> dict:\n import importlib.metadata as md\n generated_with = {}\n for pkg in FLOORS:\n try:\n generated_with[pkg] = md.version(pkg)\n except md.PackageNotFoundError:\n generated_with[pkg] = None\n data = {\n \"generated_with\": generated_with,\n \"fingerprints\": collect_fingerprints(),\n }\n with open(path, \"w\") as f:\n json.dump(data, f, indent=1, sort_keys=True)\n f.write(\"\\n\")\n return data\n\n\ndef main(argv=None) -> int:\n import argparse\n p = argparse.ArgumentParser(\n description=\"Check (default) or regenerate the upstream seam \"\n \"fingerprints.\")\n p.add_argument(\"--regen\", action=\"store_true\",\n help=\"re-capture fingerprints from the installed \"\n \"upstream versions (do this only after a deliberate, \"\n \"audited upstream bump)\")\n args = p.parse_args(argv)\n if args.regen:\n data = regen()\n n = len(data[\"fingerprints\"])\n print(f\"pinned {n} seam fingerprints for {data['generated_with']}\")\n return 0\n problems = check_seams() + vendored_upstream_collisions()\n try:\n problems += check_upstream_versions(quiet=True)\n except RuntimeError as e:\n problems.append(str(e))\n if problems:\n print(\"\\n\".join(problems))\n return 1\n print(f\"{len(SEAMS)} seams OK\")\n return 0\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n"}}}}