Skip to content

Instantly share code, notes, and snippets.

@zsmatrix62
Last active September 3, 2025 04:57
Show Gist options
  • Save zsmatrix62/2707627362209258d347dd41bee9af79 to your computer and use it in GitHub Desktop.
Save zsmatrix62/2707627362209258d347dd41bee9af79 to your computer and use it in GitHub Desktop.
Nushell 脚本 提供 `md` 和 `md2` 命令,用于在 Claude Code 中使用 ModelScope.cn 的模型
# ModelScope CLI 辅助函数
## 功能说明
# 此模块提供 `md` 和 `md2` 命令,用于在 Claude Code 中使用 ModelScope.cn 的模型。
## 环境要求
# 在使用前,需要设置以下环境变量:
#
# - `MODELSCOPE_API_KEY`: ModelScope API 密钥(必需)
# - `ANTHROPIC_AUTH_TOKEN`: 用于 `md` 命令的认证令牌
# - `ANTHROPIC_AUTH_TOKEN2`: 用于 `md2` 命令的认证令牌(可选)
## 使用方法
# ```nu
# # 使用默认模型
# md <model_name> [args...]
#
# # 使用第二个认证令牌
# # md2 <model_name> [args...]
# ```
## 模型过滤
# 系统默认过滤包含以下关键词的模型:
# - "GLM-4.5"
# - "Qwen3-Coder-480B"
## 缓存机制
# - 系统会缓存模型列表 24 小时以提高性能
# - 缓存文件位置:系统临时目录下的 `modelscope-models-cache.txt`
# - 可以通过清除缓存来强制刷新模型列表
## 模型列表
# 支持的模型会从 https://models.dev/api.json 自动获取,只包含支持工具调用的 ModelScope 模型。
# Cache file path
const CACHE_FILE = $"($nu.temp-path)/modelscope-models-cache.txt"
const CACHE_DURATION = "24hr" # 24 hours expiration
# Check if cache is valid (not expired)
def is-cache-valid [] {
if not ($CACHE_FILE | path exists) {
return false
}
try {
let file_info = (ls $CACHE_FILE | get 0)
let file_age = (date now) - $file_info.modified
let max_age = ($CACHE_DURATION | into duration)
$file_age <= $max_age
} catch {
# If there's any error reading the file, consider cache invalid
false
}
}
# Get cached model names or fetch fresh data
def get-api-data [] {
if (is-cache-valid) {
try {
print "Using cached model names"
let cached_model_names = ($CACHE_FILE | open | lines)
print $"Cache data loaded successfully with ($cached_model_names | length) models"
return $cached_model_names
} catch {|e|
# If cache is corrupted, fetch fresh data
print $"Cache corrupted, error: ($e.msg)"
fetch-fresh-api-data
}
} else {
print "Cache expired or not found, fetching fresh data"
fetch-fresh-api-data
}
}
# Fetch fresh API data and cache it
def fetch-fresh-api-data [] {
print "Fetching fresh API data from https://models.dev/api.json"
let api_data = (curl -s "https://models.dev/api.json" | from json)
# Extract and cache only the model names we need
let model_names = ($api_data.modelscope.models |
transpose key value |
where value.tool_call == true |
get key |
sort)
print $"Caching ($model_names | length) model names"
# Save only the model names to cache as plain text (one per line)
$model_names | str join "\n" | save $CACHE_FILE --force
$model_names
}
# Clear cache file
def clear-cache [] {
if ($CACHE_FILE | path exists) {
rm $CACHE_FILE
print "Cache cleared successfully"
} else {
print "No cache file found"
}
}
# Available models for auto-completion - fetched from API with cache
def get-available-models [...keywords: string] {
let model_names = (get-api-data)
if ($keywords | length) > 0 {
$model_names | where {|model|
$keywords | any {|keyword| $model | str contains $keyword}
}
} else {
$model_names
}
}
# Create profile configuration for a specific model
def create-model-profile [model_name: string] {
{
base_url: "https://api-inference.modelscope.cn",
default_model: $model_name,
default_small_model: $model_name,
api_key: ($env.MODELSCOPE_API_KEY? | default "")
}
}
# Get available profile names for auto-completion
export def get-anthropic-profiles [] {
get-available-models "GLM-4.5" "Qwen3-Coder-480B"
}
# Get profile configuration
def get-profile-config [profile: string] {
create-model-profile $profile
}
# Generic function to get config for a specific profile with custom auth token variable
def get-anthropic-config [profile: string, auth_token_var: string = "ANTHROPIC_AUTH_TOKEN"] {
let profile_config = (get-profile-config $profile)
{
ANTHROPIC_BASE_URL: $profile_config.base_url,
ANTHROPIC_AUTH_TOKEN: $profile_config.api_key,
ANTHROPIC_MODEL: ($env | get -i $"($profile | str upcase)_MODEL" | default $profile_config.default_model),
ANTHROPIC_SMALL_FAST_MODEL: ($env | get -i $"($profile | str upcase)_SMALL_FAST_MODEL" | default $profile_config.default_small_model)
}
}
# Generic function to run claude with custom auth token variable
def run-claude-with-profile [profile: string, auth_token_var: string, ...args] {
let config = (get-anthropic-config $profile $auth_token_var)
# Set environment variables
load-env {
ANTHROPIC_BASE_URL: $config.ANTHROPIC_BASE_URL,
$"($auth_token_var)": $config.ANTHROPIC_AUTH_TOKEN,
ANTHROPIC_MODEL: $config.ANTHROPIC_MODEL,
ANTHROPIC_SMALL_FAST_MODEL: $config.ANTHROPIC_SMALL_FAST_MODEL
}
# Run claude command with the new environment
^claude ...$args
}
# Main md command that overwrites environment variables and runs claude
export def md [
profile: string@get-anthropic-profiles,
...args
] {
run-claude-with-profile $profile "ANTHROPIC_AUTH_TOKEN" ...$args
}
# Main md2 command that overwrites environment variables and runs claude using ANTHROPIC_AUTH_TOKEN2
export def md2 [
profile: string@get-anthropic-profiles,
...args
] {
run-claude-with-profile $profile "ANTHROPIC_AUTH_TOKEN2" ...$args
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment