Meryem Sakin commited on
Commit
98e6a40
·
1 Parent(s): 9d3e347

Add commit-pinned reproducible sweep manifests

Browse files
README.md CHANGED
@@ -61,12 +61,15 @@ Run all targets without downloading model weights:
61
  ```bash
62
  toolcall-lint-sweep benchmarks/transformers-45419.json \
63
  --json-output reports/transformers-45419.json \
64
- --markdown-output reports/transformers-45419.md
 
65
  ```
66
 
67
  Each model is isolated: gated, missing, or incompatible repositories become
68
  `load_error` rows and do not abort the dataset. Contract failures are recorded
69
  separately. Use `--strict` when either condition should fail CI.
 
 
70
 
71
  ### Measured baseline (2026-08-19)
72
 
@@ -85,7 +88,9 @@ Key observations:
85
 
86
  See the compact [compatibility matrix](data/baseline-2026-08-19.md) and the
87
  [full machine-readable evidence](data/baseline-2026-08-19.json). Every loaded
88
- row records the resolved Hub commit and the chat-template SHA-256.
 
 
89
 
90
  ## Hugging Face Space
91
 
 
61
  ```bash
62
  toolcall-lint-sweep benchmarks/transformers-45419.json \
63
  --json-output reports/transformers-45419.json \
64
+ --markdown-output reports/transformers-45419.md \
65
+ --lock-output reports/transformers-45419.lock.json
66
  ```
67
 
68
  Each model is isolated: gated, missing, or incompatible repositories become
69
  `load_error` rows and do not abort the dataset. Contract failures are recorded
70
  separately. Use `--strict` when either condition should fail CI.
71
+ The regular manifest tracks current Hub state; the generated lock manifest pins
72
+ resolved commits for an exact rerun.
73
 
74
  ### Measured baseline (2026-08-19)
75
 
 
88
 
89
  See the compact [compatibility matrix](data/baseline-2026-08-19.md) and the
90
  [full machine-readable evidence](data/baseline-2026-08-19.json). Every loaded
91
+ row records the resolved Hub commit and the chat-template SHA-256. The
92
+ [commit-pinned manifest](benchmarks/transformers-45419.lock.json) reproduces
93
+ the accessible portion of this baseline exactly.
94
 
95
  ## Hugging Face Space
96
 
benchmarks/transformers-45419.lock.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "Commit-pinned manifest generated by toolcall-lint-sweep.",
3
+ "contract_version": "2026-08-mvp1",
4
+ "generated_at": "2026-08-19T10:56:59.206374+00:00",
5
+ "models": [
6
+ {
7
+ "label": "DeepSeekV3",
8
+ "model_id": "deepseek-ai/DeepSeek-R1",
9
+ "revision": "56d4cbbb4d29f4355bab4b9a39ccb717a14ad5ad"
10
+ },
11
+ {
12
+ "label": "DeepSeekV3-0528",
13
+ "model_id": "deepseek-ai/DeepSeek-R1-0528",
14
+ "revision": "4236a6af538feda4548eca9ab308586007567f52"
15
+ },
16
+ {
17
+ "label": "EXAONE-4.5",
18
+ "model_id": "LGAI-EXAONE/EXAONE-4.5-33B",
19
+ "revision": "570aa4b15a4f45ba1133072b45f50198f6e3b4fd"
20
+ },
21
+ {
22
+ "label": "Gemma4",
23
+ "model_id": "google/gemma-4-E2B-it",
24
+ "revision": "3e22461f65e89153144f8adb70e3b8c2cc9845a7"
25
+ },
26
+ {
27
+ "label": "GLM-5.1",
28
+ "model_id": "zai-org/GLM-5.1",
29
+ "revision": "26e1bd6e011feb778d25ae34b09b07074139d92d"
30
+ },
31
+ {
32
+ "label": "GLM4MOE",
33
+ "model_id": "zai-org/GLM-4.5",
34
+ "revision": "cbb2c7cfb52fa128a9660cb1a7a78e017899e115"
35
+ },
36
+ {
37
+ "label": "GptOSS",
38
+ "model_id": "openai/gpt-oss-20b",
39
+ "revision": "6cee5e81ee83917806bbde320786a8fb61efebee"
40
+ },
41
+ {
42
+ "label": "Holo3",
43
+ "model_id": "Hcompany/Holo3-35B-A3B",
44
+ "revision": "208d5ae3a03f99d561f32ab5e606f73397a390ea"
45
+ },
46
+ {
47
+ "label": "LFM2.5-VL",
48
+ "model_id": "LiquidAI/LFM2.5-VL-450M",
49
+ "revision": "fc6221ca597f3315e4f82fc2df606783267b34ba"
50
+ },
51
+ {
52
+ "label": "Llama3.1",
53
+ "model_id": "meta-llama/Llama-3.1-8B-Instruct"
54
+ },
55
+ {
56
+ "label": "Llama3.2",
57
+ "model_id": "meta-llama/Llama-3.2-1B-Instruct"
58
+ },
59
+ {
60
+ "label": "Marco-Mini",
61
+ "model_id": "AIDC-AI/Marco-Mini-Instruct",
62
+ "revision": "a85af582f1a2384e1eb3b3c8b03466e190403879"
63
+ },
64
+ {
65
+ "label": "MiniMax-M2.5",
66
+ "model_id": "MiniMaxAI/MiniMax-M2.5",
67
+ "revision": "f710177d938eff80b684d42c5aa84b382612f21f"
68
+ },
69
+ {
70
+ "label": "MiniMax-M2.7",
71
+ "model_id": "MiniMaxAI/MiniMax-M2.7",
72
+ "revision": "d494266a4affc0d2995ba1fa35c8481cbd84294b"
73
+ },
74
+ {
75
+ "label": "Qwen2.5",
76
+ "model_id": "Qwen/Qwen2.5-32B-Instruct",
77
+ "revision": "5ede1c97bbab6ce5cda5812749b4c0bdf79b18dd"
78
+ },
79
+ {
80
+ "label": "Qwen3",
81
+ "model_id": "Qwen/Qwen3-8B",
82
+ "revision": "b968826d9c46dd6066d109eabc6255188de91218"
83
+ },
84
+ {
85
+ "label": "Qwen3-Coder",
86
+ "model_id": "Qwen/Qwen3-Coder-Next",
87
+ "revision": "a7fbcb5c0e12d62a448eaa0e260346bf5dcc0feb"
88
+ },
89
+ {
90
+ "label": "Qwen3MOE",
91
+ "model_id": "Qwen/Qwen3-30B-A3B",
92
+ "revision": "ad44e777bcd18fa416d9da3bd8f70d33ebb85d39"
93
+ },
94
+ {
95
+ "label": "Qwen3VL",
96
+ "model_id": "Qwen/Qwen3-VL-2B-Instruct",
97
+ "revision": "89644892e4d85e24eaac8bacfd4f463576704203"
98
+ },
99
+ {
100
+ "label": "Qwen3.5",
101
+ "model_id": "Qwen/Qwen3.5-0.8B",
102
+ "revision": "2fc06364715b967f1860aea9cf38778875588b17"
103
+ }
104
+ ]
105
+ }
data/baseline-2026-08-19.json CHANGED
@@ -1,8 +1,14 @@
1
  {
2
  "schema_version": "1.0",
3
  "contract_version": "2026-08-mvp1",
4
- "generated_at": "2026-08-19T10:50:18.474746+00:00",
5
  "loads_model_weights": false,
 
 
 
 
 
 
6
  "summary": {
7
  "targets": 20,
8
  "loaded": 18,
@@ -16,7 +22,7 @@
16
  "model_id": "deepseek-ai/DeepSeek-R1",
17
  "template_name": null,
18
  "requested_revision": null,
19
- "resolved_revision": null,
20
  "template_sha256": "563b1ce7d61d50a9b4c7439a912a1116f095b712df5b5e4d3e1116049874eb64",
21
  "status": "contract_fail",
22
  "score": 20,
@@ -38,7 +44,7 @@
38
  "contract_version": "2026-08-mvp1",
39
  "template_sha256": "563b1ce7d61d50a9b4c7439a912a1116f095b712df5b5e4d3e1116049874eb64",
40
  "requested_revision": null,
41
- "resolved_revision": null,
42
  "tokenizer_class": "TokenizersBackend",
43
  "transformers_version": "5.15.0"
44
  },
@@ -123,14 +129,14 @@
123
  }
