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.
- {llmcapa-0.2.2 → llmcapa-0.2.4}/DEVELOP.ja.md +1 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/DEVELOP.md +1 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/PKG-INFO +54 -6
- {llmcapa-0.2.2 → llmcapa-0.2.4}/README.ja.md +53 -5
- {llmcapa-0.2.2 → llmcapa-0.2.4}/README.md +53 -5
- {llmcapa-0.2.2 → llmcapa-0.2.4}/pyproject.toml +1 -1
- llmcapa-0.2.4/pyproject.toml.org +42 -0
- llmcapa-0.2.4/src/llmcapa/__init__.py +92 -0
- llmcapa-0.2.2/src/llmcapa/__init__.py → llmcapa-0.2.4/src/llmcapa/__init__.py.org +1 -1
- llmcapa-0.2.4/src/llmcapa/__init__.py.org1 +79 -0
- llmcapa-0.2.4/src/llmcapa/__init__.py.org2 +92 -0
- llmcapa-0.2.4/src/llmcapa/cli.py +204 -0
- llmcapa-0.2.4/src/llmcapa/data/azure_foundry.json +6571 -0
- llmcapa-0.2.4/src/llmcapa/data/xai.json +287 -0
- llmcapa-0.2.4/src/llmcapa/registry.py +368 -0
- llmcapa-0.2.4/xai_console.png +0 -0
- llmcapa-0.2.2/src/llmcapa/data/azure_foundry.json +0 -33179
- llmcapa-0.2.2/src/llmcapa/data/xai.json +0 -68
- {llmcapa-0.2.2 → llmcapa-0.2.4}/.gitignore +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/LICENSE +0 -0
- /llmcapa-0.2.2/src/llmcapa/cli.py → /llmcapa-0.2.4/src/llmcapa/cli.py.org +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/__init__.py +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/amazon.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/anthropic.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/deepseek.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/google.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/japanese.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/meta.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/microsoft.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/mistral.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/moonshot.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/nvidia.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/openai.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/openrouter.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/data/qwen.json +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/models.py +0 -0
- /llmcapa-0.2.2/src/llmcapa/registry.py → /llmcapa-0.2.4/src/llmcapa/registry.py.org +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/src/llmcapa/tokenizer.py +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/tests/test_advanced.py +0 -0
- {llmcapa-0.2.2 → llmcapa-0.2.4}/tests/test_cache.py +0 -0
- {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.
|
|
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', '
|
|
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
|
|
321
|
-
print(gpt4o.can_be_replaced_by(gpt4o_mini)) #
|
|
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
|
|
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', '
|
|
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
|
|
89
|
-
print(gpt4o.can_be_replaced_by(gpt4o_mini)) #
|
|
88
|
+
# gpt-4o-miniは同じコンテキストウィンドウを持ち、同じ機能をすべてサポートしています
|
|
89
|
+
print(gpt4o.can_be_replaced_by(gpt4o_mini)) # True
|
|
90
90
|
|
|
91
|
-
# gemini-3.5-flash
|
|
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', '
|
|
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
|
|
89
|
-
print(gpt4o.can_be_replaced_by(gpt4o_mini)) #
|
|
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
|
|
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.
|
|
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.
|
|
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)
|