feat: add Friendli serverless models to auto price/context sync

Adds transform_friendli_data() to auto_update_price_and_context_window_file.py
and registers https://api.friendli.ai/serverless/v1/models as a sync source.

Also adds the current 7 Friendli serverless models to the backup JSON:
- friendliai/Qwen/Qwen3-235B-A22B-Instruct-2507
- friendliai/LGAI-EXAONE/K-EXAONE-236B-A23B
- friendliai/MiniMaxAI/MiniMax-M2.5
- friendliai/deepseek-ai/DeepSeek-V3.2
- friendliai/zai-org/GLM-5.1
- friendliai/google/gemma-4-31B-it
- friendliai/zai-org/GLM-5.2
This commit is contained in:
Lee-Si-Yoon 2026-07-26 20:23:14 +09:00
parent 24123269cc
commit f13325aca9
2 changed files with 153 additions and 2 deletions

View file

@ -110,6 +110,61 @@ def transform_vercel_ai_gateway_data(data):
return transformed
def transform_friendli_data(data):
transformed = {}
for row in data:
f = row.get("functionality", {}) or {}
p = row.get("pricing", {}) or {}
inp = row.get("input_modalities", []) or []
out = row.get("output_modalities", []) or []
obj = {
"max_input_tokens": row.get("context_length"),
"max_output_tokens": row.get("max_completion_tokens"),
"max_tokens": row.get("max_completion_tokens") or row.get("context_length"),
"input_cost_per_token": float(p.get("input", 0)),
"output_cost_per_token": float(p.get("output", 0)),
"supports_function_calling": bool(f.get("tool_call")),
"supports_parallel_function_calling": bool(f.get("parallel_tool_call")),
"supports_response_schema": bool(f.get("structured_output")),
"litellm_provider": "friendliai",
"mode": row.get("mode", "chat"),
}
# cache pricing (optional)
if p.get("input_cache_read") is not None:
obj["cache_read_input_token_cost"] = float(p["input_cache_read"])
if p.get("cache_write") is not None:
obj["cache_creation_input_token_cost"] = float(p["cache_write"])
# only set these when the API actually returns them — don't overwrite
# an existing true with false just because the field is absent.
if f.get("tool_choice") is not None:
obj["supports_tool_choice"] = bool(f["tool_choice"])
if f.get("system_messages") is not None:
obj["supports_system_messages"] = bool(f["system_messages"])
# reasoning
if row.get("reasoning"):
obj["supports_reasoning"] = True
# deprecation
if v := row.get("deprecation_date"):
obj["deprecation_date"] = v[:10]
# vision modality
if "image" in inp or "video" in inp:
obj["supports_vision"] = True
if inp:
obj["supported_modalities"] = inp
if out:
obj["supported_output_modalities"] = out
transformed[f'friendliai/{row["id"]}'] = obj
return transformed
# Load local data from a specified file
def load_local_data(file_path):
try:
@ -130,6 +185,7 @@ def main():
local_file_path = "model_prices_and_context_window.json" # Path to the local data file
openrouter_url = "https://openrouter.ai/api/v1/models" # URL to fetch OpenRouter data
vercel_ai_gateway_url = "https://ai-gateway.vercel.sh/v1/models" # URL to fetch Vercel AI Gateway data
friendli_url = "https://api.friendli.ai/serverless/v1/models" # URL to fetch Friendli serverless data
# Load local data from file
local_data = load_local_data(local_file_path)
@ -143,9 +199,14 @@ def main():
vercel_data = asyncio.run(fetch_data(vercel_ai_gateway_url))
# Transform the fetched Vercel AI Gateway data
vercel_data = transform_vercel_ai_gateway_data(vercel_data)
# Fetch Friendli serverless data
friendli_data = asyncio.run(fetch_data(friendli_url))
# Transform the fetched Friendli data
friendli_data = transform_friendli_data(friendli_data)
# Combine both datasets
all_remote_data = {**openrouter_data, **vercel_data}
# Combine all datasets
all_remote_data = {**openrouter_data, **vercel_data, **friendli_data}
# If both local and openrouter data are available, synchronize and save
if local_data and all_remote_data:

View file

@ -46194,5 +46194,95 @@
}
}
]
},
"friendliai/Qwen/Qwen3-235B-A22B-Instruct-2507": {
"max_input_tokens": 262144,
"max_output_tokens": 262144,
"max_tokens": 262144,
"input_cost_per_token": 2e-07,
"output_cost_per_token": 8e-07,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"deprecation_date": "2026-08-05"
},
"friendliai/LGAI-EXAONE/K-EXAONE-236B-A23B": {
"max_input_tokens": 262144,
"max_output_tokens": 262144,
"max_tokens": 262144,
"input_cost_per_token": 2e-07,
"output_cost_per_token": 8e-07,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"cache_read_input_token_cost": 1e-07
},
"friendliai/MiniMaxAI/MiniMax-M2.5": {
"max_input_tokens": 196608,
"max_output_tokens": 196608,
"max_tokens": 196608,
"input_cost_per_token": 3e-07,
"output_cost_per_token": 1.2e-06,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"cache_read_input_token_cost": 6e-08
},
"friendliai/deepseek-ai/DeepSeek-V3.2": {
"max_input_tokens": 163840,
"max_output_tokens": 163840,
"max_tokens": 163840,
"input_cost_per_token": 5e-07,
"output_cost_per_token": 1.5e-06,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"cache_read_input_token_cost": 2.5e-07
},
"friendliai/zai-org/GLM-5.1": {
"max_input_tokens": 202752,
"max_output_tokens": 202752,
"max_tokens": 202752,
"input_cost_per_token": 1.4e-06,
"output_cost_per_token": 4.4e-06,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"cache_read_input_token_cost": 2.6e-07
},
"friendliai/google/gemma-4-31B-it": {
"max_input_tokens": 262144,
"max_output_tokens": 262144,
"max_tokens": 262144,
"input_cost_per_token": 1.4e-07,
"output_cost_per_token": 4e-07,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat"
},
"friendliai/zai-org/GLM-5.2": {
"max_input_tokens": 1048576,
"max_output_tokens": 1048576,
"max_tokens": 1048576,
"input_cost_per_token": 1.4e-06,
"output_cost_per_token": 4.4e-06,
"supports_function_calling": true,
"supports_parallel_function_calling": true,
"supports_response_schema": true,
"litellm_provider": "friendliai",
"mode": "chat",
"cache_read_input_token_cost": 2.6e-07
}
}