124
  ]
125
  },
126
- "elapsed_seconds": 4.003
127
  },
128
  {
129
  "label": "DeepSeekV3-0528",
130
  "model_id": "deepseek-ai/DeepSeek-R1-0528",
131
  "template_name": null,
132
  "requested_revision": null,
133
- "resolved_revision": null,
134
  "template_sha256": "53671bac29bcb3e1f95f51b8c77d85a6011b66dc38bd23dce64eef04384a976b",
135
  "status": "contract_fail",
136
  "score": 20,
@@ -152,7 +158,7 @@
152
  "contract_version": "2026-08-mvp1",
153
  "template_sha256": "53671bac29bcb3e1f95f51b8c77d85a6011b66dc38bd23dce64eef04384a976b",
154
  "requested_revision": null,
155
- "resolved_revision": null,
156
  "tokenizer_class": "TokenizersBackend",
157
  "transformers_version": "5.15.0"
158
  },
@@ -237,14 +243,14 @@
237
  }
238
  ]
239
  },
240
- "elapsed_seconds": 1.63
241
  },
242
  {
243
  "label": "EXAONE-4.5",
244
  "model_id": "LGAI-EXAONE/EXAONE-4.5-33B",
245
  "template_name": null,
246
  "requested_revision": null,
247
- "resolved_revision": null,
248
  "template_sha256": "e4ece7acc79ba82121d4d57791fb7ecb796e39185087197377da5d2286bec0e5",
249
  "status": "contract_pass",
250
  "score": 98,
@@ -266,7 +272,7 @@
266
  "contract_version": "2026-08-mvp1",
267
  "template_sha256": "e4ece7acc79ba82121d4d57791fb7ecb796e39185087197377da5d2286bec0e5",
268
  "requested_revision": null,
269
- "resolved_revision": null,
270
  "tokenizer_class": "TokenizersBackend",
271
  "transformers_version": "5.15.0"
272
  },
@@ -354,14 +360,14 @@
354
  }
355
  ]
356
  },
357
- "elapsed_seconds": 1.825
358
  },
359
  {
360
  "label": "Gemma4",
361
  "model_id": "google/gemma-4-E2B-it",
362
  "template_name": null,
363
  "requested_revision": null,
364
- "resolved_revision": null,
365
  "template_sha256": "0a2c8073c878ab1da004bee933a998606537bbb62016310352c7285c3f01c5b5",
366
  "status": "contract_pass",
367
  "score": 98,
@@ -383,7 +389,7 @@
383
  "contract_version": "2026-08-mvp1",
384
  "template_sha256": "0a2c8073c878ab1da004bee933a998606537bbb62016310352c7285c3f01c5b5",
385
  "requested_revision": null,
386
- "resolved_revision": null,
387
  "tokenizer_class": "GemmaTokenizer",
388
  "transformers_version": "5.15.0"
389
  },
@@ -469,14 +475,14 @@
469
  }
470
  ]
471
  },
472
- "elapsed_seconds": 2.562
473
  },
474
  {
475
  "label": "GLM-5.1",
476
  "model_id": "zai-org/GLM-5.1",
477
  "template_name": null,
478
  "requested_revision": null,
479
- "resolved_revision": null,
480
  "template_sha256": "03b1bbff20331e54647c68167e8ac7f0b5b7ceb40ead372f44826624a9ad79cd",
481
  "status": "contract_fail",
482
  "score": 79,
@@ -498,7 +504,7 @@
498
  "contract_version": "2026-08-mvp1",
499
  "template_sha256": "03b1bbff20331e54647c68167e8ac7f0b5b7ceb40ead372f44826624a9ad79cd",
500
  "requested_revision": null,
501
- "resolved_revision": null,
502
  "tokenizer_class": "TokenizersBackend",
503
  "transformers_version": "5.15.0"
504
  },
@@ -589,14 +595,14 @@
589
  }
590
  ]
591
  },
592
- "elapsed_seconds": 2.036
593
  },
594
  {
595
  "label": "GLM4MOE",
596
  "model_id": "zai-org/GLM-4.5",
597
  "template_name": null,
598
  "requested_revision": null,
599
- "resolved_revision": null,
600
  "template_sha256": "44f815868bf02fa458dd2f741a338046f4bf45f398eb6d067766726b9d96cce3",
601
  "status": "contract_fail",
602
  "score": 79,
@@ -618,7 +624,7 @@
618
  "contract_version": "2026-08-mvp1",
619
  "template_sha256": "44f815868bf02fa458dd2f741a338046f4bf45f398eb6d067766726b9d96cce3",
620
  "requested_revision": null,
621
- "resolved_revision": null,
622
  "tokenizer_class": "TokenizersBackend",
623
  "transformers_version": "5.15.0"
624
  },
@@ -710,14 +716,14 @@
710
  }
711
  ]
712
  },
713
- "elapsed_seconds": 1.909
714
  },
715
  {
716
  "label": "GptOSS",
717
  "model_id": "openai/gpt-oss-20b",
718
  "template_name": null,
719
  "requested_revision": null,
720
- "resolved_revision": null,
721
  "template_sha256": "a4c9919cbbd4acdd51ccffe22da049264b1b73e59055fa58811a99efbd7c8146",
722
  "status": "contract_fail",
723
  "score": 74,
@@ -739,7 +745,7 @@
739
  "contract_version": "2026-08-mvp1",
740
  "template_sha256": "a4c9919cbbd4acdd51ccffe22da049264b1b73e59055fa58811a99efbd7c8146",
741
  "requested_revision": null,
742
- "resolved_revision": null,
743
  "tokenizer_class": "TokenizersBackend",
744
  "transformers_version": "5.15.0"
745
  },
