vault-cli: tiered analyze — Haiku default, --sonnet/--opus step up

vault analyze now defaults to Haiku/Bedrock (cheap+fast, the nightly tier)
instead of the profile default. --sonnet and --opus step intelligence/cost up
for harder judgment calls; raw -m/--provider still override entirely. Provider
is forced to bedrock only for the haiku (us.anthropic.*) tier; the
global.anthropic.* sonnet/opus IDs use the profile default provider. Adds an
alive banner to stderr (headless -z buffers, so a pass is silent 1-3 min).
This commit is contained in:
Hermes Agent
2026-07-22 12:34:32 -04:00
parent e535ee3608
commit b665413630
+49 -16
View File
@@ -15,11 +15,11 @@ Subcommands:
vault sync-data reconcile /data skeleton to match manifest (create missing dirs)
vault manifest regenerate the topology manifest note
vault report [--pretty] deterministic Librarian report (delegates to vault-librarian.py)
vault analyze [-m MODEL] [--provider PROVIDER]
spawn a Hermes Librarian pass (ad-hoc; uses the cron prompt).
-m/--provider dial intelligence/spend inline. e.g. nightly cheap:
vault analyze -m us.anthropic.claude-haiku-4-5-20251001-v1:0 --provider bedrock
omit both to use the profile's default (smart) model.
vault analyze [--sonnet|--opus] [-m MODEL] [--provider PROVIDER]
spawn a Hermes Librarian pass. DEFAULT: Haiku/Bedrock
(cheap+fast — the nightly/weekly tier). --sonnet / --opus
step up intelligence & cost for harder judgment calls.
-m/--provider override entirely (future/non-Bedrock models).
"""
import os, re, sys, subprocess
@@ -32,6 +32,19 @@ HERMES = "/run/current-system/sw/bin/hermes"
LIBRARIAN = os.path.join(_SELF_DIR, "vault-librarian.py")
PROMPT = os.path.join(_SELF_DIR, "vault-librarian-prompt.md")
# `vault analyze` model tiers. Default is Haiku — cheap+fast for the nightly/weekly
# pass. --sonnet / --opus step up intelligence & cost inline. IDs verified against
# this host's Hermes config + the active Bedrock provisioning.
ANALYZE_TIERS = {
"haiku": "us.anthropic.claude-haiku-4-5-20251001-v1:0",
"sonnet": "global.anthropic.claude-sonnet-5",
"opus": "global.anthropic.claude-opus-4-8",
}
# Only the haiku (us.anthropic.*) tier is known to route via an explicit `bedrock`
# provider. The global.anthropic.* IDs use the profile's default provider unless the
# caller passes --provider, to avoid a provider/model-registration mismatch.
ANALYZE_TIER_PROVIDER = {"haiku": "bedrock"}
WIKILINK_RE = re.compile(r'(!?\[\[)([^\]#|]+)((?:#[^\]|]+)?(?:\|[^\]]+)?)(\]\])')
@@ -135,21 +148,41 @@ def main():
sys.exit(subprocess.run([sys.executable, LIBRARIAN] + argv).returncode)
elif cmd == "analyze":
prompt = open(PROMPT, encoding="utf-8").read()
# `vault analyze [-m MODEL]` — pass an inline Bedrock/other model through to hermes -z
# so intelligence/spend can be dialed per cadence (nightly cheap, ad-hoc smart).
hcmd = [HERMES, "-z", prompt]
# Model tier: default Haiku (cheap nightly). --sonnet/--opus step up.
# Raw -m/--provider override the tier entirely (escape hatch for future models
# or non-Bedrock providers). Tier flags are last-wins if combined.
tier = "haiku"
if "--sonnet" in argv:
tier = "sonnet"
if "--opus" in argv:
tier = "opus"
model = ANALYZE_TIERS[tier]
provider = ANALYZE_TIER_PROVIDER.get(tier) # None for sonnet/opus (use profile default)
if "-m" in argv:
i = argv.index("-m")
if i + 1 < len(argv):
hcmd += ["-m", argv[i + 1]]
else:
die("-m requires a model name (e.g. vault analyze -m us.anthropic.claude-haiku-4-5-20251001-v1:0)")
if i + 1 >= len(argv):
die("-m requires a model name")
model = argv[i + 1]
tier = "custom"
provider = None # custom model: don't force a provider unless asked
if "--provider" in argv:
i = argv.index("--provider")
if i + 1 < len(argv):
hcmd += ["--provider", argv[i + 1]]
else:
die("--provider requires a provider name (e.g. vault analyze --provider bedrock)")
if i + 1 >= len(argv):
die("--provider requires a provider name")
provider = argv[i + 1]
hcmd = [HERMES, "-z", prompt, "-m", model]
if provider:
hcmd += ["--provider", provider]
# Banner: headless oneshot buffers output, so show it's alive + what it costs.
print(f"→ spawning Hermes Librarian pass [tier={tier} provider={provider or 'profile-default'}]",
file=sys.stderr)
print(f" model: {model}", file=sys.stderr)
print(" output is buffered; a full pass can take 1–3 min before you see anything.",
file=sys.stderr)
if tier == "haiku":
print(" step up: vault analyze --sonnet (or --opus) for harder judgment calls",
file=sys.stderr)
sys.stderr.flush()
subprocess.run(hcmd)
else:
die(f"unknown command '{cmd}'")