whosellm 0.2.5__tar.gz → 0.2.7__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.

Potentially problematic release.


This version of whosellm might be problematic. Click here for more details.

Files changed (122) hide show
  1. {whosellm-0.2.5 → whosellm-0.2.7}/.bumpversion.toml +1 -1
  2. {whosellm-0.2.5 → whosellm-0.2.7}/PKG-INFO +1 -1
  3. {whosellm-0.2.5 → whosellm-0.2.7}/pyproject.toml +1 -1
  4. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/test_anthropic.py +46 -3
  5. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/test_google.py +50 -1
  6. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/test_openai.py +41 -1
  7. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/test_zhipu.py +89 -1
  8. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_anthropic.py +68 -0
  9. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_deepseek.py +35 -0
  10. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_gemini.py +35 -3
  11. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm53.py +48 -0
  12. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_gpt5.py +18 -0
  13. whosellm-0.2.7/tests/models/families/test_gpt6.py +70 -0
  14. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_variant_priority_config.py +7 -1
  15. {whosellm-0.2.5 → whosellm-0.2.7}/uv.lock +1 -1
  16. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/__init__.py +1 -1
  17. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/base.py +1 -0
  18. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/anthropic.py +46 -0
  19. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/deepseek/deepseek_official.py +29 -4
  20. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/gemini.py +50 -7
  21. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/__init__.py +2 -0
  22. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_6.py +29 -0
  23. whosellm-0.2.7/whosellm/models/families/openai/openai_gpt_6.py +56 -0
  24. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/zhipu.py +27 -0
  25. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/commands/interview.md +0 -0
  26. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/projects/-Users-jqq-PycharmProjects-llmeta/memory/MEMORY.md +0 -0
  27. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/projects/-Users-jqq-PycharmProjects-llmeta/memory/feedback_use_uv.md +0 -0
  28. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/settings.json +0 -0
  29. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/code-review/SKILL.md +0 -0
  30. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/create-skill/SKILL.md +0 -0
  31. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/e2e-metadata/SKILL.md +0 -0
  32. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/evolve/SKILL.md +0 -0
  33. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/fix-review/SKILL.md +0 -0
  34. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/release/SKILL.md +0 -0
  35. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/SKILL.md +0 -0
  36. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/alibaba.md +0 -0
  37. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/anthropic.md +0 -0
  38. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/deepseek.md +0 -0
  39. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/gemini.md +0 -0
  40. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/openai.md +0 -0
  41. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/others.md +0 -0
  42. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/vidu.md +0 -0
  43. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/review-provider-model/providers/zhipu.md +0 -0
  44. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/update-provider-model/SKILL.md +0 -0
  45. {whosellm-0.2.5 → whosellm-0.2.7}/.claude/skills/update-provider-model/testing.md +0 -0
  46. {whosellm-0.2.5 → whosellm-0.2.7}/.coveragerc +0 -0
  47. {whosellm-0.2.5 → whosellm-0.2.7}/.github/workflows/publish.yml +0 -0
  48. {whosellm-0.2.5 → whosellm-0.2.7}/.github/workflows/tests.yml +0 -0
  49. {whosellm-0.2.5 → whosellm-0.2.7}/.gitignore +0 -0
  50. {whosellm-0.2.5 → whosellm-0.2.7}/.windsurf/workflows/addmodel.md +0 -0
  51. {whosellm-0.2.5 → whosellm-0.2.7}/.windsurf/workflows/arch.md +0 -0
  52. {whosellm-0.2.5 → whosellm-0.2.7}/.windsurf/workflows/testllmeta.md +0 -0
  53. {whosellm-0.2.5 → whosellm-0.2.7}/CHANGELOG.md +0 -0
  54. {whosellm-0.2.5 → whosellm-0.2.7}/CLAUDE.md +0 -0
  55. {whosellm-0.2.5 → whosellm-0.2.7}/LICENSE +0 -0
  56. {whosellm-0.2.5 → whosellm-0.2.7}/README.md +0 -0
  57. {whosellm-0.2.5 → whosellm-0.2.7}/docs/add_new_model_family.md +0 -0
  58. {whosellm-0.2.5 → whosellm-0.2.7}/docs/refactor_proposal.md +0 -0
  59. {whosellm-0.2.5 → whosellm-0.2.7}/docs/spec_model_family_redesign.md +0 -0
  60. {whosellm-0.2.5 → whosellm-0.2.7}/examples/advanced_usage.py +0 -0
  61. {whosellm-0.2.5 → whosellm-0.2.7}/examples/basic_usage.py +0 -0
  62. {whosellm-0.2.5 → whosellm-0.2.7}/mypy.ini +0 -0
  63. {whosellm-0.2.5 → whosellm-0.2.7}/pytest.ini +0 -0
  64. {whosellm-0.2.5 → whosellm-0.2.7}/ruff.toml +0 -0
  65. {whosellm-0.2.5 → whosellm-0.2.7}/tests/__init__.py +0 -0
  66. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/__init__.py +0 -0
  67. {whosellm-0.2.5 → whosellm-0.2.7}/tests/e2e/conftest.py +0 -0
  68. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/__init__.py +0 -0
  69. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/__init__.py +0 -0
  70. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_deepseek_tencent.py +0 -0
  71. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm41v_thinking.py +0 -0
  72. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm45.py +0 -0
  73. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm45v.py +0 -0
  74. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm46.py +0 -0
  75. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm46v.py +0 -0
  76. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm5.py +0 -0
  77. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_glm5v_turbo.py +0 -0
  78. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_gpt3_5.py +0 -0
  79. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_gpt4_1.py +0 -0
  80. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_gpt4o.py +0 -0
  81. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_o1.py +0 -0
  82. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_o3.py +0 -0
  83. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_o4.py +0 -0
  84. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_qwen.py +0 -0
  85. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_qwen3_vl_models.py +0 -0
  86. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_qwen_ollama.py +0 -0
  87. {whosellm-0.2.5 → whosellm-0.2.7}/tests/models/families/test_qwen_plus.py +0 -0
  88. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_auto_register.py +0 -0
  89. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_claude_4x_versions.py +0 -0
  90. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_llmeta.py +0 -0
  91. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_model_version.py +0 -0
  92. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_provider.py +0 -0
  93. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_registry_merge.py +0 -0
  94. {whosellm-0.2.5 → whosellm-0.2.7}/tests/test_specific_patterns.py +0 -0
  95. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/capabilities.py +0 -0
  96. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/model_version.py +0 -0
  97. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/__init__.py +0 -0
  98. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/config.py +0 -0
  99. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/dynamic_enum.py +0 -0
  100. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/__init__.py +0 -0
  101. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/alibaba.py +0 -0
  102. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/deepseek/__init__.py +0 -0
  103. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/deepseek/tencent.py +0 -0
  104. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_3_5.py +0 -0
  105. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_4.py +0 -0
  106. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_4_1.py +0 -0
  107. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_4o.py +0 -0
  108. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5.py +0 -0
  109. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_1.py +0 -0
  110. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_2.py +0 -0
  111. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_3.py +0 -0
  112. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_4.py +0 -0
  113. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_gpt_5_5.py +0 -0
  114. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_o1.py +0 -0
  115. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_o3.py +0 -0
  116. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/openai/openai_o4.py +0 -0
  117. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/others.py +0 -0
  118. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/families/vidu.py +0 -0
  119. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/patterns.py +0 -0
  120. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/models/registry.py +0 -0
  121. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/provider.py +0 -0
  122. {whosellm-0.2.5 → whosellm-0.2.7}/whosellm/py.typed +0 -0