@@ -830,14 +836,14 @@
830
  }
831
  ]
832
  },
833
- "elapsed_seconds": 2.086
834
  },
835
  {
836
  "label": "Holo3",
837
  "model_id": "Hcompany/Holo3-35B-A3B",
838
  "template_name": null,
839
  "requested_revision": null,
840
- "resolved_revision": null,
841
  "template_sha256": "a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715",
842
  "status": "contract_pass",
843
  "score": 98,
@@ -859,7 +865,7 @@
859
  "contract_version": "2026-08-mvp1",
860
  "template_sha256": "a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715",
861
  "requested_revision": null,
862
- "resolved_revision": null,
863
  "tokenizer_class": "Qwen2Tokenizer",
864
  "transformers_version": "5.15.0"
865
  },
@@ -944,14 +950,14 @@
944
  }
945
  ]
946
  },
947
- "elapsed_seconds": 1.574
948
  },
949
  {
950
  "label": "LFM2.5-VL",
951
  "model_id": "LiquidAI/LFM2.5-VL-450M",
952
  "template_name": null,
953
  "requested_revision": null,
954
- "resolved_revision": null,
955
  "template_sha256": "309e586e2eda3d7f2db1e2a045bfb07f4c83798b23f7ac587954426302d508e9",
956
  "status": "contract_fail",
957
  "score": 79,
@@ -973,7 +979,7 @@
973
  "contract_version": "2026-08-mvp1",
974
  "template_sha256": "309e586e2eda3d7f2db1e2a045bfb07f4c83798b23f7ac587954426302d508e9",
975
  "requested_revision": null,
976
- "resolved_revision": null,
977
  "tokenizer_class": "TokenizersBackend",
978
  "transformers_version": "5.15.0"
979
  },
@@ -1060,7 +1066,7 @@
1060
  }
1061
  ]
1062
  },
1063
- "elapsed_seconds": 1.097
1064
  },
1065
  {
1066
  "label": "Llama3.1",
@@ -1074,7 +1080,7 @@
1074
  "message": "You are trying to access a gated repo.\nMake sure to have access to it at https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct.\n403 Client Error.\n\nCannot access gated repo for url https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct/resolve/main/config.json.\nAccess to model meta-llama/Llama-3.1-8B-Instruct is restricted and you are not in the authorized list. Visit https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct to ask for access."
1075
  },
1076
  "report": null,
1077
- "elapsed_seconds": 0.352
1078
  },
1079
  {
1080
  "label": "Llama3.2",
@@ -1088,14 +1094,14 @@
1088
  "message": "You are trying to access a gated repo.\nMake sure to have access to it at https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct.\n403 Client Error.\n\nCannot access gated repo for url https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct/resolve/main/config.json.\nAccess to model meta-llama/Llama-3.2-1B-Instruct is restricted and you are not in the authorized list. Visit https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct to ask for access."
1089
  },
1090
  "report": null,
1091
- "elapsed_seconds": 0.304
1092
  },
1093
  {
1094
  "label": "Marco-Mini",
1095
  "model_id": "AIDC-AI/Marco-Mini-Instruct",
1096
  "template_name": null,
1097
  "requested_revision": null,
1098
- "resolved_revision": null,
1099
  "template_sha256": "64f85b198065d0fba2a81f37e10ed68161ce2c19a754c7100e67e0ca2ee9c326",
1100
  "status": "contract_pass",
1101
  "score": 100,
@@ -1117,7 +1123,7 @@
1117
  "contract_version": "2026-08-mvp1",
1118
  "template_sha256": "64f85b198065d0fba2a81f37e10ed68161ce2c19a754c7100e67e0ca2ee9c326",
1119
  "requested_revision": null,
1120
- "resolved_revision": null,
1121
  "tokenizer_class": "Qwen2Tokenizer",
1122
  "transformers_version": "5.15.0"
1123
  },
@@ -1198,14 +1204,14 @@
1198
  }
1199
  ]
1200
  },
1201
- "elapsed_seconds": 1.97
1202
  },
1203
  {
1204
  "label": "MiniMax-M2.5",
1205
  "model_id": "MiniMaxAI/MiniMax-M2.5",
1206
  "template_name": null,
1207
  "requested_revision": null,
1208
- "resolved_revision": null,
1209
  "template_sha256": "f83cec52bb3a7e5a3cb4d6fd1dfdd6f4fe13b06c5aaa39a1115e70a417fc75f5",
1210
  "status": "contract_fail",
1211
  "score": 79,
@@ -1227,7 +1233,7 @@
1227
  "contract_version": "2026-08-mvp1",
1228
  "template_sha256": "f83cec52bb3a7e5a3cb4d6fd1dfdd6f4fe13b06c5aaa39a1115e70a417fc75f5",
1229
  "requested_revision": null,
1230
- "resolved_revision": null,
1231
  "tokenizer_class": "TokenizersBackend",
1232
  "transformers_version": "5.15.0"
1233
  },
@@ -1318,14 +1324,14 @@
1318
  }
1319
  ]
1320
  },
1321
- "elapsed_seconds": 2.047
1322
  },
1323
  {
1324
  "label": "MiniMax-M2.7",
1325
  "model_id": "MiniMaxAI/MiniMax-M2.7",
1326
  "template_name": null,
1327
  "requested_revision": null,
1328
- "resolved_revision": null,
1329
  "template_sha256": "893d908f7b5cc65fdde270dcae5ea1a99647c6a7ce572ae874a57b7160069566",
1330
  "status": "contract_fail",
1331
  "score": 79,
@@ -1347,7 +1353,7 @@
1347
  "contract_version": "2026-08-mvp1",
1348
  "template_sha256": "893d908f7b5cc65fdde270dcae5ea1a99647c6a7ce572ae874a57b7160069566",
1349
  "requested_revision": null,
1350
- "resolved_revision": null,
1351
  "tokenizer_class": "TokenizersBackend",
1352
  "transformers_version": "5.15.0"
1353
  },
@@ -1438,14 +1444,14 @@
1438
  }
1439
  ]
1440
  },
1441
- "elapsed_seconds": 2.292
1442
  },
1443
  {
1444
  "label": "Qwen2.5",
1445
  "model_id": "Qwen/Qwen2.5-32B-Instruct",
1446
  "template_name": null,
1447
  "requested_revision": null,
1448
- "resolved_revision": null,
1449
  "template_sha256": "cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f",
1450
  "status": "contract_pass",
1451
  "score": 95,
@@ -1467,7 +1473,7 @@
1467
  "contract_version": "2026-08-mvp1",
1468
  "template_sha256": "cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f",
1469
  "requested_revision": null,
1470
- "resolved_revision": null,
1471
  "tokenizer_class": "Qwen2Tokenizer",
1472
  "transformers_version": "5.15.0"
1473
  },
