소스 정보
- 저장소
- chchchadzilla/hermes-openrouter-model-picker
- 최근 소스 활동
- 2026년 8월 26일 08:28
- 감지된 SKILL.md 언어
- 영어
- 스타
- 0
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/chchchadzilla/hermes-openrouter-model-picker --skill hermes-openrouter-model-picker명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | hermes-openrouter-model-picker |
| description | Fix missing models in Hermes /model picker. |
| version | 1.0.0 |
| author | ajax |
| license | MIT |
| platforms | ["linux","macos","windows"] |
| metadata | {"hermes":{"tags":["hermes","openrouter","models","model-picker","cache","cron","troubleshooting"],"related_skills":["hermes-agent"]}} |
Two jobs:
/model.Both hinge on one fact most people miss, so read the next section before touching anything.
/model renders the INTERSECTION of two independent caches. A model must be in
BOTH or it silently vanishes. No error, no warning.
| # | File | Role | TTL |
|---|---|---|---|
| 1 | $HERMES_HOME/cache/model_catalog.json | curated manifest — what's allowed | 1h (model_catalog.ttl_hours) |
| 2 | $HERMES_HOME/provider_models_cache.json | live /v1/models ids — what's available | 1h TTL, 7-day stale-serve |
Cache #2 is the trap. In hermes_cli/models.py:
_PROVIDER_MODELS_CACHE_TTL = 3600 # 1h
_PROVIDER_MODELS_STALE_SERVE_MAX = 7 * 24 * 3600 # 7d <-- the trap
An expired entry whose credential fingerprint still matches is served immediately from disk while a daemon thread refetches in the background. That thread only rewrites the disk file — it never updates the list already handed to the picker. Net effect: a newly-released model can be correct in cache #1 and still not render for up to 7 days.
hermes model --refresh does NOT fix this. It clears the picker/catalog caches,
not provider_models_cache.json. This is the single most common wrong turn.
Ordering also comes from cache #1 — the picker preserves manifest order, which is why overriding the manifest is what gives you a chronological list.
Never trust the config; check both caches. Substitute the real model id.
# Step 1 — does it exist upstream at all, and does it support tools?
curl -s https://openrouter.ai/api/v1/models \
| python3 -c "
import json,sys
want='z-ai/glm-5.3'
for m in json.load(sys.stdin)['data']:
if m['id']==want:
sp=m.get('supported_parameters') or []
print(want,'exists | tools:', 'tools' in sp)
break
else: print(want,'NOT on OpenRouter')"
If tools: False, stop — Hermes requires tool calling and deliberately hides such
models (selecting one fails at runtime). That is correct behavior, not a bug.
# Step 2 — which cache is lying? (run from the Hermes install dir, using ITS venv)
cd /usr/local/lib/hermes-agent && ./venv/bin/python -c "
import json, os
from hermes_cli.model_catalog import get_curated_openrouter_models
home=os.environ.get('HERMES_HOME') or os.path.expanduser('~/.hermes')
cur=[m for m,_ in (get_curated_openrouter_models() or [])]
live=json.load(open(f'{home}/provider_models_cache.json')).get('openrouter',{}).get('models',[])
w='z-ai/glm-5.3'
print('in manifest (cache #1):', w in cur)
print('in live cache (cache #2):', w in live)
"
# Step 3 — the actual fix for cache #2
cd /usr/local/lib/hermes-agent && ./venv/bin/python -c "
from hermes_cli import models as M
M.clear_provider_models_cache('openrouter')
ids = M.cached_provider_model_ids('openrouter') # forces live re-fetch
print('rebuilt:', len(ids), 'models')
"
# Step 4 — verify what the picker will ACTUALLY render (end-to-end, not per-cache)
cd /usr/local/lib/hermes-agent && ./venv/bin/python -c "
from hermes_cli import models as M
from hermes_cli.model_catalog import reset_cache
reset_cache(); M._openrouter_catalog_cache=None
lst=M.fetch_openrouter_models(force_refresh=True)
ids=[m for m,_ in lst]
print('entries:',len(lst))
for w in ('z-ai/glm-5.3','google/gemini-3.7-flash'):
print(' ',w,'->','OK' if w in ids else 'MISSING')
"
A live TUI holds warm in-process copies. After fixing on disk, /reload or start a
fresh session.
model_catalog.providers.<provider>.url overrides the curated list for one provider.
Point it at a locally-generated manifest and you control both membership and order.
Override fetches skip the disk cache and re-read on every picker open, so the file
is always as fresh as its last regeneration.
file:// URLs work — they pass _fetch_manifest + schema validation.
Ship scripts/openrouter_chrono_catalog.py (in this skill) and wire it:
cp scripts/openrouter_chrono_catalog.py ~/.hermes/scripts/
python3 ~/.hermes/scripts/openrouter_chrono_catalog.py 100
hermes config set model_catalog.providers.openrouter.url \
"file://$HOME/.hermes/cache/openrouter_chrono.json"
Filtering the script applies (~417 raw → 100):
:batch — async-only endpoints, unusable for interactive chat~alias — floating pointers (~z-ai/glm-latest) that duplicate a concrete idThe script sorts by the created field (every entry has one) and writes a
schema-version-1 manifest. Release date goes in description, though Hermes overwrites
that with its own recommended/free/default badge on some rows — picker-side, unavoidable.
Crucially the script also busts cache #2 whenever top-100 membership changes. Regenerating the manifest alone reintroduces the exact bug in Part 1.
cronjob(action='create', name='openrouter-chrono-catalog-refresh',
schedule='0 */6 * * *', script='openrouter_chrono_catalog.py',
no_agent=True, deliver='local',
prompt='Refresh the chronological OpenRouter model manifest.')
no_agent=True → scheduler runs the script and delivers stdout verbatim. Zero tokens.
hermes model --refresh doesn't clear provider_models_cache.json. Biggest time sink.config.yaml — use hermes config set; a stray indent breaks the live gateway.script takes a bare filename relative to ~/.hermes/scripts/. Absolute paths are
rejected, and argv can't be passed — for flags like --quiet, ship a .sh wrapper./usr/local/lib/hermes-agent/venv/bin/python) for hermes_cli
imports; system python3 lacks the deps. Keep cron scripts dependency-free (stdlib only)
so they run under plain python3 — do JSON surgery instead of importing hermes_cli.&&/heredocs in one terminal call — the parser
blocklist trips on oversized inline payloads. One command per call, or execute_code.provider_models_cache.json; other providers
(xai-oauth, gemini, …) share the file. Verify they survive.fetch_openrouter_models check.tools: False is working as intended — don't "fix" it.fetch_openrouter_models() returns the expected count.:batch / ~alias ids leaked (chronological mode).provider_models_cache.json.ok (cronjob action='run').