llmcapa 0.2.2__tar.gz → 0.2.4__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.
Files changed (41) hide show
  1. {llmcapa-0.2.2 → llmcapa-0.2.4}/DEVELOP.ja.md +1 -0
  2. {llmcapa-0.2.2 → llmcapa-0.2.4}/DEVELOP.md +1 -0
  3. {llmcapa-0.2.2 → llmcapa-0.2.4}/PKG-INFO +54 -6
  4. {llmcapa-0.2.2 → llmcapa-0.2.4}/README.ja.md +53 -5
  5. {llmcapa-0.2.2 → llmcapa-0.2.4}/README.md +53 -5
  6. {llmcapa-0.2.2 → llmcapa-0.2.4}/pyproject.toml +1 -1
  7. llmcapa-0.2.4/pyproject.toml.org +42 -0
  8. llmcapa-0.2.4/src/llmcapa/__init__.py +92 -0
  9. llmcapa-0.2.2/src/llmcapa/__init__.py → llmcapa-0.2.4/src/llmcapa/__init__.py.org +1 -1
  10. llmcapa-0.2.4/src/llmcapa/__init__.py.org1 +79 -0
  11. llmcapa-0.2.4/src/llmcapa/__init__.py.org2 +92 -0
  12. llmcapa-0.2.4/src/llmcapa/cli.py +204 -0
  13. llmcapa-0.2.4/src/llmcapa/data/azure_foundry.json +6571 -0
  14. llmcapa-0.2.4/src/llmcapa/data/xai.json +287 -0
  15. llmcapa-0.2.4/src/llmcapa/registry.py +368 -0
  16. llmcapa-0.2.4/xai_console.png +0 -0
  17. llmcapa-0.2.2/src/llmcapa/data/azure_foundry.json +0 -33179
  18. llmcapa-0.2.2/src/llmcapa/data/xai.json +0 -68
  19. {llmcapa-0.2.2 → llmcapa-0.2.4}/.gitignore +0 -0
  20. {llmcapa-0.2.2 → llmcapa-0.2.4}/LICENSE +0 -0
  21. /llmcapa-0.2.2/src/llmcapa/cli.py → /llmcapa-0.2.4/src/llmcapa/cli.py.org +0 -0
  22. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/__init__.py +0 -0
  23. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/amazon.json +0 -0
  24. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/anthropic.json +0 -0
  25. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/deepseek.json +0 -0
  26. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/google.json +0 -0
  27. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/japanese.json +0 -0
  28. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/meta.json +0 -0
  29. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/microsoft.json +0 -0
  30. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/mistral.json +0 -0
  31. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/moonshot.json +0 -0
  32. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/nvidia.json +0 -0
  33. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/openai.json +0 -0
  34. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/openrouter.json +0 -0
  35. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/qwen.json +0 -0
  36. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/models.py +0 -0
  37. /llmcapa-0.2.2/src/llmcapa/registry.py → /llmcapa-0.2.4/src/llmcapa/registry.py.org +0 -0
  38. {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/tokenizer.py +0 -0
  39. {llmcapa-0.2.2 → llmcapa-0.2.4}/tests/test_advanced.py +0 -0
  40. {llmcapa-0.2.2 → llmcapa-0.2.4}/tests/test_cache.py +0 -0
  41. {llmcapa-0.2.2 → llmcapa-0.2.4}/tests/test_registry.py +0 -0
@@ -19,6 +19,7 @@ llmcapa/
19
19
  │ ├── models.py # 機能データクラスと機能評価
20
20
  │ ├── registry.py # インメモリレジストリ、ロード、およびOpenRouter取得
21
21
  │ ├── cli.py # コマンドラインインターフェース
22
+ │ ├── tokenizer.py # トークンカウント(オフライン、プロバイダー別)
22
23
  │ └── data/ # 同梱されているオフライン機能データ (JSON)
23
24
  │ ├── __init__.py
24
25
  │ ├── openai.json
@@ -17,6 +17,7 @@ llmcapa/
17
17
  │ ├── models.py # Capability dataclass and feature evaluation
18
18
  │ ├── registry.py # In-memory registry, loading, and OpenRouter fetching
19
19
  │ ├── cli.py # Command-line interface
20
+ │ ├── tokenizer.py # Token counting (offline, provider-specific)
20
21
  │ └── data/ # Bundled offline capability data (JSON)
21
22
  │ ├── __init__.py
22
23
  │ ├── openai.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llmcapa
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Lookup capabilities (context window, modalities, features) of various LLM models offline.
5
5
  Project-URL: Homepage, https://github.com/awaku7/llmcapa
6
6
  Project-URL: Repository, https://github.com/awaku7/llmcapa
@@ -236,7 +236,7 @@ Lookup capabilities (context window, modalities, supported features) of various
236
236
 
237
237
  ## Features
238
238
 
239
- - **Comprehensive Bundled Data**: Offline capability data for OpenAI, Anthropic, Google (Gemini), Microsoft (Phi), Amazon (Nova/Titan), Meta (Llama), Mistral, Qwen, DeepSeek, NVIDIA, and Japanese domestic models (NTT tsuzumi, PFN PLaMo, ELYZA, etc. adopted by the Digital Agency's "GENNAI" platform).
239
+ - **Comprehensive Bundled Data**: Offline capability data for OpenAI, Anthropic, Google (Gemini), Microsoft (Phi), Amazon (Nova/Titan), Meta (Llama), Mistral, Qwen, DeepSeek, xAI (Grok), NVIDIA, MoonshotAI (Kimi), zhipu-ai (GLM), OpenRouter, and Japanese domestic models (NTT tsuzumi, PFN PLaMo, ELYZA, SoftBank, NEC, Fujitsu, etc. adopted by the Digital Agency's "GENNAI" platform).
240
240
  - **Zero Runtime Dependencies**: Built entirely on the Python standard library.
241
241
  - **Alias Resolution**: Automatically resolves aliases and provider-specific names (e.g., `gpt-4o-2024-08-06` -> `gpt-4o`, `gemini-1.5-pro-preview-0409` -> `gemini-1.5-pro`).
242
242
  - **Advanced Feature Queries**: Check support for `vision`, `multimodal`, `chat_completion`, `responses_api`, `reasoning_effort`, `thinking_budget`, and specific input/output modalities (e.g., `image_input`, `image_output`, `audio_input`).
@@ -283,7 +283,7 @@ print(cap.supports(Feature.LLMC_FEAT_REASONING_EFFORT)) # False
283
283
  print(ReasoningEffort.LLMC_EFFORT_HIGH) # "high"
284
284
  # List all supported features
285
285
  print(cap.features())
286
- # ['chat_completion', 'function_calling', 'image', 'image_input', 'image_output', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
286
+ # ['chat_completion', 'file', 'file_input', 'function_calling', 'image', 'image_input', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
287
287
  ```
288
288
 
289
289
  ### Token & Cost Estimation
@@ -317,10 +317,10 @@ gpt4o = llmcapa.get("gpt-4o")
317
317
  gpt4o_mini = llmcapa.get("gpt-4o-mini")
318
318
  gemini = llmcapa.get("gemini-3.5-flash")
319
319
 
320
- # gpt-4o-mini has the same context window but lacks image_output (which gpt-4o supports)
321
- print(gpt4o.can_be_replaced_by(gpt4o_mini)) # False
320
+ # gpt-4o-mini has the same context window and supports all the same features
321
+ print(gpt4o.can_be_replaced_by(gpt4o_mini)) # True
322
322
 
323
- # gemini-3.5-flash has a larger context window but also lacks image_output
323
+ # gemini-3.5-flash has a larger context window but lacks responses_api (which gpt-4o supports)
324
324
  print(gpt4o.can_be_replaced_by(gemini)) # False
325
325
 
326
326
  # If we only require vision and function_calling, gemini-3.5-flash can replace gpt-4o
@@ -386,6 +386,47 @@ print(cap.context_window) # 131072
386
386
  print(cap.pricing) # {'input_per_1m': 0.1, 'output_per_1m': 0.32, 'currency': 'USD'}
387
387
  ```
388
388
 
389
+ ### Token Counting (Standalone)
390
+
391
+ Count tokens for a single text or a list of chat messages using the best available tokenizer for a given model.
392
+
393
+ ```python
394
+ # Count tokens for a text string
395
+ import llmcapa
396
+ tokens = llmcapa.count_tokens("Hello, world!", "gpt-4o")
397
+ print(tokens) # exact count if tiktoken is installed, else estimation
398
+
399
+ # Count tokens for chat messages (includes overhead)
400
+ messages = [
401
+ {"role": "user", "content": "Hello"},
402
+ {"role": "assistant", "content": "Hi there!"},
403
+ ]
404
+ total = llmcapa.count_messages_tokens(messages, "gpt-4o")
405
+ print(total)
406
+ ```
407
+
408
+ ### Programmatic Registration
409
+
410
+ Register a Capability directly without a JSON file:
411
+
412
+ ```python
413
+ from llmcapa import Capability
414
+
415
+ cap = Capability(
416
+ provider="local",
417
+ model_id="my-model",
418
+ context_window=4096,
419
+ max_output_tokens=1024,
420
+ supports_function_calling=True,
421
+ aliases=["mm"],
422
+ )
423
+ llmcapa.register(cap)
424
+
425
+ print(llmcapa.get("my-model").context_window) # 4096
426
+ ```
427
+
428
+ > **Note**: `llmcapa.get()` raises `ModelNotFoundError` if the model is not found.
429
+
389
430
  ### Custom Local Data
390
431
 
391
432
  Load your own model definitions from a local JSON file:
@@ -429,6 +470,13 @@ llmcapa list --json --no-deprecated
429
470
  # List all known providers
430
471
  llmcapa providers
431
472
 
473
+ # Count tokens for text or messages
474
+ llmcapa tokens gpt-4o "Hello, world!"
475
+ llmcapa tokens gpt-4o --messages '[{"role":"user","content":"Hi"}]'
476
+
477
+ # Load extra model data from a local JSON file on startup
478
+ llmcapa --extra my_models.json show gpt-4o
479
+
432
480
  # Explicitly fetch and update the OpenRouter models cache (forces cache refresh)
433
481
  llmcapa update
434
482
  ```
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 特徴
6
6
 
7
- - **包括的な同梱データ**: OpenAI、Anthropic、Google (Gemini)、Microsoft (Phi)、Amazon (Nova/Titan)、Meta (Llama)、Mistral、Qwen、DeepSeek、NVIDIA、および日本の国内モデル(デジタル庁の「GENNAI」プラットフォームで採用されているNTT tsuzumi、PFN PLaMo、ELYZA、SoftBank、NEC、Fujitsuなど)のオフライン機能データを同梱しています。
7
+ - **包括的な同梱データ**: OpenAI、Anthropic、Google (Gemini)、Microsoft (Phi)、Amazon (Nova/Titan)、Meta (Llama)、Mistral、Qwen、DeepSeek、xAI (Grok)、NVIDIA、MoonshotAI (Kimi)、zhipu-ai (GLM)、OpenRouter、および日本の国内モデル(デジタル庁の「GENNAI」プラットフォームで採用されているNTT tsuzumi、PFN PLaMo、ELYZA、SoftBank、NEC、Fujitsuなど)のオフライン機能データを同梱しています。
8
8
  - **実行時依存関係ゼロ**: Python標準ライブラリのみで動作します。外部パッケージ(`pytest` や `build` など)は開発・テスト用のみです。
9
9
  - **エイリアス解決**: エイリアスやプロバイダー固有の名前を自動的に解決します(例: `gpt-4o-2024-08-06` -> `gpt-4o`、`gemini-1.5-pro-preview-0409` -> `gemini-1.5-pro`)。
10
10
  - **高度な機能クエリ**: `vision`、`multimodal`、`chat_completion`、`responses_api`、`reasoning_effort`、`thinking_budget`、および特定の入力/出力モダリティ(例: `image_input`、`image_output`、`audio_input`)のサポート状況を確認できます。
@@ -51,7 +51,7 @@ print(cap.supports(Feature.LLMC_FEAT_REASONING_EFFORT)) # False
51
51
  print(ReasoningEffort.LLMC_EFFORT_HIGH) # "high"
52
52
  # サポートされているすべての機能を一覧表示
53
53
  print(cap.features())
54
- # ['chat_completion', 'function_calling', 'image', 'image_input', 'image_output', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
54
+ # ['chat_completion', 'file', 'file_input', 'function_calling', 'image', 'image_input', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
55
55
  ```
56
56
 
57
57
  ### トークン数とコストの見積もり
@@ -85,10 +85,10 @@ gpt4o = llmcapa.get("gpt-4o")
85
85
  gpt4o_mini = llmcapa.get("gpt-4o-mini")
86
86
  gemini = llmcapa.get("gemini-3.5-flash")
87
87
 
88
- # gpt-4o-miniは同じコンテキストウィンドウを持ちますが、image_output(gpt-4oがサポート)がありません
89
- print(gpt4o.can_be_replaced_by(gpt4o_mini)) # False
88
+ # gpt-4o-miniは同じコンテキストウィンドウを持ち、同じ機能をすべてサポートしています
89
+ print(gpt4o.can_be_replaced_by(gpt4o_mini)) # True
90
90
 
91
- # gemini-3.5-flashはより大きなコンテキストウィンドウを持ちますが、同様にimage_outputがありません
91
+ # gemini-3.5-flashはより大きなコンテキストウィンドウを持ちますが、responses_api(gpt-4oがサポート)がありません
92
92
  print(gpt4o.can_be_replaced_by(gemini)) # False
93
93
 
94
94
  # visionとfunction_callingのみが必要な場合、gemini-3.5-flashはgpt-4oを代替できます
@@ -154,6 +154,47 @@ print(cap.context_window) # 131072
154
154
  print(cap.pricing) # {'input_per_1m': 0.1, 'output_per_1m': 0.32, 'currency': 'USD'}
155
155
  ```
156
156
 
157
+ ### トークン数のカウント(スタンドアロン)
158
+
159
+ 指定されたモデルに最適なトークナイザーを使用して、単一テキストまたはチャットメッセージのトークン数をカウントします。
160
+
161
+ ```python
162
+ # テキストのトークン数をカウント
163
+ import llmcapa
164
+ tokens = llmcapa.count_tokens("Hello, world!", "gpt-4o")
165
+ print(tokens) # tiktokenがインストールされていれば正確な値、それ以外は推定値
166
+
167
+ # チャットメッセージのトークン数(オーバーヘッド含む)
168
+ messages = [
169
+ {"role": "user", "content": "Hello"},
170
+ {"role": "assistant", "content": "Hi there!"},
171
+ ]
172
+ total = llmcapa.count_messages_tokens(messages, "gpt-4o")
173
+ print(total)
174
+ ```
175
+
176
+ ### プログラムによるモデル登録
177
+
178
+ JSONファイルを使わずに直接Capabilityを登録:
179
+
180
+ ```python
181
+ from llmcapa import Capability
182
+
183
+ cap = Capability(
184
+ provider="local",
185
+ model_id="my-model",
186
+ context_window=4096,
187
+ max_output_tokens=1024,
188
+ supports_function_calling=True,
189
+ aliases=["mm"],
190
+ )
191
+ llmcapa.register(cap)
192
+
193
+ print(llmcapa.get("my-model").context_window) # 4096
194
+ ```
195
+
196
+ > **注意**: `llmcapa.get()` はモデルが見つからない場合 `ModelNotFoundError` を送出します。
197
+
157
198
  ### カスタムローカルデータ
158
199
 
159
200
  ローカルのJSONファイルから独自のモデル定義をロードできます。
@@ -197,6 +238,13 @@ llmcapa list --json --no-deprecated
197
238
  # 既知のすべてのプロバイダーを一覧表示
198
239
  llmcapa providers
199
240
 
241
+ # テキストやメッセージのトークン数をカウント
242
+ llmcapa tokens gpt-4o "Hello, world!"
243
+ llmcapa tokens gpt-4o --messages '[{"role":"user","content":"Hi"}]'
244
+
245
+ # 起動時にローカルJSONファイルから追加モデルをロード
246
+ llmcapa --extra my_models.json show gpt-4o
247
+
200
248
  # 明示的にOpenRouterモデルのキャッシュを取得・更新(キャッシュを強制リフレッシュ)
201
249
  llmcapa update
202
250
  ```
@@ -4,7 +4,7 @@ Lookup capabilities (context window, modalities, supported features) of various
4
4
 
5
5
  ## Features
6
6
 
7
- - **Comprehensive Bundled Data**: Offline capability data for OpenAI, Anthropic, Google (Gemini), Microsoft (Phi), Amazon (Nova/Titan), Meta (Llama), Mistral, Qwen, DeepSeek, NVIDIA, and Japanese domestic models (NTT tsuzumi, PFN PLaMo, ELYZA, etc. adopted by the Digital Agency's "GENNAI" platform).
7
+ - **Comprehensive Bundled Data**: Offline capability data for OpenAI, Anthropic, Google (Gemini), Microsoft (Phi), Amazon (Nova/Titan), Meta (Llama), Mistral, Qwen, DeepSeek, xAI (Grok), NVIDIA, MoonshotAI (Kimi), zhipu-ai (GLM), OpenRouter, and Japanese domestic models (NTT tsuzumi, PFN PLaMo, ELYZA, SoftBank, NEC, Fujitsu, etc. adopted by the Digital Agency's "GENNAI" platform).
8
8
  - **Zero Runtime Dependencies**: Built entirely on the Python standard library.
9
9
  - **Alias Resolution**: Automatically resolves aliases and provider-specific names (e.g., `gpt-4o-2024-08-06` -> `gpt-4o`, `gemini-1.5-pro-preview-0409` -> `gemini-1.5-pro`).
10
10
  - **Advanced Feature Queries**: Check support for `vision`, `multimodal`, `chat_completion`, `responses_api`, `reasoning_effort`, `thinking_budget`, and specific input/output modalities (e.g., `image_input`, `image_output`, `audio_input`).
@@ -51,7 +51,7 @@ print(cap.supports(Feature.LLMC_FEAT_REASONING_EFFORT)) # False
51
51
  print(ReasoningEffort.LLMC_EFFORT_HIGH) # "high"
52
52
  # List all supported features
53
53
  print(cap.features())
54
- # ['chat_completion', 'function_calling', 'image', 'image_input', 'image_output', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
54
+ # ['chat_completion', 'file', 'file_input', 'function_calling', 'image', 'image_input', 'json_mode', 'multimodal', 'responses_api', 'streaming', 'text', 'text_input', 'text_output', 'vision']
55
55
  ```
56
56
 
57
57
  ### Token & Cost Estimation
@@ -85,10 +85,10 @@ gpt4o = llmcapa.get("gpt-4o")
85
85
  gpt4o_mini = llmcapa.get("gpt-4o-mini")
86
86
  gemini = llmcapa.get("gemini-3.5-flash")
87
87
 
88
- # gpt-4o-mini has the same context window but lacks image_output (which gpt-4o supports)
89
- print(gpt4o.can_be_replaced_by(gpt4o_mini)) # False
88
+ # gpt-4o-mini has the same context window and supports all the same features
89
+ print(gpt4o.can_be_replaced_by(gpt4o_mini)) # True
90
90
 
91
- # gemini-3.5-flash has a larger context window but also lacks image_output
91
+ # gemini-3.5-flash has a larger context window but lacks responses_api (which gpt-4o supports)
92
92
  print(gpt4o.can_be_replaced_by(gemini)) # False
93
93
 
94
94
  # If we only require vision and function_calling, gemini-3.5-flash can replace gpt-4o
@@ -154,6 +154,47 @@ print(cap.context_window) # 131072
154
154
  print(cap.pricing) # {'input_per_1m': 0.1, 'output_per_1m': 0.32, 'currency': 'USD'}
155
155
  ```
156
156
 
157
+ ### Token Counting (Standalone)
158
+
159
+ Count tokens for a single text or a list of chat messages using the best available tokenizer for a given model.
160
+
161
+ ```python
162
+ # Count tokens for a text string
163
+ import llmcapa
164
+ tokens = llmcapa.count_tokens("Hello, world!", "gpt-4o")
165
+ print(tokens) # exact count if tiktoken is installed, else estimation
166
+
167
+ # Count tokens for chat messages (includes overhead)
168
+ messages = [
169
+ {"role": "user", "content": "Hello"},
170
+ {"role": "assistant", "content": "Hi there!"},
171
+ ]
172
+ total = llmcapa.count_messages_tokens(messages, "gpt-4o")
173
+ print(total)
174
+ ```
175
+
176
+ ### Programmatic Registration
177
+
178
+ Register a Capability directly without a JSON file:
179
+
180
+ ```python
181
+ from llmcapa import Capability
182
+
183
+ cap = Capability(
184
+ provider="local",
185
+ model_id="my-model",
186
+ context_window=4096,
187
+ max_output_tokens=1024,
188
+ supports_function_calling=True,
189
+ aliases=["mm"],
190
+ )
191
+ llmcapa.register(cap)
192
+
193
+ print(llmcapa.get("my-model").context_window) # 4096
194
+ ```
195
+
196
+ > **Note**: `llmcapa.get()` raises `ModelNotFoundError` if the model is not found.
197
+
157
198
  ### Custom Local Data
158
199
 
159
200
  Load your own model definitions from a local JSON file:
@@ -197,6 +238,13 @@ llmcapa list --json --no-deprecated
197
238
  # List all known providers
198
239
  llmcapa providers
199
240
 
241
+ # Count tokens for text or messages
242
+ llmcapa tokens gpt-4o "Hello, world!"
243
+ llmcapa tokens gpt-4o --messages '[{"role":"user","content":"Hi"}]'
244
+
245
+ # Load extra model data from a local JSON file on startup
246
+ llmcapa --extra my_models.json show gpt-4o
247
+
200
248
  # Explicitly fetch and update the OpenRouter models cache (forces cache refresh)
201
249
  llmcapa update
202
250
  ```
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "llmcapa"
7
- version = "0.2.2"
7
+ version = "0.2.4"
8
8
  description = "Lookup capabilities (context window, modalities, features) of various LLM models offline."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "llmcapa"
7
+ version = "0.2.3"
8
+ description = "Lookup capabilities (context window, modalities, features) of various LLM models offline."
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Hirofumi Ukawa", email = "hirofumi@ukawa.biz" }]
13
+ keywords = ["llm", "capability", "openai", "anthropic", "gemini", "models"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: Apache Software License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Software Development :: Libraries",
26
+ ]
27
+
28
+ [project.scripts]
29
+ llmcapa = "llmcapa.cli:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/awaku7/llmcapa"
33
+ Repository = "https://github.com/awaku7/llmcapa"
34
+ "Bug Tracker" = "https://github.com/awaku7/llmcapa/issues"
35
+
36
+ [project.optional-dependencies]
37
+ openai = ["tiktoken>=0.5.0"]
38
+ gemini = ["sentencepiece>=0.2.0"]
39
+ all = ["tiktoken>=0.5.0", "sentencepiece>=0.2.0"]
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/llmcapa"]
@@ -0,0 +1,92 @@
1
+ """llmcapa: lookup capabilities of various LLM models, fully offline.
2
+
3
+ Example:
4
+ >>> import llmcapa
5
+ >>> cap = llmcapa.get("gpt-4o")
6
+ >>> cap.context_window
7
+ 128000
8
+ >>> cap.supports("vision")
9
+ True
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import List, Optional, Union
15
+ from pathlib import Path
16
+
17
+ from .models import Capability, Feature, ReasoningEffort
18
+ from .registry import Registry, ModelNotFoundError, default_registry
19
+ from .tokenizer import count_tokens, count_messages_tokens
20
+
21
+ __version__ = "0.2.4"
22
+
23
+ __all__ = [
24
+ "Capability",
25
+ "Feature",
26
+ "ReasoningEffort",
27
+ "Registry",
28
+ "ModelNotFoundError",
29
+ "get",
30
+ "list_models",
31
+ "providers",
32
+ "find",
33
+ "search",
34
+ "load_extra",
35
+ "fetch_openrouter",
36
+ "register",
37
+ "default_registry",
38
+ "count_tokens",
39
+ "count_messages_tokens",
40
+ "__version__",
41
+ ]
42
+
43
+
44
+ def get(model_id: str) -> Capability:
45
+ """Return the Capability for a model id or alias."""
46
+ return default_registry().get(model_id)
47
+
48
+
49
+ def list_models(
50
+ provider: Optional[str] = None,
51
+ include_deprecated: bool = True,
52
+ ) -> List[Capability]:
53
+ """List known models, optionally filtered by provider."""
54
+ return default_registry().list_models(provider, include_deprecated)
55
+
56
+
57
+ def providers() -> List[str]:
58
+ """Return the sorted list of known providers."""
59
+ return default_registry().providers()
60
+
61
+
62
+ def find(**kwargs) -> List[Capability]:
63
+ """Search models by conditions. See Registry.find."""
64
+ return default_registry().find(**kwargs)
65
+
66
+
67
+ def search(
68
+ prefix: str,
69
+ provider: Optional[str] = None,
70
+ include_deprecated: bool = False,
71
+ limit: Optional[int] = None,
72
+ ) -> List[Capability]:
73
+ """Search models by prefix matching on model_id, display_name, or aliases.
74
+
75
+ Case-insensitive prefix search. Results are sorted by (provider, model_id).
76
+ """
77
+ return default_registry().search(prefix, provider, include_deprecated, limit)
78
+
79
+
80
+ def load_extra(path: Union[str, Path]) -> int:
81
+ """Load user-defined model data from a local JSON file."""
82
+ return default_registry().load_extra(path)
83
+
84
+
85
+ def fetch_openrouter(cache_ttl: Optional[int] = None) -> int:
86
+ """Fetch all models dynamically from OpenRouter API and register them."""
87
+ return default_registry().fetch_openrouter(cache_ttl)
88
+
89
+
90
+ def register(cap: Capability) -> None:
91
+ """Register (or override) a Capability in the default registry."""
92
+ default_registry().register(cap)
@@ -18,7 +18,7 @@ from .models import Capability, Feature, ReasoningEffort
18
18
  from .registry import Registry, ModelNotFoundError, default_registry
19
19
  from .tokenizer import count_tokens, count_messages_tokens
20
20
 
21
- __version__ = "0.2.0"
21
+ __version__ = "0.2.3"
22
22
 
23
23
  __all__ = [
24
24
  "Capability",
@@ -0,0 +1,79 @@
1
+ """llmcapa: lookup capabilities of various LLM models, fully offline.
2
+
3
+ Example:
4
+ >>> import llmcapa
5
+ >>> cap = llmcapa.get("gpt-4o")
6
+ >>> cap.context_window
7
+ 128000
8
+ >>> cap.supports("vision")
9
+ True
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import List, Optional, Union
15
+ from pathlib import Path
16
+
17
+ from .models import Capability, Feature, ReasoningEffort
18
+ from .registry import Registry, ModelNotFoundError, default_registry
19
+ from .tokenizer import count_tokens, count_messages_tokens
20
+
21
+ __version__ = "0.2.3"
22
+
23
+ __all__ = [
24
+ "Capability",
25
+ "Feature",
26
+ "ReasoningEffort",
27
+ "Registry",
28
+ "ModelNotFoundError",
29
+ "get",
30
+ "list_models",
31
+ "providers",
32
+ "find",
33
+ "search",
34
+ "load_extra",
35
+ "fetch_openrouter",
36
+ "register",
37
+ "default_registry",
38
+ "count_tokens",
39
+ "count_messages_tokens",
40
+ "__version__",
41
+ ]
42
+
43
+
44
+ def get(model_id: str) -> Capability:
45
+ """Return the Capability for a model id or alias."""
46
+ return default_registry().get(model_id)
47
+
48
+
49
+ def list_models(
50
+ provider: Optional[str] = None,
51
+ include_deprecated: bool = True,
52
+ ) -> List[Capability]:
53
+ """List known models, optionally filtered by provider."""
54
+ return default_registry().list_models(provider, include_deprecated)
55
+
56
+
57
+ def providers() -> List[str]:
58
+ """Return the sorted list of known providers."""
59
+ return default_registry().providers()
60
+
61
+
62
+ def find(**kwargs) -> List[Capability]:
63
+ """Search models by conditions. See Registry.find."""
64
+ return default_registry().find(**kwargs)
65
+
66
+
67
+ def load_extra(path: Union[str, Path]) -> int:
68
+ """Load user-defined model data from a local JSON file."""
69
+ return default_registry().load_extra(path)
70
+
71
+
72
+ def fetch_openrouter(cache_ttl: Optional[int] = None) -> int:
73
+ """Fetch all models dynamically from OpenRouter API and register them."""
74
+ return default_registry().fetch_openrouter(cache_ttl)
75
+
76
+
77
+ def register(cap: Capability) -> None:
78
+ """Register (or override) a Capability in the default registry."""
79
+ default_registry().register(cap)
@@ -0,0 +1,92 @@
1
+ """llmcapa: lookup capabilities of various LLM models, fully offline.
2
+
3
+ Example:
4
+ >>> import llmcapa
5
+ >>> cap = llmcapa.get("gpt-4o")
6
+ >>> cap.context_window
7
+ 128000
8
+ >>> cap.supports("vision")
9
+ True
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import List, Optional, Union
15
+ from pathlib import Path
16
+
17
+ from .models import Capability, Feature, ReasoningEffort
18
+ from .registry import Registry, ModelNotFoundError, default_registry
19
+ from .tokenizer import count_tokens, count_messages_tokens
20
+
21
+ __version__ = "0.2.3"
22
+
23
+ __all__ = [
24
+ "Capability",
25
+ "Feature",
26
+ "ReasoningEffort",
27
+ "Registry",
28
+ "ModelNotFoundError",
29
+ "get",
30
+ "list_models",
31
+ "providers",
32
+ "find",
33
+ "search",
34
+ "load_extra",
35
+ "fetch_openrouter",
36
+ "register",
37
+ "default_registry",
38
+ "count_tokens",
39
+ "count_messages_tokens",
40
+ "__version__",
41
+ ]
42
+
43
+
44
+ def get(model_id: str) -> Capability:
45
+ """Return the Capability for a model id or alias."""
46
+ return default_registry().get(model_id)
47
+
48
+
49
+ def list_models(
50
+ provider: Optional[str] = None,
51
+ include_deprecated: bool = True,
52
+ ) -> List[Capability]:
53
+ """List known models, optionally filtered by provider."""
54
+ return default_registry().list_models(provider, include_deprecated)
55
+
56
+
57
+ def providers() -> List[str]:
58
+ """Return the sorted list of known providers."""
59
+ return default_registry().providers()
60
+
61
+
62
+ def find(**kwargs) -> List[Capability]:
63
+ """Search models by conditions. See Registry.find."""
64
+ return default_registry().find(**kwargs)
65
+
66
+
67
+ def search(
68
+ prefix: str,
69
+ provider: Optional[str] = None,
70
+ include_deprecated: bool = False,
71
+ limit: Optional[int] = None,
72
+ ) -> List[Capability]:
73
+ """Search models by prefix matching on model_id, display_name, or aliases.
74
+
75
+ Case-insensitive prefix search. Results are sorted by (provider, model_id).
76
+ """
77
+ return default_registry().search(prefix, provider, include_deprecated, limit)
78
+
79
+
80
+ def load_extra(path: Union[str, Path]) -> int:
81
+ """Load user-defined model data from a local JSON file."""
82
+ return default_registry().load_extra(path)
83
+
84
+
85
+ def fetch_openrouter(cache_ttl: Optional[int] = None) -> int:
86
+ """Fetch all models dynamically from OpenRouter API and register them."""
87
+ return default_registry().fetch_openrouter(cache_ttl)
88
+
89
+
90
+ def register(cap: Capability) -> None:
91
+ """Register (or override) a Capability in the default registry."""
92
+ default_registry().register(cap)