@@ -1550,14 +1556,14 @@
1550
  }
1551
  ]
1552
  },
1553
- "elapsed_seconds": 1.189
1554
  },
1555
  {
1556
  "label": "Qwen3",
1557
  "model_id": "Qwen/Qwen3-8B",
1558
  "template_name": null,
1559
  "requested_revision": null,
1560
- "resolved_revision": null,
1561
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1562
  "status": "contract_pass",
1563
  "score": 95,
@@ -1579,7 +1585,7 @@
1579
  "contract_version": "2026-08-mvp1",
1580
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1581
  "requested_revision": null,
1582
- "resolved_revision": null,
1583
  "tokenizer_class": "Qwen2Tokenizer",
1584
  "transformers_version": "5.15.0"
1585
  },
@@ -1667,14 +1673,14 @@
1667
  }
1668
  ]
1669
  },
1670
- "elapsed_seconds": 1.361
1671
  },
1672
  {
1673
  "label": "Qwen3-Coder",
1674
  "model_id": "Qwen/Qwen3-Coder-Next",
1675
  "template_name": null,
1676
  "requested_revision": null,
1677
- "resolved_revision": null,
1678
  "template_sha256": "c79a833039a43602150cce0902403d6e376c50930c1b2a139b2964e1f0c322a0",
1679
  "status": "contract_pass",
1680
  "score": 100,
@@ -1696,7 +1702,7 @@
1696
  "contract_version": "2026-08-mvp1",
1697
  "template_sha256": "c79a833039a43602150cce0902403d6e376c50930c1b2a139b2964e1f0c322a0",
1698
  "requested_revision": null,
1699
- "resolved_revision": null,
1700
  "tokenizer_class": "Qwen2Tokenizer",
1701
  "transformers_version": "5.15.0"
1702
  },
@@ -1775,14 +1781,14 @@
1775
  }
1776
  ]
1777
  },
1778
- "elapsed_seconds": 1.392
1779
  },
1780
  {
1781
  "label": "Qwen3MOE",
1782
  "model_id": "Qwen/Qwen3-30B-A3B",
1783
  "template_name": null,
1784
  "requested_revision": null,
1785
- "resolved_revision": null,
1786
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1787
  "status": "contract_pass",
1788
  "score": 95,
@@ -1804,7 +1810,7 @@
1804
  "contract_version": "2026-08-mvp1",
1805
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1806
  "requested_revision": null,
1807
- "resolved_revision": null,
1808
  "tokenizer_class": "Qwen2Tokenizer",
1809
  "transformers_version": "5.15.0"
1810
  },
@@ -1892,14 +1898,14 @@
1892
  }
1893
  ]
1894
  },
1895
- "elapsed_seconds": 1.227
1896
  },
1897
  {
1898
  "label": "Qwen3VL",
1899
  "model_id": "Qwen/Qwen3-VL-2B-Instruct",
1900
  "template_name": null,
1901
  "requested_revision": null,
1902
- "resolved_revision": null,
1903
  "template_sha256": "3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4",
1904
  "status": "contract_fail",
1905
  "score": 81,
@@ -1921,7 +1927,7 @@
1921
  "contract_version": "2026-08-mvp1",
1922
  "template_sha256": "3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4",
1923
  "requested_revision": null,
1924
- "resolved_revision": null,
1925
  "tokenizer_class": "Qwen2Tokenizer",
1926
  "transformers_version": "5.15.0"
1927
  },
@@ -2005,14 +2011,14 @@
2005
  }
2006
  ]
2007
  },
2008
- "elapsed_seconds": 1.262
2009
  },
2010
  {
2011
  "label": "Qwen3.5",
2012
  "model_id": "Qwen/Qwen3.5-0.8B",
2013
  "template_name": null,
2014
  "requested_revision": null,
2015
- "resolved_revision": null,
2016
  "template_sha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80",
2017
  "status": "contract_pass",
2018
  "score": 98,
@@ -2034,7 +2040,7 @@
2034
  "contract_version": "2026-08-mvp1",
2035
  "template_sha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80",
2036
  "requested_revision": null,
2037
- "resolved_revision": null,
2038
  "tokenizer_class": "Qwen2Tokenizer",
2039
  "transformers_version": "5.15.0"
2040
  },
@@ -2119,7 +2125,7 @@
2119
  }
2120
  ]
2121
  },
2122
- "elapsed_seconds": 1.756
2123
  }
2124
  ],
2125
  "manifest": {
 
1
  {
2
  "schema_version": "1.0",
3
  "contract_version": "2026-08-mvp1",
4
+ "generated_at": "2026-08-19T10:56:59.206374+00:00",
5
  "loads_model_weights": false,
6
+ "environment": {
7
+ "python": "3.14.4",
8
+ "platform": "macOS-26.4.1-arm64-arm-64bit-Mach-O",
9
+ "toolcall_lint": "0.1.0",
10
+ "transformers": "5.15.0"
11
+ },
12
  "summary": {
13
  "targets": 20,
14
  "loaded": 18,
 
22
  "model_id": "deepseek-ai/DeepSeek-R1",
23
  "template_name": null,
24
  "requested_revision": null,
25
+ "resolved_revision": "56d4cbbb4d29f4355bab4b9a39ccb717a14ad5ad",
26
  "template_sha256": "563b1ce7d61d50a9b4c7439a912a1116f095b712df5b5e4d3e1116049874eb64",
27
  "status": "contract_fail",
28
  "score": 20,
 
44
  "contract_version": "2026-08-mvp1",
45
  "template_sha256": "563b1ce7d61d50a9b4c7439a912a1116f095b712df5b5e4d3e1116049874eb64",
46
  "requested_revision": null,
47
+ "resolved_revision": "56d4cbbb4d29f4355bab4b9a39ccb717a14ad5ad",
48
  "tokenizer_class": "TokenizersBackend",
49
  "transformers_version": "5.15.0"
50
  },
 
129
  }
130
  ]
131
  },
132
+ "elapsed_seconds": 4.103
133
  },
134
  {
135
  "label": "DeepSeekV3-0528",
136
  "model_id": "deepseek-ai/DeepSeek-R1-0528",
137
  "template_name": null,
138
  "requested_revision": null,
139
+ "resolved_revision": "4236a6af538feda4548eca9ab308586007567f52",
140
  "template_sha256": "53671bac29bcb3e1f95f51b8c77d85a6011b66dc38bd23dce64eef04384a976b",
141
  "status": "contract_fail",
142
  "score": 20,
 
158
  "contract_version": "2026-08-mvp1",
159
  "template_sha256": "53671bac29bcb3e1f95f51b8c77d85a6011b66dc38bd23dce64eef04384a976b",
160
  "requested_revision": null,
161
+ "resolved_revision": "4236a6af538feda4548eca9ab308586007567f52",
162
  "tokenizer_class": "TokenizersBackend",
163
  "transformers_version": "5.15.0"
164
  },
 