@@ -2,7 +2,7 @@
2
2
  # 文档 / Documentation: https://callowayproject.github.io/bump-my-version/
3
3
 
4
4
  [tool.bumpversion]
5
- current_version = "0.2.5"
5
+ current_version = "0.2.7"
6
6
  parse = """(?x)
7
7
  (?P<major>0|[1-9]\\d*)\\.
8
8
  (?P<minor>0|[1-9]\\d*)\\.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: whosellm
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: A unified LLM model version and capability management library
5
5
  Author-email: JQQ <jqq1716@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "whosellm"
3
- version = "0.2.5"
3
+ version = "0.2.7"
4
4
  description = "A unified LLM model version and capability management library"
5
5
  authors = [
6
6
  {name = "JQQ", email = "jqq1716@gmail.com"}
@@ -1,7 +1,7 @@
1
1
  """Anthropic E2E 元数据测试。
2
2
 
3
3
  来源: https://platform.claude.com/docs/en/docs/about-claude/models
4
- 采集日期: 2026-04-12
4
+ 采集日期: 2026-04-12(2026-09-04 增补 Fable 5.1 / Mythos 5.1)
5
5
  """
6
6
 
7
7
  import pytest
@@ -11,7 +11,50 @@ from whosellm import ModelFamily, Provider
11
11
  from .conftest import assert_model_metadata
12
12
 
13
13
  # ============================================================================
14
- # Claude Family — Latest (version 4.6)
14
+ # Claude Family — Version 5.1 (2026-09-01 发布 / Released 2026-09-01)
15
+ # 来源: https://platform.claude.com/docs/en/models/fable-5-1/overview
16
+ # ============================================================================
17
+
18
+ CLAUDE_51_MODELS = [
19
+ (
20
+ "claude-fable-5-1",
21
+ {
22
+ "provider": Provider.ANTHROPIC,
23
+ "family": ModelFamily.CLAUDE,
24
+ "version": "5.1",
25
+ "variant": "fable",
26
+ "supports_thinking": True,
27
+ "supports_vision": True,
28
+ "supports_streaming": True,
29
+ "supports_function_calling": True,
30
+ "supports_structured_outputs": True,
31
+ "supports_computer_use": True,
32
+ "context_window": 1_000_000,
33
+ "max_tokens": 128_000,
34
+ },
35
+ ),
36
+ (
37
+ "claude-mythos-5-1",
38
+ {
39
+ # Glasswing 受邀版,与 Fable 5.1 同规格 / Glasswing invite-only, same specs as Fable 5.1
40
+ "provider": Provider.ANTHROPIC,
41
+ "family": ModelFamily.CLAUDE,
42
+ "version": "5.1",
43
+ "variant": "mythos",
44
+ "supports_thinking": True,
45
+ "supports_vision": True,
46
+ "supports_streaming": True,
47
+ "supports_function_calling": True,
48
+ "supports_structured_outputs": True,
49
+ "supports_computer_use": True,
50
+ "context_window": 1_000_000,
51
+ "max_tokens": 128_000,
52
+ },
53
+ ),
54
+ ]
55
+
56
+ # ============================================================================
57
+ # Claude Family — Version 4.6
15
58
  # 来源: https://platform.claude.com/docs/en/docs/about-claude/models/overview
16
59
  # ============================================================================
17
60
 
@@ -190,7 +233,7 @@ CLAUDE_30_MODELS = [
190
233
  # 聚合 + 参数化
191
234
  # ============================================================================
192
235
 
193
- ALL_MODELS = CLAUDE_LATEST_MODELS + CLAUDE_45_MODELS + CLAUDE_41_MODELS + CLAUDE_40_MODELS + CLAUDE_30_MODELS
236
+ ALL_MODELS = CLAUDE_51_MODELS + CLAUDE_LATEST_MODELS + CLAUDE_45_MODELS + CLAUDE_41_MODELS + CLAUDE_40_MODELS + CLAUDE_30_MODELS
194
237
 
195
238
 
196
239
  @pytest.mark.e2e
@@ -94,11 +94,30 @@ GEMINI_3X_MODELS = [
94
94
  ]
95
95
 
96
96
  # ============================================================================
97
- # Gemini Family — 2026-08 新增(GA Flash 主线 / Nano Banana 2 / Live / TTS)
97
+ # Gemini Family — 2026-08/09 新增(GA Flash 主线 / Nano Banana 2 / Live / TTS / Transcribe
98
98
  # 来源: https://ai.google.dev/gemini-api/docs/models/gemini-3.7-flash 等(2026-08-20 采集)
99
+ # https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash(2026-09-04 采集 3.8/transcribe/omni-1.1)
99
100
  # ============================================================================
100
101
 
101
102
  GEMINI_2026_NEW_MODELS = [
103
+ (
104
+ "gemini-3.8-flash",
105
+ {
106
+ "provider": Provider.GOOGLE,
107
+ "family": ModelFamily.GEMINI,
108
+ "version": "3.8",
109
+ "variant": "flash",
110
+ "supports_thinking": True,
111
+ "supports_vision": True,
112
+ "supports_audio": True,
113
+ "supports_video": True,
114
+ "supports_streaming": True,
115
+ "supports_function_calling": True,
116
+ "supports_structured_outputs": True,
117
+ "context_window": 1_048_576,
118
+ "max_tokens": 65_536,
119
+ },
120
+ ),
102
121
  (
103
122
  "gemini-3.7-flash",
104
123
  {
@@ -280,6 +299,36 @@ GEMINI_2026_NEW_MODELS = [
280
299
  "max_tokens": 16_384,
281
300
  },
282
301
  ),
302
+ (
303
+ # 官方无 token 上限说明(按音频时长限制);live 端点走 Live API
304
+ "gemini-3.5-transcribe",
305
+ {
306
+ "provider": Provider.GOOGLE,
307
+ "family": ModelFamily.GEMINI,
308
+ "version": "3.5",
309
+ "variant": "transcribe",
310
+ "supports_audio": True,
311
+ "supports_thinking": False,
312
+ "supports_function_calling": False,
313
+ "supports_streaming": True,
314
+ "supports_structured_outputs": False,
315
+ },
316
+ ),
317
+ (
318
+ "gemini-omni-1.1-flash",
319
+ {
320
+ "provider": Provider.GOOGLE,
321
+ "family": ModelFamily.GEMINI,
322
+ "version": "3.0",
323
+ "variant": "omni-flash",
324
+ "supports_vision": True,
325
+ "supports_video": True,
326
+ "supports_thinking": False,
327
+ "supports_streaming": True,
328
+ "supports_structured_outputs": False,
329
+ "context_window": 1_048_576,
330
+ },
331
+ ),
283
332
  ]
284
333
 
285
334
  # ============================================================================
@@ -11,9 +11,10 @@ from whosellm import ModelFamily, Provider
11
11
  from .conftest import assert_model_metadata
12
12
 
13
13
  # ============================================================================
14
- # GPT Family (latest: 5.6)
14
+ # GPT Family (latest: 6.0)
15
15
  # 来源: https://developers.openai.com/api/docs/models/gpt-5.4(2026-04-12 采集)
16
16
  # https://developers.openai.com/api/docs/models/gpt-5.6-sol(2026-08-20 采集 5.5/5.6)
17
+ # https://developers.openai.com/api/docs/models/gpt-6-astra(2026-09-04 采集 6-astra/5.6-cyber)
17
18
  # ============================================================================
18
19
 
19
20
  GPT_MODELS = [
@@ -199,6 +200,45 @@ GPT_MODELS = [
199
200
  "max_tokens": 128_000,
200
201
  },
201
202
  ),
203
+ (
204
+ "gpt-5.6-cyber",
205
+ {
206
+ # 仅 Responses API(不含 Batch),400K 上下文,需单独审批
207
+ "provider": Provider.OPENAI,
208
+ "family": ModelFamily.GPT,
209
+ "version": "5.6",
210
+ "variant": "cyber",
211
+ "supports_thinking": True,
212
+ "supports_vision": True,
213
+ "supports_streaming": True,
214
+ "supports_function_calling": True,
215
+ "supports_structured_outputs": True,
216
+ "supports_computer_use": True,
217
+ "context_window": 400_000,
218
+ "max_tokens": 128_000,
219
+ },
220
+ ),
221
+ # ------------------------------------------------------------------
222
+ # GPT-6 Astra 系列(2026-09-04 采集)
223
+ # 来源: https://developers.openai.com/api/docs/models/gpt-6-astra
224
+ # ------------------------------------------------------------------
225
+ (
226
+ "gpt-6-astra",
227
+ {
228
+ "provider": Provider.OPENAI,
229
+ "family": ModelFamily.GPT,
230
+ "version": "6.0",
231
+ "variant": "astra",
232
+ "supports_thinking": True,
233
+ "supports_vision": True,
234
+ "supports_streaming": True,
235
+ "supports_function_calling": True,
236
+ "supports_structured_outputs": True,
237
+ "supports_computer_use": True,
238
+ "context_window": 1_050_000,
239
+ "max_tokens": 128_000,
240
+ },
241
+ ),
202
242
  ]
203
243
 
204
244
  # ============================================================================
@@ -16,8 +16,9 @@ from whosellm import ModelFamily, Provider
16
16
  from .conftest import assert_model_metadata
17
17
 
18
18
  # ============================================================================
19
- # GLM Family — Version 5.0
19
+ # GLM Family — Version 5.0-5.3
20
20
  # 来源: https://docs.bigmodel.cn/cn/guide/models/text/glm-5.md
21
+ # https://docs.bigmodel.cn/cn/guide/models/text/glm-5.3.md(2026-09-04 采集 5.x)
21
22
  # ============================================================================
22
23
 
23
24
  GLM_50_MODELS = [
@@ -38,6 +39,93 @@ GLM_50_MODELS = [
38
39
  "max_tokens": 128_000,
39
40
  },
40
41
  ),
42
+ (
43
+ "glm-5-turbo",
44
+ {
45
+ "provider": Provider.ZHIPU,
46
+ "family": ModelFamily.GLM,
47
+ "version": "5.0",
48
+ "variant": "turbo",
49
+ "supports_thinking": True,
50
+ "supports_vision": False,
51
+ "supports_streaming": True,
52
+ "supports_function_calling": True,
53
+ "supports_structured_outputs": False,
54
+ "supports_json_outputs": True,
55
+ "context_window": 200_000,
56
+ "max_tokens": 128_000,
57
+ },
58
+ ),
59
+ (
60
+ "glm-5.1",
61
+ {
62
+ "provider": Provider.ZHIPU,
63
+ "family": ModelFamily.GLM,
64
+ "version": "5.1",
65
+ "variant": "base",
66
+ "supports_thinking": True,
67
+ "supports_vision": False,
68
+ "supports_streaming": True,
69
+ "supports_function_calling": True,
70
+ "supports_structured_outputs": False,
71
+ "supports_json_outputs": True,
72
+ "context_window": 200_000,
73
+ "max_tokens": 128_000,
74
+ },
75
+ ),
76
+ (
77
+ "glm-5.2",
78
+ {
79
+ "provider": Provider.ZHIPU,
80
+ "family": ModelFamily.GLM,
81
+ "version": "5.2",
82
+ "variant": "base",
83
+ "supports_thinking": True,
84
+ "supports_vision": False,
85
+ "supports_streaming": True,
86
+ "supports_function_calling": True,
87
+ "supports_structured_outputs": False,
88
+ "supports_json_outputs": True,
89
+ "context_window": 1_000_000,
90
+ "max_tokens": 128_000,
91
+ },
92
+ ),
93
+ (
94
+ "glm-5.3",
95
+ {
96
+ "provider": Provider.ZHIPU,
97
+ "family": ModelFamily.GLM,
98
+ "version": "5.3",
99
+ "variant": "base",
100
+ "supports_thinking": True,
101
+ "supports_vision": False,
102
+ "supports_streaming": True,
103
+ "supports_function_calling": True,
104
+ "supports_structured_outputs": False,
105
+ "supports_json_outputs": True,
106
+ "context_window": 1_000_000,
107
+ "max_tokens": 128_000,
108
+ },
109
+ ),
110
+ (
111
+ # 2026-09 新发布:GLM-5 系列首个原生多模态(输入 视频/图像/文本/文件)
112
+ "glm-5.3-flash",
113
+ {
114
+ "provider": Provider.ZHIPU,
115
+ "family": ModelFamily.GLM,
116
+ "version": "5.3",
117
+ "variant": "flash",
118
+ "supports_thinking": True,
119
+ "supports_vision": True,
120
+ "supports_video": True,
121
+ "supports_streaming": True,
122
+ "supports_function_calling": True,
123
+ "supports_structured_outputs": False,
124
+ "supports_json_outputs": True,
125
+ "context_window": 1_000_000,
126
+ "max_tokens": 128_000,
127
+ },
128
+ ),
41
129
  ]
42
130
 
43
131
  # ============================================================================
@@ -173,6 +173,74 @@ class TestClaudeMythos5:
173
173
  assert matched["provider"] == Provider.ANTHROPIC
174
174
 
175
175
 
176
+ class TestClaudeFable51:
177
+ """Claude Fable 5.1 测试(2026-09-01 发布,当前最新) / Claude Fable 5.1 tests"""
178
+
179
+ def test_specific_model_config(self):
180
+ """验证 claude-fable-5-1 配置 / Validate claude-fable-5-1 config"""
181
+ config = get_specific_model_config("claude-fable-5-1")
182
+ assert config is not None
183
+ version, variant, capabilities = config
184
+ assert version == "5.1"
185
+ assert variant == "fable"
186
+ assert capabilities is not None
187
+ assert capabilities.supports_vision is True
188
+ assert capabilities.supports_thinking is True
189
+ assert capabilities.supports_function_calling is True
190
+ assert capabilities.supports_streaming is True
191
+ assert capabilities.supports_structured_outputs is True
192
+ assert capabilities.supports_computer_use is True
193
+ assert capabilities.max_tokens == 128000
194
+ assert capabilities.context_window == 1000000
195
+
196
+ def test_pattern_match(self):
197
+ """验证 claude-fable-5-1 模式匹配 / Validate claude-fable-5-1 pattern match"""
198
+ matched = match_model_pattern("claude-fable-5-1")
199
+ assert matched is not None
200
+ assert matched["family"] == ModelFamily.CLAUDE
201
+ assert matched["variant"] == "fable"
202
+ assert matched["provider"] == Provider.ANTHROPIC
203
+
204
+ @pytest.mark.parametrize("model_name", ["claude-fable-5-1-20260901", "claude-fable-5-1@20260901"])
205
+ def test_pattern_with_snapshot(self, model_name: str):
206
+ """验证带 snapshot 的解析(版本号不被吞) / Validate snapshot forms keep version 5.1"""
207
+ meta = LLMeta(model_name)
208
+ assert meta.family == ModelFamily.CLAUDE
209
+ assert meta.version == "5.1"
210
+ assert meta.variant == "fable"
211
+
212
+ def test_version_ordering(self):
213
+ """验证 5.0 < 5.1 / Validate Fable 5.0 < Fable 5.1"""
214
+ assert LLMeta("claude-fable-5") < LLMeta("claude-fable-5-1")
215
+
216
+
217
+ class TestClaudeMythos51:
218
+ """Claude Mythos 5.1 测试(Glasswing 受邀版) / Claude Mythos 5.1 tests"""
219
+
220
+ def test_specific_model_config(self):
221
+ """验证 claude-mythos-5-1 配置 / Validate claude-mythos-5-1 config"""
222
+ config = get_specific_model_config("claude-mythos-5-1")
223
+ assert config is not None
224
+ version, variant, capabilities = config
225
+ assert version == "5.1"
226
+ assert variant == "mythos"
227
+ assert capabilities is not None
228
+ assert capabilities.supports_vision is True
229
+ assert capabilities.supports_thinking is True
230
+ assert capabilities.supports_structured_outputs is True
231
+ assert capabilities.supports_computer_use is True
232
+ assert capabilities.max_tokens == 128000
233
+ assert capabilities.context_window == 1000000
234
+
235
+ def test_pattern_match(self):
236
+ """验证 claude-mythos-5-1 模式匹配 / Validate claude-mythos-5-1 pattern match"""
237
+ matched = match_model_pattern("claude-mythos-5-1")
238
+ assert matched is not None
239
+ assert matched["family"] == ModelFamily.CLAUDE
240
+ assert matched["variant"] == "mythos"
241
+ assert matched["provider"] == Provider.ANTHROPIC
242
+
243
+
176
244
  class TestClaudeMythosClassOrdering:
177
245
  """Mythos-class 版本比较:mythos > fable > opus > sonnet / Mythos-class ordering"""
178
246
 
@@ -174,3 +174,38 @@ def test_deepseek_versioned_pattern_matches_official_family() -> None:
174
174
  assert model_v32.provider == Provider.DEEPSEEK
175
175
  assert model_v32.version == "3.2"
176
176
  assert model_v32.variant == "exp"
177
+
178
+
179
+ def test_deepseek_v4_flash_vision_exp_specific_model() -> None:
180
+ """验证 deepseek-v4-flash-vision-exp 配置(多模态实验版)"""
181
+ config = get_specific_model_config("deepseek-v4-flash-vision-exp")
182
+ assert config is not None
183
+ version, variant, capabilities = config
184
+ assert version == "4.0"
185
+ assert variant == "flash-vision-exp"
186
+ assert capabilities is not None
187
+ # 图像输入 / image input
188
+ assert capabilities.supports_vision is True
189
+ # 双模式,默认思考 / dual mode, thinking by default
190
+ assert capabilities.supports_thinking is True
191
+ assert capabilities.supports_function_calling is True
192
+ assert capabilities.supports_streaming is True
193
+ assert capabilities.supports_json_outputs is True
194
+ assert capabilities.supports_structured_outputs is False
195
+ # 不支持视频输入 / no video input
196
+ assert capabilities.supports_video is False
197
+ assert capabilities.max_tokens == 384_000
198
+ assert capabilities.context_window == 1_000_000
199
+
200
+
201
+ def test_deepseek_v4_flash_vision_exp_llmeta() -> None:
202
+ """验证 deepseek-v4-flash-vision-exp LLMeta 解析"""
203
+ from whosellm import LLMeta
204
+
205
+ model = LLMeta("deepseek-v4-flash-vision-exp")
206
+ assert model.provider == Provider.DEEPSEEK
207
+ assert model.family == ModelFamily.DEEPSEEK
208
+ assert model.version == "4.0"
209
+ assert model.variant == "flash-vision-exp"
210
+ assert model.capabilities.context_window == 1_000_000
211
+ assert model.capabilities.supports_vision is True
@@ -144,8 +144,8 @@ class TestGemini3x:
144
144
  assert variant == "flash-lite"
145
145
 
146
146
 
147
- class TestGemini35to37Flash:
148
- """Gemini 3.5/3.6/3.7 Flash 系列(GA)测试 / Gemini 3.5/3.6/3.7 Flash (GA) tests"""
147
+ class TestGemini35to38Flash:
148
+ """Gemini 3.5-3.8 Flash 系列(GA)测试 / Gemini 3.5-3.8 Flash (GA) tests"""
149
149
 
150
150
  @pytest.mark.parametrize(
151
151
  "model_name,expected_version,expected_variant",
@@ -153,6 +153,7 @@ class TestGemini35to37Flash:
153
153
  ("gemini-3.5-flash", "3.5", "flash"),
154
154
  ("gemini-3.6-flash", "3.6", "flash"),
155
155
  ("gemini-3.7-flash", "3.7", "flash"),
156
+ ("gemini-3.8-flash", "3.8", "flash"),
156
157
  ("gemini-3.5-flash-lite", "3.5", "flash-lite"),
157
158
  ],
158
159
  )
@@ -176,10 +177,36 @@ class TestGemini35to37Flash:
176
177
  assert capabilities.context_window == 1_048_576
177
178
 
178
179
  def test_ga_flash_ordering(self):
179
- """验证 3.1 < 3.5 < 3.6 < 3.7 / Validate 3.1 < 3.5 < 3.6 < 3.7"""
180
+ """验证 3.1 < 3.5 < 3.6 < 3.7 < 3.8 / Validate 3.1 < 3.5 < 3.6 < 3.7 < 3.8"""
180
181
  assert LLMeta("gemini-3.1-flash-lite") < LLMeta("gemini-3.5-flash")
181
182
  assert LLMeta("gemini-3.5-flash") < LLMeta("gemini-3.6-flash")
182
183
  assert LLMeta("gemini-3.6-flash") < LLMeta("gemini-3.7-flash")
184
+ assert LLMeta("gemini-3.7-flash") < LLMeta("gemini-3.8-flash")
185
+
186
+
187
+ def test_gemini_3_5_transcribe():
188
+ """测试 gemini-3.5-transcribe 转写模型(仅音频输入,无 token 上限,按音频时长限制)
189
+ Test Gemini 3.5 Transcribe (audio-only, no token limits, audio-duration capped)
190
+ """
191
+ config = get_specific_model_config("gemini-3.5-transcribe")
192
+ assert config is not None
193
+ version, variant, capabilities = config
194
+ assert version == "3.5"
195
+ assert variant == "transcribe"
196
+ assert capabilities is not None
197
+ assert capabilities.supports_audio is True
198
+ assert capabilities.supports_thinking is False
199
+ assert capabilities.supports_function_calling is False
200
+ assert capabilities.supports_structured_outputs is False
201
+ assert capabilities.supports_streaming is True
202
+ assert capabilities.max_audio_duration_seconds == 3600
203
+
204
+ # Live 端点共用同一配置 / live endpoint shares the same config
205
+ config_live = get_specific_model_config("gemini-3.5-transcribe-live")
206
+ assert config_live is not None
207
+ version_live, variant_live, _ = config_live
208
+ assert version_live == "3.5"
209
+ assert variant_live == "transcribe"
183
210
 
184
211
 
185
212
  class TestGemini20:
@@ -280,6 +307,7 @@ class TestGeminiParametrized:
280
307
  ("gemini-3.5-flash", "3.5", "flash"),
281
308
  ("gemini-3.6-flash", "3.6", "flash"),
282
309
  ("gemini-3.7-flash", "3.7", "flash"),
310
+ ("gemini-3.8-flash", "3.8", "flash"),
283
311
  ("gemini-3.5-flash-lite", "3.5", "flash-lite"),
284
312
  ("gemini-3.1-flash-lite", "3.1", "flash-lite"),
285
313
  ("gemini-3.1-flash-image", "3.1", "flash-image"),
@@ -288,6 +316,9 @@ class TestGeminiParametrized:
288
316
  ("gemini-3.1-flash-live-preview", "3.1", "flash-live"),
289
317
  ("gemini-3.1-flash-tts-preview", "3.1", "flash-tts"),
290
318
  ("gemini-3.5-live-translate-preview", "3.5", "live-translate"),
319
+ ("gemini-3.5-transcribe", "3.5", "transcribe"),
320
+ ("gemini-3.5-transcribe-live", "3.5", "transcribe"),
321
+ ("gemini-omni-1.1-flash", "3.0", "omni-flash"),
291
322
  ("gemini-omni-flash", "3.0", "omni-flash"),
292
323
  ("gemini-omni-flash-preview", "3.0", "omni-flash"),
293
324
  ],
@@ -308,6 +339,7 @@ class TestGeminiParametrized:
308
339
  ("gemini-3.5-flash", 65_536, 1_048_576),
309
340
  ("gemini-3.6-flash", 65_536, 1_048_576),
310
341
  ("gemini-3.7-flash", 65_536, 1_048_576),
342
+ ("gemini-3.8-flash", 65_536, 1_048_576),
311
343
  ("gemini-3.5-flash-lite", 65_536, 1_048_576),
312
344
  ("gemini-3.1-flash-lite", 65_536, 1_048_576),
313
345
  ("gemini-3.1-flash-image", 32_768, 131_072),
@@ -167,3 +167,51 @@ class TestGLM5xLLMetaIntegration:
167
167
  assert model.family == ModelFamily.GLM
168
168
  assert model.version == "5.0"
169
169
  assert model.variant == "turbo"
170
+
171
+
172
+ class TestGLM53Flash:
173
+ """GLM-5.3-Flash 测试(2026-09 原生多模态) / GLM-5.3-Flash tests"""
174
+
175
+ def test_specific_config_exists(self) -> None:
176
+ """验证 glm-5.3-flash specific_model 配置存在 / Validate glm-5.3-flash config exists"""
177
+ config = get_specific_model_config("glm-5.3-flash")
178
+ assert config is not None
179
+
180
+ version, variant, capabilities = config
181
+ assert version == "5.3"
182
+ assert variant == "flash"
183
+ assert capabilities is not None
184
+
185
+ def test_specific_capabilities(self) -> None:
186
+ """验证 glm-5.3-flash 能力与官方文档一致(原生多模态) / Validate capabilities match official docs"""
187
+ config = get_specific_model_config("glm-5.3-flash")
188
+ assert config is not None
189
+ _, _, capabilities = config
190
+ assert capabilities is not None
191
+
192
+ # 思考常开(thinking.type 仅支持 enabled)/ Always-on thinking
193
+ assert capabilities.supports_thinking is True
194
+ assert capabilities.supports_function_calling is True
195
+ # 原生多模态:图像/视频/文件输入 / Native multimodal input
196
+ assert capabilities.supports_vision is True
197
+ assert capabilities.supports_video is True
198
+ assert capabilities.supports_pdf is True
199
+ assert capabilities.supports_json_outputs is True
200
+ assert capabilities.supports_structured_outputs is False
201
+ assert capabilities.supports_streaming is True
202
+
203
+ assert capabilities.max_tokens == 128000
204
+ assert capabilities.context_window == 1000000 # 1M 上下文 / 1M context
205
+
206
+ def test_llmeta_basic(self) -> None:
207
+ model = LLMeta("glm-5.3-flash")
208
+
209
+ assert model.provider == Provider.ZHIPU
210
+ assert model.family == ModelFamily.GLM
211
+ assert model.version == "5.3"
212
+ assert model.variant == "flash"
213
+ assert model.capabilities.context_window == 1000000
214
+
215
+ def test_flash_below_base(self) -> None:
216
+ """同版本内 flash 优先级低于 base: glm-5.3-flash < glm-5.3"""
217
+ assert LLMeta("glm-5.3-flash") < LLMeta("glm-5.3")
@@ -405,6 +405,24 @@ def test_gpt5_6_with_date_suffix():
405
405
  assert m.release_date == date(2026, 8, 6)
406
406
 
407
407
 
408
+ def test_gpt5_6_cyber_model():
409
+ """测试gpt-5.6-cyber模型(网络安全,仅Responses API,400K上下文)
410
+ Test gpt-5.6-cyber model (cybersecurity, Responses API only, 400K context)
411
+ """
412
+ m = LLMeta("gpt-5.6-cyber")
413
+ assert m.family == ModelFamily.GPT
414
+ assert m.version == "5.6"
415
+ assert m.variant == "cyber"
416
+ assert m.capabilities.context_window == 400_000
417
+ assert m.capabilities.max_tokens == 128_000
418
+ assert m.capabilities.supports_thinking is True
419
+ assert m.capabilities.supports_vision is True
420
+ assert m.capabilities.supports_function_calling is True
421
+ assert m.capabilities.supports_structured_outputs is True
422
+ assert m.capabilities.supports_computer_use is True
423
+ assert m.capabilities.supports_fine_tuning is False
424
+
425
+
408
426
  # ============================================================================
409
427
  # GPT-5 Codex 系列测试 / GPT-5 Codex Series Tests
410
428
  # ============================================================================
@@ -0,0 +1,70 @@
1
+ # filename: test_gpt6.py
2
+ # @Time : 2026/09/04
3
+ # @Author : JQQ
4
+ # @Email : jiaqia@qknode.com
5
+ # @Software: PyCharm
6
+ """
7
+ GPT-6 模型家族测试 / GPT-6 model family tests
8
+ """
9
+
10
+ from datetime import date
11
+
12
+ from whosellm import LLMeta
13
+ from whosellm.models.base import ModelFamily
14
+
15
+ # ============================================================================
16
+ # GPT-6 Astra 测试 / GPT-6 Astra Tests
17
+ # ============================================================================
18
+
19
+
20
+ def test_gpt6_astra_model():
21
+ """测试GPT-6 Astra模型(2026-09-04 发布,旗舰) / Test GPT-6 Astra model"""
22
+ m = LLMeta("gpt-6-astra")
23
+ assert m.family == ModelFamily.GPT
24
+ assert m.version == "6.0"
25
+ assert m.variant == "astra"
26
+ assert m.capabilities.context_window == 1_050_000
27
+ assert m.capabilities.max_tokens == 128_000
28
+ assert m.capabilities.supports_thinking is True
29
+ assert m.capabilities.supports_vision is True
30
+ assert m.capabilities.supports_function_calling is True
31
+ assert m.capabilities.supports_streaming is True
32
+ assert m.capabilities.supports_structured_outputs is True
33
+ assert m.capabilities.supports_web_search is True
34
+ assert m.capabilities.supports_file_search is True
35
+ assert m.capabilities.supports_image_generation is True
36
+ assert m.capabilities.supports_code_interpreter is True
37
+ assert m.capabilities.supports_computer_use is True
38
+ assert m.capabilities.supports_fine_tuning is False
39
+
40
+
41
+ def test_gpt6_astra_snapshot():
42
+ """测试带日期后缀的GPT-6 Astra / Test GPT-6 Astra with date suffix"""
43
+ m = LLMeta("gpt-6-astra-2026-09-04")
44
+ assert m.family == ModelFamily.GPT
45
+ assert m.version == "6.0"
46
+ assert m.variant == "astra"
47
+ assert m.release_date == date(2026, 9, 4)
48
+
49
+
50
+ def test_gpt6_parent_pattern_inheritance():
51
+ """测试 parent pattern 匹配的 GPT-6 变体继承版本级 capabilities
52
+ Test parent pattern matched GPT-6 variant inherits version-level capabilities
53
+ """
54
+ m = LLMeta("gpt-6-turbo")
55
+
56
+ assert m.family == ModelFamily.GPT
57
+ assert m.version == "6.0"
58
+ assert m.variant == "turbo"
59
+ # 应继承 GPT-6.0 版本级 caps,而非 family default
60
+ assert m.capabilities.context_window == 1_050_000
61
+ assert m.capabilities.supports_thinking is True
62
+ assert m.capabilities.supports_computer_use is True
63
+
64
+
65
+ def test_gpt6_version_ordering():
66
+ """测试GPT-6版本排序 / Test GPT-6 version ordering"""
67
+ v56 = LLMeta("gpt-5.6")
68
+ v60 = LLMeta("gpt-6-astra")
69
+
70
+ assert v56 < v60