243
  }
244
  ]
245
  },
246
+ "elapsed_seconds": 2.423
247
  },
248
  {
249
  "label": "EXAONE-4.5",
250
  "model_id": "LGAI-EXAONE/EXAONE-4.5-33B",
251
  "template_name": null,
252
  "requested_revision": null,
253
+ "resolved_revision": "570aa4b15a4f45ba1133072b45f50198f6e3b4fd",
254
  "template_sha256": "e4ece7acc79ba82121d4d57791fb7ecb796e39185087197377da5d2286bec0e5",
255
  "status": "contract_pass",
256
  "score": 98,
 
272
  "contract_version": "2026-08-mvp1",
273
  "template_sha256": "e4ece7acc79ba82121d4d57791fb7ecb796e39185087197377da5d2286bec0e5",
274
  "requested_revision": null,
275
+ "resolved_revision": "570aa4b15a4f45ba1133072b45f50198f6e3b4fd",
276
  "tokenizer_class": "TokenizersBackend",
277
  "transformers_version": "5.15.0"
278
  },
 
360
  }
361
  ]
362
  },
363
+ "elapsed_seconds": 2.226
364
  },
365
  {
366
  "label": "Gemma4",
367
  "model_id": "google/gemma-4-E2B-it",
368
  "template_name": null,
369
  "requested_revision": null,
370
+ "resolved_revision": "3e22461f65e89153144f8adb70e3b8c2cc9845a7",
371
  "template_sha256": "0a2c8073c878ab1da004bee933a998606537bbb62016310352c7285c3f01c5b5",
372
  "status": "contract_pass",
373
  "score": 98,
 
389
  "contract_version": "2026-08-mvp1",
390
  "template_sha256": "0a2c8073c878ab1da004bee933a998606537bbb62016310352c7285c3f01c5b5",
391
  "requested_revision": null,
392
+ "resolved_revision": "3e22461f65e89153144f8adb70e3b8c2cc9845a7",
393
  "tokenizer_class": "GemmaTokenizer",
394
  "transformers_version": "5.15.0"
395
  },
 
475
  }
476
  ]
477
  },
478
+ "elapsed_seconds": 3.132
479
  },
480
  {
481
  "label": "GLM-5.1",
482
  "model_id": "zai-org/GLM-5.1",
483
  "template_name": null,
484
  "requested_revision": null,
485
+ "resolved_revision": "26e1bd6e011feb778d25ae34b09b07074139d92d",
486
  "template_sha256": "03b1bbff20331e54647c68167e8ac7f0b5b7ceb40ead372f44826624a9ad79cd",
487
  "status": "contract_fail",
488
  "score": 79,
 
504
  "contract_version": "2026-08-mvp1",
505
  "template_sha256": "03b1bbff20331e54647c68167e8ac7f0b5b7ceb40ead372f44826624a9ad79cd",
506
  "requested_revision": null,
507
+ "resolved_revision": "26e1bd6e011feb778d25ae34b09b07074139d92d",
508
  "tokenizer_class": "TokenizersBackend",
509
  "transformers_version": "5.15.0"
510
  },
 
595
  }
596
  ]
597
  },
598
+ "elapsed_seconds": 2.998
599
  },
600
  {
601
  "label": "GLM4MOE",
602
  "model_id": "zai-org/GLM-4.5",
603
  "template_name": null,
604
  "requested_revision": null,
605
+ "resolved_revision": "cbb2c7cfb52fa128a9660cb1a7a78e017899e115",
606
  "template_sha256": "44f815868bf02fa458dd2f741a338046f4bf45f398eb6d067766726b9d96cce3",
607
  "status": "contract_fail",
608
  "score": 79,
 
624
  "contract_version": "2026-08-mvp1",
625
  "template_sha256": "44f815868bf02fa458dd2f741a338046f4bf45f398eb6d067766726b9d96cce3",
626
  "requested_revision": null,
627
+ "resolved_revision": "cbb2c7cfb52fa128a9660cb1a7a78e017899e115",
628
  "tokenizer_class": "TokenizersBackend",
629
  "transformers_version": "5.15.0"
630
  },
 
716
  }
717
  ]
718
  },
719
+ "elapsed_seconds": 2.757
720
  },
721
  {
722
  "label": "GptOSS",
723
  "model_id": "openai/gpt-oss-20b",
724
  "template_name": null,
725
  "requested_revision": null,
726
+ "resolved_revision": "6cee5e81ee83917806bbde320786a8fb61efebee",
727
  "template_sha256": "a4c9919cbbd4acdd51ccffe22da049264b1b73e59055fa58811a99efbd7c8146",
728
  "status": "contract_fail",
729
  "score": 74,
 
745
  "contract_version": "2026-08-mvp1",
746
  "template_sha256": "a4c9919cbbd4acdd51ccffe22da049264b1b73e59055fa58811a99efbd7c8146",
747
  "requested_revision": null,
748
+ "resolved_revision": "6cee5e81ee83917806bbde320786a8fb61efebee",
749
  "tokenizer_class": "TokenizersBackend",
750
  "transformers_version": "5.15.0"
751
  },
 
836
  }
837
  ]
838
  },
839
+ "elapsed_seconds": 3.213
840
  },
841
  {
842
  "label": "Holo3",
843
  "model_id": "Hcompany/Holo3-35B-A3B",
844
  "template_name": null,
845
  "requested_revision": null,
846
+ "resolved_revision": "208d5ae3a03f99d561f32ab5e606f73397a390ea",
847
  "template_sha256": "a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715",
848
  "status": "contract_pass",
849
  "score": 98,
 
865
  "contract_version": "2026-08-mvp1",
866
  "template_sha256": "a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715",
867
  "requested_revision": null,
868
+ "resolved_revision": "208d5ae3a03f99d561f32ab5e606f73397a390ea",
869
  "tokenizer_class": "Qwen2Tokenizer",
870
  "transformers_version": "5.15.0"
871
  },
 
950
  }
951
  ]
952
  },
953
+ "elapsed_seconds": 1.88
954
  },
955
  {
956
  "label": "LFM2.5-VL",
957
  "model_id": "LiquidAI/LFM2.5-VL-450M",
958
  "template_name": null,
959
  "requested_revision": null,
960
+ "resolved_revision": "fc6221ca597f3315e4f82fc2df606783267b34ba",
961
  "template_sha256": "309e586e2eda3d7f2db1e2a045bfb07f4c83798b23f7ac587954426302d508e9",
962
  "status": "contract_fail",
963
  "score": 79,
 
979
  "contract_version": "2026-08-mvp1",
980
  "template_sha256": "309e586e2eda3d7f2db1e2a045bfb07f4c83798b23f7ac587954426302d508e9",
981
  "requested_revision": null,
982
+ "resolved_revision": "fc6221ca597f3315e4f82fc2df606783267b34ba",
983
  "tokenizer_class": "TokenizersBackend",
984
  "transformers_version": "5.15.0"
985
  },
 
1066
  }
1067
  ]
1068
  },
1069
+ "elapsed_seconds": 1.372
1070
  },
1071
  {
1072
  "label": "Llama3.1",
 
1080
  "message": "You are trying to access a gated repo.\nMake sure to have access to it at https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct.\n403 Client Error.\n\nCannot access gated repo for url https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct/resolve/main/config.json.\nAccess to model meta-llama/Llama-3.1-8B-Instruct is restricted and you are not in the authorized list. Visit https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct to ask for access."
1081
  },
1082
  "report": null,
1083
+ "elapsed_seconds": 0.336
1084
  },
1085
  {
1086
  "label": "Llama3.2",
 
1094
  "message": "You are trying to access a gated repo.\nMake sure to have access to it at https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct.\n403 Client Error.\n\nCannot access gated repo for url https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct/resolve/main/config.json.\nAccess to model meta-llama/Llama-3.2-1B-Instruct is restricted and you are not in the authorized list. Visit https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct to ask for access."
1095
  },
1096
  "report": null,
1097
+ "elapsed_seconds": 0.318
1098
  },
1099
  {
1100
  "label": "Marco-Mini",
1101
  "model_id": "AIDC-AI/Marco-Mini-Instruct",
1102
  "template_name": null,
1103
  "requested_revision": null,
1104
+ "resolved_revision": "a85af582f1a2384e1eb3b3c8b03466e190403879",
1105
  "template_sha256": "64f85b198065d0fba2a81f37e10ed68161ce2c19a754c7100e67e0ca2ee9c326",
1106
  "status": "contract_pass",
1107
  "score": 100,
 
1123
  "contract_version": "2026-08-mvp1",
1124
  "template_sha256": "64f85b198065d0fba2a81f37e10ed68161ce2c19a754c7100e67e0ca2ee9c326",
1125
  "requested_revision": null,
1126
+ "resolved_revision": "a85af582f1a2384e1eb3b3c8b03466e190403879",
1127
  "tokenizer_class": "Qwen2Tokenizer",
1128
  "transformers_version": "5.15.0"
1129
  },
 
1204
  }
1205
  ]
1206
  },
1207
+ "elapsed_seconds": 2.188
1208
  },
1209
  {
1210
  "label": "MiniMax-M2.5",
1211
  "model_id": "MiniMaxAI/MiniMax-M2.5",
1212
  "template_name": null,
1213
  "requested_revision": null,
1214
+ "resolved_revision": "f710177d938eff80b684d42c5aa84b382612f21f",
1215
  "template_sha256": "f83cec52bb3a7e5a3cb4d6fd1dfdd6f4fe13b06c5aaa39a1115e70a417fc75f5",
1216
  "status": "contract_fail",
1217
  "score": 79,
 
1233
  "contract_version": "2026-08-mvp1",
1234
  "template_sha256": "f83cec52bb3a7e5a3cb4d6fd1dfdd6f4fe13b06c5aaa39a1115e70a417fc75f5",
1235
  "requested_revision": null,
1236
+ "resolved_revision": "f710177d938eff80b684d42c5aa84b382612f21f",
1237
  "tokenizer_class": "TokenizersBackend",
1238
  "transformers_version": "5.15.0"
1239
  },
 
1324
  }
1325
  ]
1326
  },
1327
+ "elapsed_seconds": 2.456
1328
  },
1329
  {
1330
  "label": "MiniMax-M2.7",
1331
  "model_id": "MiniMaxAI/MiniMax-M2.7",
1332
  "template_name": null,
1333
  "requested_revision": null,
1334
+ "resolved_revision": "d494266a4affc0d2995ba1fa35c8481cbd84294b",
1335
  "template_sha256": "893d908f7b5cc65fdde270dcae5ea1a99647c6a7ce572ae874a57b7160069566",
1336
  "status": "contract_fail",
1337
  "score": 79,
 
1353
  "contract_version": "2026-08-mvp1",
1354
  "template_sha256": "893d908f7b5cc65fdde270dcae5ea1a99647c6a7ce572ae874a57b7160069566",
1355
  "requested_revision": null,
1356
+ "resolved_revision": "d494266a4affc0d2995ba1fa35c8481cbd84294b",
1357
  "tokenizer_class": "TokenizersBackend",
1358
  "transformers_version": "5.15.0"
1359
  },
 
1444
  }
1445
  ]
1446
  },
1447
+ "elapsed_seconds": 2.558
1448
  },
1449
  {
1450
  "label": "Qwen2.5",
1451
  "model_id": "Qwen/Qwen2.5-32B-Instruct",
1452
  "template_name": null,
1453
  "requested_revision": null,
1454
+ "resolved_revision": "5ede1c97bbab6ce5cda5812749b4c0bdf79b18dd",
1455
  "template_sha256": "cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f",
1456
  "status": "contract_pass",
1457
  "score": 95,
 
1473
  "contract_version": "2026-08-mvp1",
1474
  "template_sha256": "cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f",
1475
  "requested_revision": null,
1476
+ "resolved_revision": "5ede1c97bbab6ce5cda5812749b4c0bdf79b18dd",
1477
  "tokenizer_class": "Qwen2Tokenizer",
1478
  "transformers_version": "5.15.0"
1479
  },
 
1556
  }
1557
  ]
1558
  },
1559
+ "elapsed_seconds": 1.44
1560
  },
1561
  {
1562
  "label": "Qwen3",
1563
  "model_id": "Qwen/Qwen3-8B",
1564
  "template_name": null,
1565
  "requested_revision": null,
1566
+ "resolved_revision": "b968826d9c46dd6066d109eabc6255188de91218",
1567
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1568
  "status": "contract_pass",
1569
  "score": 95,
 
1585
  "contract_version": "2026-08-mvp1",
1586
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1587
  "requested_revision": null,
1588
+ "resolved_revision": "b968826d9c46dd6066d109eabc6255188de91218",
1589
  "tokenizer_class": "Qwen2Tokenizer",
1590
  "transformers_version": "5.15.0"
1591
  },
 
1673
  }
1674
  ]
1675
  },
1676
+ "elapsed_seconds": 1.824
1677
  },
1678
  {
1679
  "label": "Qwen3-Coder",
1680
  "model_id": "Qwen/Qwen3-Coder-Next",
1681
  "template_name": null,
1682
  "requested_revision": null,
1683
+ "resolved_revision": "a7fbcb5c0e12d62a448eaa0e260346bf5dcc0feb",
1684
  "template_sha256": "c79a833039a43602150cce0902403d6e376c50930c1b2a139b2964e1f0c322a0",
1685
  "status": "contract_pass",
1686
  "score": 100,
 
1702
  "contract_version": "2026-08-mvp1",
1703
  "template_sha256": "c79a833039a43602150cce0902403d6e376c50930c1b2a139b2964e1f0c322a0",
1704
  "requested_revision": null,
1705
+ "resolved_revision": "a7fbcb5c0e12d62a448eaa0e260346bf5dcc0feb",
1706
  "tokenizer_class": "Qwen2Tokenizer",
1707
  "transformers_version": "5.15.0"
1708
  },
 
1781
  }
1782
  ]
1783
  },
1784
+ "elapsed_seconds": 1.36
1785
  },
1786
  {
1787
  "label": "Qwen3MOE",
1788
  "model_id": "Qwen/Qwen3-30B-A3B",
1789
  "template_name": null,
1790
  "requested_revision": null,
1791
+ "resolved_revision": "ad44e777bcd18fa416d9da3bd8f70d33ebb85d39",
1792
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1793
  "status": "contract_pass",
1794
  "score": 95,
 
1810
  "contract_version": "2026-08-mvp1",
1811
  "template_sha256": "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8",
1812
  "requested_revision": null,
1813
+ "resolved_revision": "ad44e777bcd18fa416d9da3bd8f70d33ebb85d39",
1814
  "tokenizer_class": "Qwen2Tokenizer",
1815
  "transformers_version": "5.15.0"
1816
  },
 
1898
  }
1899
  ]
1900
  },
1901
+ "elapsed_seconds": 1.283
1902
  },
1903
  {
1904
  "label": "Qwen3VL",
1905
  "model_id": "Qwen/Qwen3-VL-2B-Instruct",
1906
  "template_name": null,
1907
  "requested_revision": null,
1908
+ "resolved_revision": "89644892e4d85e24eaac8bacfd4f463576704203",
1909
  "template_sha256": "3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4",
1910
  "status": "contract_fail",
1911
  "score": 81,
 
1927
  "contract_version": "2026-08-mvp1",
1928
  "template_sha256": "3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4",
1929
  "requested_revision": null,
1930
+ "resolved_revision": "89644892e4d85e24eaac8bacfd4f463576704203",
1931
  "tokenizer_class": "Qwen2Tokenizer",
1932
  "transformers_version": "5.15.0"
1933
  },
 
2011
  }
2012
  ]
2013
  },
2014
+ "elapsed_seconds": 1.141
2015
  },
2016
  {
2017
  "label": "Qwen3.5",
2018
  "model_id": "Qwen/Qwen3.5-0.8B",
2019
  "template_name": null,
2020
  "requested_revision": null,
2021
+ "resolved_revision": "2fc06364715b967f1860aea9cf38778875588b17",
2022
  "template_sha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80",
2023
  "status": "contract_pass",
2024
  "score": 98,
 
2040
  "contract_version": "2026-08-mvp1",
2041
  "template_sha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80",
2042
  "requested_revision": null,
2043
+ "resolved_revision": "2fc06364715b967f1860aea9cf38778875588b17",
2044
  "tokenizer_class": "Qwen2Tokenizer",
2045
  "transformers_version": "5.15.0"
2046
  },
 
2125
  }
2126
  ]
2127
  },
2128
+ "elapsed_seconds": 1.845
2129
  }
2130
  ],
2131
  "manifest": {
src/toolcall_lint/adapters.py CHANGED
@@ -2,11 +2,39 @@
2
 
3
  from __future__ import annotations
4
 
 
5
  from collections.abc import Sequence
6
  from importlib.metadata import version
 
7
  from typing import Any
8
 
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  class TransformersRenderer:
11
  """Render a Hub model's chat template through ``transformers``.
12
 
@@ -41,7 +69,12 @@ class TransformersRenderer:
41
 
42
  def source_metadata(self) -> dict[str, Any]:
43
  init_kwargs = getattr(self.tokenizer, "init_kwargs", {})
44
- resolved_revision = getattr(self.tokenizer, "_commit_hash", None) or init_kwargs.get("_commit_hash")
 
 
 
 
 
45
  return {
46
  "requested_revision": self.revision,
47
  "resolved_revision": resolved_revision,
 
2
 
3
  from __future__ import annotations
4
 
5
+ import re
6
  from collections.abc import Sequence
7
  from importlib.metadata import version
8
+ from pathlib import Path
9
  from typing import Any
10
 
11
 
12
+ _SNAPSHOT_COMMIT = re.compile(r"(?:^|[/\\])snapshots[/\\]([0-9a-f]{40})(?:[/\\]|$)")
13
+
14
+
15
+ def _commit_from_snapshot_path(path: str | Path | None) -> str | None:
16
+ if path is None:
17
+ return None
18
+ match = _SNAPSHOT_COMMIT.search(str(path))
19
+ return match.group(1) if match else None
20
+
21
+
22
+ def _cached_commit(model_id: str, revision: str | None) -> str | None:
23
+ """Resolve the snapshot SHA already downloaded by ``from_pretrained``."""
24
+
25
+ try:
26
+ from huggingface_hub import try_to_load_from_cache
27
+
28
+ cached = try_to_load_from_cache(
29
+ model_id,
30
+ "tokenizer_config.json",
31
+ revision=revision or "main",
32
+ )
33
+ except Exception:
34
+ return None
35
+ return _commit_from_snapshot_path(cached if isinstance(cached, str) else None)
36
+
37
+
38
  class TransformersRenderer:
39
  """Render a Hub model's chat template through ``transformers``.
40
 
 
69
 
70
  def source_metadata(self) -> dict[str, Any]:
71
  init_kwargs = getattr(self.tokenizer, "init_kwargs", {})
72
+ resolved_revision = (
73
+ getattr(self.tokenizer, "_commit_hash", None)
74
+ or init_kwargs.get("_commit_hash")
75
+ or _commit_from_snapshot_path(getattr(self.tokenizer, "vocab_file", None))
76
+ or _cached_commit(self.model_id, self.revision)
77
+ )
78
  return {
79
  "requested_revision": self.revision,
80
  "resolved_revision": resolved_revision,
src/toolcall_lint/sweep.py CHANGED
@@ -5,11 +5,13 @@ from __future__ import annotations
5
  import argparse
6
  import hashlib
7
  import json
 
8
  import re
9
  import sys
10
  from collections import Counter
11
  from collections.abc import Callable, Sequence
12
  from datetime import datetime, timezone
 
13
  from pathlib import Path
14
  from time import perf_counter
15
  from typing import Any
@@ -114,6 +116,12 @@ def run_sweep(
114
  "contract_version": contract_version,
115
  "generated_at": datetime.now(timezone.utc).isoformat(),
116
  "loads_model_weights": False,
 
 
 
 
 
 
117
  "summary": {
118
  "targets": len(rows),
119
  "loaded": len(rows) - status_counts["load_error"],
@@ -152,6 +160,33 @@ def _stable_error_message(message: str) -> str:
152
  return re.sub(r"\s*\(Request ID: [^)]+\)", "", message).strip()
153
 
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  def to_markdown(dataset: dict[str, Any]) -> str:
156
  """Render a compact, reviewable compatibility matrix."""
157
 
@@ -210,6 +245,7 @@ def build_parser() -> argparse.ArgumentParser:
210
  parser.add_argument("manifest", type=Path, help="JSON file containing a `models` list")
211
  parser.add_argument("--json-output", type=Path, required=True, help="Dataset output path")
212
  parser.add_argument("--markdown-output", type=Path, help="Optional summary table output path")
 
213
  parser.add_argument(
214
  "--trust-remote-code",
215
  action="store_true",
@@ -243,6 +279,12 @@ def main(argv: list[str] | None = None) -> int:
243
  if args.markdown_output:
244
  args.markdown_output.parent.mkdir(parents=True, exist_ok=True)
245
  args.markdown_output.write_text(to_markdown(dataset) + "\n", encoding="utf-8")
 
 
 
 
 
 
246
  except Exception as exc:
247
  print(f"toolcall-lint-sweep: {type(exc).__name__}: {exc}", file=sys.stderr)
248
  return 2
 
5
  import argparse
6
  import hashlib
7
  import json
8
+ import platform
9
  import re
10
  import sys
11
  from collections import Counter
12
  from collections.abc import Callable, Sequence
13
  from datetime import datetime, timezone
14
+ from importlib.metadata import PackageNotFoundError, version
15
  from pathlib import Path
16
  from time import perf_counter
17
  from typing import Any
 
116
  "contract_version": contract_version,
117
  "generated_at": datetime.now(timezone.utc).isoformat(),
118
  "loads_model_weights": False,
119
+ "environment": {
120
+ "python": platform.python_version(),
121
+ "platform": platform.platform(),
122
+ "toolcall_lint": _package_version("toolcall-lint"),
123
+ "transformers": _package_version("transformers"),
124
+ },
125
  "summary": {
126
  "targets": len(rows),
127
  "loaded": len(rows) - status_counts["load_error"],
 
160
  return re.sub(r"\s*\(Request ID: [^)]+\)", "", message).strip()
161
 
162
 
163
+ def _package_version(name: str) -> str | None:
164
+ try:
165
+ return version(name)
166
+ except PackageNotFoundError:
167
+ return None
168
+
169
+
170
+ def to_lock_manifest(dataset: dict[str, Any]) -> dict[str, Any]:
171
+ """Pin every successfully resolved Hub revision from a sweep dataset."""
172
+
173
+ models: list[dict[str, Any]] = []
174
+ for row in dataset["models"]:
175
+ target: dict[str, Any] = {"label": row["label"], "model_id": row["model_id"]}
176
+ if row.get("template_name"):
177
+ target["template_name"] = row["template_name"]
178
+ revision = row.get("resolved_revision") or row.get("requested_revision")
179
+ if revision:
180
+ target["revision"] = revision
181
+ models.append(target)
182
+ return {
183
+ "description": "Commit-pinned manifest generated by toolcall-lint-sweep.",
184
+ "contract_version": dataset.get("contract_version"),
185
+ "generated_at": dataset.get("generated_at"),
186
+ "models": models,
187
+ }
188
+
189
+
190
  def to_markdown(dataset: dict[str, Any]) -> str:
191
  """Render a compact, reviewable compatibility matrix."""
192
 
 
245
  parser.add_argument("manifest", type=Path, help="JSON file containing a `models` list")
246
  parser.add_argument("--json-output", type=Path, required=True, help="Dataset output path")
247
  parser.add_argument("--markdown-output", type=Path, help="Optional summary table output path")
248
+ parser.add_argument("--lock-output", type=Path, help="Optional commit-pinned manifest output path")
249
  parser.add_argument(
250
  "--trust-remote-code",
251
  action="store_true",
 
279
  if args.markdown_output:
280
  args.markdown_output.parent.mkdir(parents=True, exist_ok=True)
281
  args.markdown_output.write_text(to_markdown(dataset) + "\n", encoding="utf-8")
282
+ if args.lock_output:
283
+ args.lock_output.parent.mkdir(parents=True, exist_ok=True)
284
+ args.lock_output.write_text(
285
+ json.dumps(to_lock_manifest(dataset), indent=2, ensure_ascii=False) + "\n",
286
+ encoding="utf-8",
287
+ )
288
  except Exception as exc:
289
  print(f"toolcall-lint-sweep: {type(exc).__name__}: {exc}", file=sys.stderr)
290
  return 2
tests/test_adapters.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import unittest
4
+
5
+ from toolcall_lint.adapters import _commit_from_snapshot_path
6
+
7
+
8
+ class AdapterMetadataTests(unittest.TestCase):
9
+ def test_extracts_hub_snapshot_commit(self) -> None:
10
+ commit = "b968826d9c46dd6066d109eabc6255188de91218"
11
+ path = f"/cache/models--Qwen--Qwen3-8B/snapshots/{commit}/vocab.json"
12
+
13
+ self.assertEqual(_commit_from_snapshot_path(path), commit)
14
+
15
+ def test_ignores_non_snapshot_paths(self) -> None:
16
+ self.assertIsNone(_commit_from_snapshot_path("/local/model/vocab.json"))
17
+
18
+
19
+ if __name__ == "__main__":
20
+ unittest.main()
tests/test_sweep.py CHANGED
@@ -6,7 +6,13 @@ import unittest
6
  from pathlib import Path
7
 
8
  from test_checks import FixtureRenderer
9
- from toolcall_lint.sweep import _stable_error_message, load_manifest, run_sweep, to_markdown
 
 
 
 
 
 
10
 
11
 
12
  class SweepRenderer(FixtureRenderer):
@@ -75,6 +81,16 @@ class SweepTests(unittest.TestCase):
75
  "403 Client Error.\nCannot access gated repo",
76
  )
77
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  if __name__ == "__main__":
80
  unittest.main()
 
6
  from pathlib import Path
7
 
8
  from test_checks import FixtureRenderer
9
+ from toolcall_lint.sweep import (
10
+ _stable_error_message,
11
+ load_manifest,
12
+ run_sweep,
13
+ to_lock_manifest,
14
+ to_markdown,
15
+ )
16
 
17
 
18
  class SweepRenderer(FixtureRenderer):
 
81
  "403 Client Error.\nCannot access gated repo",
82
  )
83
 
84
+ def test_lock_manifest_pins_resolved_revisions(self) -> None:
85
+ dataset = run_sweep(
86
+ [{"label": "Good", "model_id": "good/model"}],
87
+ renderer_factory=SweepRenderer,
88
+ )
89
+
90
+ locked = to_lock_manifest(dataset)
91
+
92
+ self.assertEqual(locked["models"][0]["revision"], "abc123")
93
+
94
 
95
  if __name__ == "__main__":
96
  unittest.main()