Token Optimizer
Find potential token waste in OpenClaw or Hermes Agent. Use when asked to reduce AI costs, review model choices, check large instructions or audit recurring tasks. Explain what matters and suggest safe next steps without changing settings.
Choose how to use this skill
You do not need every option. Choose the path your AI client supports. The stable page stays the same; versioned files are immutable.
1. Native installer
This listing has no registered native installer command. Use the complete package or source fallback below, depending on what your client supports.
Do not guess an installer command or replace an existing version without reviewing the diff.
2. Complete package recommended
Download the ZIP when available. It includes SKILL.md plus the references, security notes and version metadata.
No complete ProSkills package is published for this listing yet.3. Prompt-only
Copy the prompt above when the agent can read the stable page or when you want to adopt the workflow without installing a skill.
Need only the instruction file?
Download SKILL.md only if your client requires a single file. The complete ZIP is safer for a full installation because it preserves the references and release context.
No path installs or executes anything by itself. Your agent still needs access to the project files. Before updating, compare the installed version and review the diff.
// RATINGS
// README
Token Optimizer for OpenClaw & Hermes
Built by MissionDeck.ai · GitHub · ClawHub
Find where your AI agent may be wasting tokens—and get a clear, safe improvement plan.
Large instructions, poorly matched models and repetitive AI tasks can all add overhead. Token Optimizer helps your OpenClaw or Hermes agent investigate those opportunities and explain what is worth changing. It does not silently change your setup or promise savings it has not measured.
Start by asking your agent
Once the skill is installed, say:
“Use Token Optimizer to check my setup and suggest the three most useful improvements.”
You can also ask:
- “Are my scheduled tasks using AI when a simple script would do?”
- “Which instruction files are taking up the most context?”
- “Review my model choices for everyday tasks.”
- “Check my Hermes profile for unnecessary recurring AI work.”
You do not need to begin with terminal commands. A tool-enabled agent uses its known host runtime, current agent or active profile to perform read-only checks. It asks only when information is missing or ambiguous. The skill cannot add terminal access to an agent that does not have it.
What you will get
- A clear verdict: what was inspected and what deserves attention.
- Prioritized suggestions: a few useful next steps, with evidence and caveats.
- No surprise changes: your models, schedules and instruction files stay untouched.
- Honest limits: missing spending data stays unknown, not a misleading zero.
For example, it may flag an agent task running every few minutes for review, or identify large instruction files. Neither proves waste by itself; your agent explains the trade-off before recommending a change. Actual savings require a comparable before/after measurement.
One skill, two platforms
OpenClaw: inspects the native model catalog/status and scheduled jobs. Optional known config files add deeper checks. Recognizes agent tasks, commands, heartbeats and system events.
Hermes Agent: reads the active profile's configuration and scheduled jobs. Traces model choices including saved creation-time defaults, skips paused jobs, and recognizes no-agent scripts. This is file-based auditing—not native model discovery or authentication testing.
Both: can inspect selected instruction sizes, duplicate content and supplied usage figures. Model recommendations need a user policy and sufficient availability evidence.
The agent selects the runtime from trusted context. If both platforms are installed and no active runtime is known, it asks rather than guessing. Your chosen profile takes priority.
Install
Ask your agent to install the ClawHub skill openclaw-token-optimizer through its normal skill installer, or use the ClawHub CLI:
clawhub install openclaw-token-optimizer --version 4.1.1
The slug stays the same for both platforms. Keep the bundled scripts and references with SKILL.md. Python 3.10+ is required; YAML input additionally needs PyYAML, usually available in the Hermes Python environment. Nothing is installed automatically by the audit.
OpenClaw is tested on 2026.9.4. Hermes compatibility is tested against a pinned upstream cron-storage implementation in an isolated profile, without starting an agent or scheduler. See Hermes compatibility and agent quick start.
Frequently asked before starting
Will this reduce my bill automatically? No. It finds candidates for improvement; actual savings depend on the changes you choose and how they perform on matched workloads.
Will it break my working setup? The bundled analyzer does not edit configuration, activate models, execute jobs or restart anything. OpenClaw read commands may contact configured services or update native caches.
Do I need to prepare exports? Not for a normal audit when the host has the required read tools and known profile. Exports are an alternative for offline use; Hermes's separate model-routing function requires normalized catalog/status evidence.
Does it measure my complete API spending? Not automatically. Native usage collection and budget alerts are not included. Missing or incomplete data is labeled clearly.
The sections below are for advanced users and maintainers. Your agent can handle these steps for an ordinary audit.
Advanced: run the OpenClaw audit yourself
python3 scripts/optimizer.py audit --live --agent YOUR_AGENT --json
Replace YOUR_AGENT with your actual agent ID. To include config-level findings, provide
an explicit local JSON file with --config /path/to/config.json. Its contents are not echoed.
Generate a review plan with the same inputs:
python3 scripts/optimizer.py plan --live --agent YOUR_AGENT --json
The plan contains review actions, not automatic fixes. Model absence and missing metadata are reasons to investigate—not proof that a model or job is broken.
Choose a model using your policy
python3 scripts/optimizer.py route --live --agent YOUR_AGENT \
--policy assets/config.example.json --tier research --json
The bundled policy illustrates routine, balanced, research, coding and background tiers. Adapt it to your available providers and quality/cost preferences. It is not a universal ranking or live pricing database. Recommendations never activate a model.
Add --image, --tools or --context-tokens 8000 when the task requires those capabilities.
Unknown capability metadata blocks the recommendation. In particular, many native catalogs
do not expose supportsTools; lack of that field does not mean the model lacks tools.
A separately authorized exact-route canary is needed before activation.
Inspect context size and duplicate instructions
python3 scripts/optimizer.py context /path/to/SOUL.md /path/to/AGENTS.md --json
Only explicitly named files are read. Reports show character counts, approximate tokens
(character count divided by four), and duplicate content. They do not print file contents.
Use OpenClaw's native /context list and /context detail to establish actual injected
context. Do not remove essential agent instructions based on file size alone.
Check supplied usage without false zeros
python3 scripts/optimizer.py budget --json
python3 scripts/optimizer.py budget --usage usage.json --limit 10 --json
usage.json accepts an aggregate such as {"costUSD":2.5,"complete":false}.
Without data, the result is unknown/null. Automatic native usage ingestion, daily/weekly
alerts and measured billing comparisons are not included in v4.1.1.
Offline audit and input formats
python3 scripts/optimizer.py audit --catalog catalog.json --status status.json \
--config config.json --jobs jobs.json --json
Native JSON shapes:
- Catalog:
{ "models": [{ "key": "provider/model", "available": true, "input": "text+image", "contextWindow": 32000 }] } - Status:
{ "allowed": ["provider/model"], "auth": { "missingProvidersInUse": [], "modelRouteIssues": [] } } - Config:
{ "agents": { "defaults": { "model": "provider/model" }, "entries": {} } } - Automations:
{ "jobs": [] } - Optional normalized sessions via
--sessions:{ "sessions": [{ "agentId": "example", "model": "provider/model" }] }
Inputs must be JSON, not JSON5. Missing inputs and paginated automation responses are
explicitly marked as incomplete coverage. Tool capability may be supplied as
supportsTools: true only when backed by trustworthy metadata.
Safety and operational limits
Th
// HOW IT'S BUILT
// FILES
37 files shipped with this skill. Inline text is the catalog copy. The upstream link is the source repository.
SKILL.md5.4 KBc2db3e22e9faupstream ↗
--- name: openclaw-token-optimizer description: "Find potential token waste in OpenClaw or Hermes Agent. Use when asked to reduce AI costs, review model choices, check large instructions or audit recurring tasks. Explain what matters and suggest safe next steps without changing settings." version: 4.1.1 author: Asif2BD homepage: https://missiondeck.ai source: https://github.com/Asif2BD/OpenClaw-Token-Optimizer license: MIT openclaw: ">=2026.9.4" metadata: {"openclaw":{"emoji":"💰","requires":{"bins":["python3"]}}} --- # Make your AI agent leaner—not less capable Ask your agent: > “Check where I might be wasting tokens and tell me what to improve.” Or try: - “Review my scheduled tasks for unnecessary AI usage.” - “Which instruction files are making my context heavy?” - “Help me choose a suitable model for routine work.” Works with **OpenClaw and Hermes Agent**. Your agent handles the technical steps below; you do not need to copy Python commands or prepare exports when the required evidence is already available in its environment. ## What you get A short, prioritized explanation of what was checked, what deserves attention and what to do next. Nothing silently changes your models, instructions or schedules. Potential savings are opportunities to test—not a promise or a measured reduction in your bill. Built by [MissionDeck.ai](https://missiondeck.ai). ## Instructions for the agent ### 1. Start with what you already know When the user requests an audit, proceed with relevant read-only checks; do not ask them to restate the runtime, agent ID or active profile if trusted session context already provides it. Say briefly that you will inspect and recommend, without changing settings. Use this decision order: - An explicit user-selected runtime/profile takes priority. - Otherwise use the hosting session's known runtime and active agent/profile. - Installed binaries alone are not proof of which profile is active. If the host is unknown or multiple profiles are plausible, ask one focused question rather than auditing the wrong system. Continue any independent checks whose scope is already clear. Resolve bundled script paths relative to this SKILL.md directory. Use an available Python 3.10+ interpreter. No automatic installs, recursive home-directory searches or credential searches. Never print raw configuration or environment values. ### 2. Run the matching read-only audit **In OpenClaw:** use the current agent ID from trusted runtime context, not the example name or the CLI's default. Follow `references/QUICKSTART.md` for the command. Include `--config` only when the active config path is already established and the audit needs it. If the CLI is unavailable, use exports already supplied; otherwise report the missing capability instead of asking the user to run a long list of commands. **In Hermes:** use the active profile path already supplied by the host/user. A known HERMES_HOME path is profile evidence; do not dump the environment or load `.env`. Do not assume the default profile just because a default directory exists. The audit reads only config.yaml and cron/jobs.json. Prefer the existing Hermes Python environment for YAML support. If no cron file exists, report automation coverage as unavailable; audit the available config separately rather than claiming zero jobs. See references/QUICKSTART.md. Do not ask for catalog/status exports for an ordinary Hermes profile audit: those are only needed for the separate model-routing function. Do not start Hermes or any job. ### 3. Match extra checks to the question - Context: inspect only known, relevant instruction files. Character/4 estimates are not actual injected tokens; use native context diagnostics if available. Never delete instructions. - Model choice: use the user's policy and known catalog/status evidence. Missing capability metadata means unverified, not unsupported. No automatic switching or paid canary. - Spending: without complete usage evidence, say actual spending/savings are unknown. Native usage ingestion and automatic budget alerts are not implemented. Read only the reference needed: QUICKSTART.md for commands, HERMES.md for profile/model precedence, PROVIDERS.md for routing/cache advice. Do not load every reference by default. ### 4. Explain the result, not the machinery Lead with a plain-language verdict and at most three prioritized next steps. For each, explain the evidence, why it matters, and the uncertainty. Separate confirmed problems from review candidates; do not count every informational finding as a fault. End with what was not checked and confirmation that no settings were changed. Do not paste raw JSON unless requested. Offer technical details only when useful. If nothing actionable is found, say so. Never claim a fixed savings percentage, cheapest model, successful authentication or measured dollars without evidence. ## Boundaries All bundled commands are diagnostic. No config edits, installs, restarts, messages, new jobs or credential reads. OpenClaw native reads may contact configured services and update native caches. Hermes support is file-based, not native catalog/authentication discovery; profile overlays and runtime overrides remain unverified. See SECURITY.md. Python 3.10+; optional PyYAML for YAML input. OpenClaw adapter tested on 2026.9.4; Hermes file compatibility is pinned in references/HERMES.md. The CLI still requires explicit runtime selection for Hermes; the agent chooses it from trusted context, not autodetection.README.md11 KBc90ce63a1f7fupstream ↗
# Token Optimizer for OpenClaw & Hermes [](CHANGELOG.md) [](https://missiondeck.ai) [](LICENSE.txt) Built by [MissionDeck.ai](https://missiondeck.ai) · [GitHub](https://github.com/Asif2BD/OpenClaw-Token-Optimizer) · [ClawHub](https://clawhub.ai/asif2bd/skills/openclaw-token-optimizer) **Find where your AI agent may be wasting tokens—and get a clear, safe improvement plan.** Large instructions, poorly matched models and repetitive AI tasks can all add overhead. Token Optimizer helps your OpenClaw or Hermes agent investigate those opportunities and explain what is worth changing. It does not silently change your setup or promise savings it has not measured. ## Start by asking your agent Once the skill is installed, say: > “Use Token Optimizer to check my setup and suggest the three most useful improvements.” You can also ask: - “Are my scheduled tasks using AI when a simple script would do?” - “Which instruction files are taking up the most context?” - “Review my model choices for everyday tasks.” - “Check my Hermes profile for unnecessary recurring AI work.” **You do not need to begin with terminal commands.** A tool-enabled agent uses its known host runtime, current agent or active profile to perform read-only checks. It asks only when information is missing or ambiguous. The skill cannot add terminal access to an agent that does not have it. ## What you will get - **A clear verdict:** what was inspected and what deserves attention. - **Prioritized suggestions:** a few useful next steps, with evidence and caveats. - **No surprise changes:** your models, schedules and instruction files stay untouched. - **Honest limits:** missing spending data stays unknown, not a misleading zero. For example, it may flag an agent task running every few minutes for review, or identify large instruction files. Neither proves waste by itself; your agent explains the trade-off before recommending a change. Actual savings require a comparable before/after measurement. ## One skill, two platforms **OpenClaw:** inspects the native model catalog/status and scheduled jobs. Optional known config files add deeper checks. Recognizes agent tasks, commands, heartbeats and system events. **Hermes Agent:** reads the active profile's configuration and scheduled jobs. Traces model choices including saved creation-time defaults, skips paused jobs, and recognizes no-agent scripts. This is file-based auditing—not native model discovery or authentication testing. **Both:** can inspect selected instruction sizes, duplicate content and supplied usage figures. Model recommendations need a user policy and sufficient availability evidence. The agent selects the runtime from trusted context. If both platforms are installed and no active runtime is known, it asks rather than guessing. Your chosen profile takes priority. ## Install Ask your agent to install the ClawHub skill **openclaw-token-optimizer** through its normal skill installer, or use the ClawHub CLI: ```bash clawhub install openclaw-token-optimizer --version 4.1.1 ``` The slug stays the same for both platforms. Keep the bundled scripts and references with SKILL.md. Python 3.10+ is required; YAML input additionally needs PyYAML, usually available in the Hermes Python environment. Nothing is installed automatically by the audit. OpenClaw is tested on 2026.9.4. Hermes compatibility is tested against a pinned upstream cron-storage implementation in an isolated profile, without starting an agent or scheduler. See [Hermes compatibility](references/HERMES.md) and [agent quick start](references/QUICKSTART.md). ## Frequently asked before starting **Will this reduce my bill automatically?** No. It finds candidates for improvement; actual savings depend on the changes you choose and how they perform on matched workloads. **Will it break my working setup?** The bundled analyzer does not edit configuration, activate models, execute jobs or restart anything. OpenClaw read commands may contact configured services or update native caches. **Do I need to prepare exports?** Not for a normal audit when the host has the required read tools and known profile. Exports are an alternative for offline use; Hermes's separate model-routing function requires normalized catalog/status evidence. **Does it measure my complete API spending?** Not automatically. Native usage collection and budget alerts are not included. Missing or incomplete data is labeled clearly. --- The sections below are for advanced users and maintainers. Your agent can handle these steps for an ordinary audit. ## Advanced: run the OpenClaw audit yourself ```bash python3 scripts/optimizer.py audit --live --agent YOUR_AGENT --json ``` Replace `YOUR_AGENT` with your actual agent ID. To include config-level findings, provide an explicit local JSON file with `--config /path/to/config.json`. Its contents are not echoed. Generate a review plan with the same inputs: ```bash python3 scripts/optimizer.py plan --live --agent YOUR_AGENT --json ``` The plan contains review actions, not automatic fixes. Model absence and missing metadata are reasons to investigate—not proof that a model or job is broken. ## Choose a model using your policy ```bash python3 scripts/optimizer.py route --live --agent YOUR_AGENT \ --policy assets/config.example.json --tier research --json ``` The bundled policy illustrates routine, balanced, research, coding and background tiers. Adapt it to your available providers and quality/cost preferences. It is not a universal ranking or live pricing database. Recommendations never activate a model. Add `--image`, `--tools` or `--context-tokens 8000` when the task requires those capabilities. Unknown capability metadata blocks the recommendation. In particular, many native catalogs do not expose `supportsTools`; lack of that field does not mean the model lacks tools. A separately authorized exact-route canary is needed before activation. ## Inspect context size and duplicate instructions ```bash python3 scripts/optimizer.py context /path/to/SOUL.md /path/to/AGENTS.md --json ``` Only explicitly named files are read. Reports show character counts, approximate tokens (character count divided by four), and duplicate content. They do not print file contents. Use OpenClaw's native `/context list` and `/context detail` to establish actual injected context. Do not remove essential agent instructions based on file size alone. ## Check supplied usage without false zeros ```bash python3 scripts/optimizer.py budget --json python3 scripts/optimizer.py budget --usage usage.json --limit 10 --json ``` `usage.json` accepts an aggregate such as `{"costUSD":2.5,"complete":false}`. Without data, the result is unknown/null. **Automatic native usage ingestion, daily/weekly alerts and measured billing comparisons are not included in v4.1.1.** ## Offline audit and input formats ```bash python3 scripts/optimizer.py audit --catalog catalog.json --status status.json \ --config config.json --jobs jobs.json --json ``` Native JSON shapes: - Catalog: `{ "models": [{ "key": "provider/model", "available": true, "input": "text+image", "contextWindow": 32000 }] }` - Status: `{ "allowed": ["provider/model"], "auth": { "missingProvidersInUse": [], "modelRouteIssues": [] } }` - Config: `{ "agents": { "defaults": { "model": "provider/model" }, "entries": {} } }` - Automations: `{ "jobs": [] }` - Optional normalized sessions via `--sessions`: `{ "sessions": [{ "agentId": "example", "model": "provider/model" }] }` Inputs must be JSON, not JSON5. Missing inputs and paginated automation responses are explicitly marked as incomplete coverage. Tool capability may be supplied as `supportsTools: true` only when backed by trustworthy metadata. ## Safety and operational limits The pure analysis core has no I/O. Explicit live mode invokes fixed native read commands: - `openclaw --version` - `openclaw models list --agent ID --all --json` - `openclaw models status --agent ID --json` - `openclaw cron list --all --json` (audit/plan only) These commands may contact your configured Gateway or providers and update native caches. The optimizer does not run paid inference probes, upload reports, install other software, or write your configuration. Native reads have a 45-second timeout; inputs have an 8 MiB size limit. Selected identifiers and basenames can still be private—review reports before sharing. Exit **0** means analysis completed, not that no issues exist. Exit **2** means invalid input or a failed native read. Reports go to stdout; `--json` supports downstream tooling. `plan` intentionally emits no schema-blind patches. See [SECURITY.md](SECURITY.md). ## Automation support Native **heartbeat** and **systemEvent** jobs are now recognized. The optimizer no longer reports them as unknown or subjects them to agent-turn-only model/timeout/context checks. Unknown future payload kinds remain visible. Recognition is not a full audit of those jobs' effective runtime settings. ## Frequently asked questions ### Does this automatically reduce OpenClaw API costs? No. It identifies review candidates. Savings depend on which changes you safely apply and must be measured on comparable workloads. There is no guaranteed savings percentage. ### Does it work with OpenAI, Anthropic and other model providers? Routing uses your supplied/native catalog and policy instead of a fixed vendor list. Eligibility depends on your model availability, allowlist and capability evidence. Catalog availability alone is not proof that an exact authentication route will succeed. ### Will it change my models, cron jobs or heartbeat schedule? No. All v4 commands are diagnostic. No restart is required to run the CLI. ### Is the ClawHub package verifiable? Yes. From the extracted package directory: ```bash sha256sum -c SHA256SUMS.txt ``` `LICENSE.txt` and `SHA256SUMS.txt` survive registry clients that filter extensionless files. Hashes verify integrity, not safety. Check the version-specific ClawHub security review too. ## Development and migration ```bash python3 -m unittest discover -s tests -v python3 -m py_compile scripts/*.py ``` Tests are in the GitHub source, not the installed skill bundle. CI covers Python 3.10/3.12/3.13. From v3, use the new CLI arguments: old script names are migration shims, not the former prompt classifiers or template installers. Existing state files are left untouched. MIT licensing is retained. See [CHANGELOG.md](CHANGELOG.md). ## MissionDeck.ai — Your Agent Command Center [MissionDeck.ai](https://missiondeck.ai) is the related multi-agent coordination dashboard. This optimizer runs locally, requires no MissionDeck account and has no cloud upload integration. ## More by Asif2BD Browse [Asif2BD on ClawHub](https://clawhub.ai/asif2bd) for other OpenClaw skills. [MissionDeck.ai](https://missiondeck.ai) · [OpenClaw documentation](https://docs.openclaw.ai/) · [Source code](https://github.com/Asif2BD/OpenClaw-Token-Optimizer)scripts/context_optimizer.py225 Ba440f915e0daupstream ↗
#!/usr/bin/env python3 """v4 migration shim: legacy behavior removed; explicit v4 arguments required.""" import sys from optimizer import main if __name__ == '__main__': sys.argv.insert(1, 'context') sys.exit(main())scripts/heartbeat_optimizer.py223 B5592dfa95bbbupstream ↗
#!/usr/bin/env python3 """v4 migration shim: legacy behavior removed; explicit v4 arguments required.""" import sys from optimizer import main if __name__ == '__main__': sys.argv.insert(1, 'audit') sys.exit(main())scripts/hermes_adapter.py5.2 KB83caeeee2f3aupstream ↗
"""Hermes file-only adapter. No Hermes imports, subprocesses, .env reads or writes.""" import json from pathlib import Path from optimizer_core import VERSION, finding, safe_id HERMES_SOURCE = 'd7b836ab1c0cddaafc109ed24c9a83b6191cdc88' MAX_BYTES = 8 * 1024 * 1024 def read_config(path): p = Path(path) if p.stat().st_size > MAX_BYTES: raise ValueError('Config exceeds limit') text = p.read_text() if p.suffix.lower() == '.json': data = json.loads(text) else: try: import yaml except ImportError as exc: raise ValueError('Hermes YAML requires PyYAML; use JSON export or Hermes Python environment') from exc try: data = yaml.safe_load(text) except yaml.YAMLError as exc: raise ValueError('Invalid YAML; raw data withheld') from exc if not isinstance(data, dict): raise ValueError('Config must be an object') return data def resolve_job(job, config, model_env=None): model_cfg = config.get('model') or {} fleet = config.get('cron') or {} if not isinstance(fleet, dict) or not isinstance(model_cfg, (dict, str)): raise ValueError('Unsupported Hermes model/cron shape') global_model = model_cfg.get('default') if isinstance(model_cfg, dict) else model_cfg global_provider = model_cfg.get('provider') if isinstance(model_cfg, dict) else None def choose(pairs): for source, value in pairs: if isinstance(value, str) and value.strip(): return safe_id(value.strip()), source return None, 'unknown' model, model_source = choose([('job',job.get('model')),('cron',fleet.get('model')), ('snapshot',job.get('model_snapshot')),('explicit_environment',model_env),('global_config',global_model)]) provider, provider_source = choose([('job',job.get('provider')),('cron',fleet.get('model_provider')), ('snapshot',job.get('provider_snapshot')),('global_config',global_provider)]) return {'model':model,'modelSource':model_source,'provider':provider,'providerSource':provider_source} def audit_hermes(config, jobs, model_env=None, config_present=True, jobs_present=True): if not isinstance(jobs, list) or any(not isinstance(j, dict) for j in jobs): raise ValueError('Hermes jobs must be an array of objects') out=[]; summaries=[]; enabled=0; scripts=0 for index, job in enumerate(jobs,1): if job.get('enabled',True) is False or job.get('state')=='paused': continue enabled += 1 label=f'Automation #{index}' no_agent=job.get('no_agent',False) if not isinstance(no_agent,bool): raise ValueError('no_agent must be a boolean') if no_agent: scripts += 1 summaries.append({'index':index,'mode':'no_agent','llmInference':False}) if not isinstance(job.get('script'),str) or not job['script'].strip(): out.append(finding('hermes_script_missing','warning',f'{label}: no_agent job has no script.')) continue resolved=resolve_job(job,config,model_env) summaries.append({'index':index,'mode':'agent','resolution':resolved}) if not resolved['model']: out.append(finding('hermes_model_unknown','warning',f'{label}: no model found in supplied file evidence; environment/runtime may differ.')) elif resolved['modelSource']=='snapshot': out.append(finding('hermes_snapshot_model','info',f'{label}: retains its creation-time model snapshot, not the current global default.')) elif resolved['modelSource'] in ('global_config','explicit_environment'): out.append(finding('hermes_inherited_model','info',f'{label}: model depends on defaults rather than a job/fleet pin or snapshot.')) schedule=job.get('schedule') or {} if not isinstance(schedule,dict):raise ValueError('Invalid schedule') minutes=schedule.get('minutes') if schedule.get('kind')=='interval' and isinstance(minutes,(int,float)) and 0<minutes<60: out.append(finding('hermes_frequent_agent_job','warning',f'{label}: agent runs more than hourly; review whether no_agent would suffice for a deterministic task.')) if not job.get('deliver'): out.append(finding('hermes_delivery_inherited','info',f'{label}: delivery is not explicit in the supplied job.')) return {'version':VERSION,'runtime':'hermes','mode':'read-only-files','findings':out, 'automations':summaries,'counts':{'total':len(jobs),'enabled':enabled,'noAgent':scripts}, 'coverage':{'config':config_present,'jobs':jobs_present,'authentication':False,'catalog':False,'environment':model_env is not None}, 'compatibility':{'sourceCommit':HERMES_SOURCE,'status':'file_schema_tested'}, 'savingsEstimate':None,'limitations':[ 'File evidence only: profile overlays, runtime overrides, aliases and provider fallbacks are not resolved.', 'No .env, credential store, ambient environment, model catalog or authentication read.', 'A missing explicit environment value can change legacy/global model resolution.', 'No agent, scheduler, script, inference canary or network request is started.', 'no_agent avoids Hermes inference; its script may incur costs of its own.']}scripts/model_router.py223 Bdc974efa5bcaupstream ↗
#!/usr/bin/env python3 """v4 migration shim: legacy behavior removed; explicit v4 arguments required.""" import sys from optimizer import main if __name__ == '__main__': sys.argv.insert(1, 'route') sys.exit(main())scripts/optimize.sh148 Bb07909c4365fupstream ↗
#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" exec python3 "$SCRIPT_DIR/optimizer.py" "$@"scripts/optimizer.py8.8 KB393aea45d0cfupstream ↗
#!/usr/bin/env python3 """Read-only CLI adapter. OpenClaw native reads or explicitly selected Hermes profile files.""" import argparse import json import math import re import subprocess import sys from pathlib import Path from hermes_adapter import read_config, audit_hermes from optimizer_core import VERSION, audit, route, context_report, budget MAX_BYTES = 8 * 1024 * 1024 def read_json(path, default=None): if not path: return default p = Path(path) if p.stat().st_size > MAX_BYTES: raise ValueError('Input exceeds 8 MiB limit') value = json.loads(p.read_text()) if not isinstance(value, dict): raise ValueError('Expected a JSON object') return value def native(args, json_output=True): # No shell, no arbitrary executable/command option, no auth probe or mutation. result = subprocess.run(['openclaw', *args], capture_output=True, text=True, timeout=45, check=False) if result.returncode: raise ValueError('Native read command failed; inspect OpenClaw locally. Raw output withheld to protect secrets.') if len(result.stdout) > MAX_BYTES: raise ValueError('Native response exceeds limit') return json.loads(result.stdout) if json_output else result.stdout.strip() def main(): p = argparse.ArgumentParser(description='Token Optimizer v4: read-only evidence-based analysis') p.add_argument('--version', action='version', version=VERSION) sub = p.add_subparsers(dest='command', required=True) for cmd in ('audit', 'plan', 'route'): s = sub.add_parser(cmd) s.add_argument('--runtime', choices=['openclaw','hermes'], default='openclaw', help='Explicit runtime; default preserves OpenClaw compatibility') s.add_argument('--hermes-home', help='Explicit Hermes profile directory; reads config.yaml and cron/jobs.json only') s.add_argument('--hermes-model-env', help='Optional explicit HERMES_MODEL value; ambient environment is never read') s.add_argument('--catalog') s.add_argument('--status') s.add_argument('--live', action='store_true', help='Run fixed native read commands; may contact configured Gateway/providers') s.add_argument('--agent', default='oracle', help='Agent whose native model status is read') s.add_argument('--json', action='store_true') s.add_argument('--openclaw-version', help='Installed version for offline compatibility checks') if cmd == 'route': s.add_argument('--policy', required=True) s.add_argument('--tier', required=True) s.add_argument('--image', action='store_true') s.add_argument('--tools', action='store_true') s.add_argument('--context-tokens', type=int, default=0) else: s.add_argument('--config', help='Explicit local JSON config; never written or echoed') s.add_argument('--jobs') s.add_argument('--sessions', help='Normalized JSON object containing sessions array') s = sub.add_parser('context') s.add_argument('files', nargs='+', help='Explicit bootstrap files; no recursive traversal') s.add_argument('--json', action='store_true') s = sub.add_parser('budget') s.add_argument('--usage', help='JSON {costUSD, complete}; no native ingestion') s.add_argument('--limit', type=float) s.add_argument('--json', action='store_true') a = p.parse_args() try: if a.command in ('audit', 'plan', 'route'): if not re.fullmatch(r'[A-Za-z0-9_-]+', a.agent): raise ValueError('Invalid agent identifier') if a.runtime == 'hermes': if a.live and not a.hermes_home: raise ValueError('Hermes live file mode needs an explicit profile directory') if a.command == 'route': if a.live or a.hermes_home: raise ValueError('Hermes route requires explicit normalized catalog/status exports; no native discovery') if a.context_tokens < 0: raise ValueError('Context must not be negative') result = route(read_json(a.catalog,{}),read_json(a.status,{}),read_json(a.policy),a.tier,a.image,a.tools,a.context_tokens) result['runtime']='hermes' else: if a.catalog or a.status or a.sessions: raise ValueError('Hermes audit does not ingest catalog/status/session evidence') if a.hermes_home and (a.config or a.jobs): raise ValueError('Choose profile directory OR explicit exports, not both') home=Path(a.hermes_home).expanduser() if a.hermes_home else None config_path=home/'config.yaml' if home else a.config jobs_path=home/'cron/jobs.json' if home else a.jobs # Missing explicit profile files are errors, not empty successful audits. config=read_config(config_path) if config_path else {} jobs=read_json(jobs_path,{}) result=audit_hermes(config,jobs.get('jobs',[]),a.hermes_model_env,bool(config_path),bool(jobs_path)) if a.command == 'plan': result['plan']=[{'action':f['message'],'automatic':False} for f in result['findings']] result['patches']=[] else: if a.hermes_home or a.hermes_model_env: raise ValueError('Hermes options require --runtime hermes') installed_version = native(['--version'], json_output=False) if a.live else a.openclaw_version cat = native(['models', 'list', '--agent', a.agent, '--all', '--json']) if a.live else read_json(a.catalog, {}) status = native(['models', 'status', '--agent', a.agent, '--json']) if a.live else read_json(a.status, {}) if a.command == 'route': if a.context_tokens < 0: raise ValueError('Context must not be negative') result = route(cat, status, read_json(a.policy), a.tier, a.image, a.tools, a.context_tokens) else: jobs = native(['cron', 'list', '--all', '--json']) if a.live else read_json(a.jobs, {}) sessions = read_json(a.sessions, {}) result = audit(cat, status, read_json(a.config, {}), jobs.get('jobs', []), sessions.get('sessions')) result['coverage'] = {'config': bool(a.config), 'catalog': bool(a.live or a.catalog), 'status': bool(a.live or a.status), 'jobs': bool(a.live or a.jobs)} if jobs.get('hasMore'): result['limitations'].append('Automation response is paginated; this report covers only returned jobs.') if a.command == 'plan': result['plan'] = [{'action': f['message'], 'automatic': False} for f in result['findings']] result['patches'] = [] result['limitations'].append('No schema-blind config patches: validate each proposed change against your installed OpenClaw schema.') match = re.search(r'(202[0-9])\.(\d+)\.(\d+)', installed_version or '') parsed = tuple(map(int, match.groups())) if match else None result['compatibility'] = {'installed': '.'.join(match.groups()) if match else None, 'adapterTested': '2026.9.4', 'status': 'tested_version' if parsed == (2026,9,4) else ('older_than_supported' if parsed and parsed < (2026,9,4) else 'unverified_version')} elif a.command == 'context': files = {} for i, path in enumerate(a.files): file = Path(path) if file.stat().st_size > MAX_BYTES: raise ValueError('Context input exceeds limit') files[f'{i+1}:{file.name}'] = file.read_text() result = context_report(files) else: if a.limit is not None and (not math.isfinite(a.limit) or a.limit <= 0): raise ValueError('Limit must be positive') result = budget(read_json(a.usage), a.limit) # Reports are constructed from selected fields, never raw config/auth/prompts. if a.json: print(json.dumps(result, indent=2)) else: print(f'Token Optimizer {VERSION} — {a.command} (read-only)') for key, value in result.items(): if key != 'version': print(f'{key}: {json.dumps(value, ensure_ascii=False)}') return 0 except (ValueError, OSError, TypeError, AttributeError, KeyError, subprocess.TimeoutExpired): print('Unable to analyze input: invalid/missing JSON/YAML, unsupported shape, or native read failure. No changes made. Raw data withheld.', file=sys.stderr) return 2 if __name__ == '__main__': sys.exit(main())scripts/optimizer_core.py10.0 KBc91e87b2b401upstream ↗
"""Pure, read-only analysis. No filesystem, network, process, or credential access.""" import re import math def safe_id(value): return value if isinstance(value, str) and re.fullmatch(r'[A-Za-z0-9_.:/-]{1,160}', value) else '[redacted identifier]' VERSION = '4.1.1' def finding(code, severity, message): return {'code': code, 'severity': severity, 'message': message} def catalog_rows(catalog): rows = catalog.get('models', []) if not isinstance(rows, list): raise ValueError('catalog.models must be an array') return {r['key']: r for r in rows if isinstance(r, dict) and isinstance(r.get('key'), str)} def route(catalog, status, policy, tier, image=False, tools=False, context=0): """Operator-ordered tiers; availability is not proof of successful inference.""" rows = catalog_rows(catalog) allowed = status.get('allowed') missing = status.get('auth', {}).get('missingProvidersInUse', []) candidates = policy.get('tiers', {}).get(tier, []) if not isinstance(candidates, list) or any(not isinstance(x, str) for x in candidates): raise ValueError('policy tier must contain model identifiers') rejected = [] for key in candidates: row = rows.get(key) reasons = [] if safe_id(key) != key: rejected.append({'model': '[redacted identifier]', 'reasons': ['invalid identifier']}) continue issues = status.get('auth', {}).get('modelRouteIssues', []) if issues: reasons.append('native status reports unresolved route issues; resolve before recommendation') if row is None: reasons.append('absent from catalog') else: if row.get('available') is not True: reasons.append('availability missing or not true') if allowed is None or key not in allowed: reasons.append('not explicitly allowed by supplied status') if key.split('/')[0] in missing: reasons.append('provider authentication missing') if image and 'image' not in str(row.get('input', '')): reasons.append('image capability not established') if tools and row.get('supportsTools') is not True: reasons.append('tool capability not established') limit = row.get('contextTokens') or row.get('contextWindow') if context and (not isinstance(limit, (int, float)) or limit < context): reasons.append('context capacity insufficient or unknown') if reasons: rejected.append({'model': key, 'reasons': reasons}) else: return {'version': VERSION, 'tier': tier, 'candidate': key, 'activation': 'not_performed', 'canaryRequired': True, 'reason': 'First eligible model in operator preference order; price and latency not inferred.', 'rejected': rejected} return {'version': VERSION, 'tier': tier, 'candidate': None, 'activation': 'not_performed', 'canaryRequired': True, 'rejected': rejected, 'reason': 'No proven eligible candidate. Supply policy and current catalog/status; do not guess.'} def audit(catalog, status, config, jobs, sessions=None): rows = catalog_rows(catalog) out = [] agents = config.get('agents', {}) defaults = agents.get('defaults', {}) entries = agents.get('entries', {}) if not isinstance(entries, dict): raise ValueError('agents.entries must be an object') def check_model(model, label): if isinstance(model, str): primary, fallbacks = model, [] elif isinstance(model, dict): primary, fallbacks = model.get('primary'), model.get('fallbacks', []) else: return for key in ([primary] if primary else []) + fallbacks: if key not in rows: out.append(finding('model_absent', 'warning', f'{label}: model is absent from supplied catalog: {safe_id(key)}')) elif rows[key].get('available') is not True: out.append(finding('model_unverified', 'warning', f'{label}: availability is unverified: {safe_id(key)}')) if primary and fallbacks and all(x.split('/')[0] == primary.split('/')[0] for x in fallbacks): out.append(finding('shared_provider_fallback', 'info', f'{label}: all fallbacks share the primary provider; provider-wide outages may affect all routes.')) heartbeat = defaults.get('heartbeat', {}) if heartbeat.get('every'): out.append(finding('heartbeat_review', 'info', 'A default heartbeat interval is configured; verify task necessity, quiet hours and delivery rather than assuming cache savings.')) for field in ('bootstrapMaxChars', 'bootstrapTotalMaxChars'): limit = defaults.get(field) if isinstance(limit, (int, float)) and limit > 40000: out.append(finding('bootstrap_large_limit', 'info', f'{field} allows more than 40,000 characters; inspect native /context detail before reducing it. This is a review heuristic, not measured waste.')) check_model(defaults.get('model'), 'defaults') for agent, entry in entries.items(): check_model(entry.get('model', defaults.get('model')), f'agent {safe_id(agent)}') for key in status.get('allowed', []): if key not in rows: out.append(finding('allowlist_absent', 'warning', f'Allowed model absent from catalog: {safe_id(key)}')) for provider in status.get('auth', {}).get('missingProvidersInUse', []): out.append(finding('auth_missing', 'warning', f'Authentication unavailable for provider: {safe_id(provider)}')) if status.get('auth', {}).get('modelRouteIssues'): out.append(finding('route_issues', 'warning', 'Native model status reports route issues; inspect locally with openclaw models status.')) if sessions is None: out.append(finding('sessions_unknown', 'info', 'Session overrides were not supplied; default-vs-session comparisons unavailable.')) else: for s in sessions: agent = s.get('agentId') model = entries.get(agent, {}).get('model', defaults.get('model', {})) primary = model if isinstance(model, str) else model.get('primary') if s.get('model') and primary and s['model'] != primary: out.append(finding('session_override', 'info', f'Agent {safe_id(agent)}: session model differs from configured primary.')) for index, job in enumerate(jobs): if not job.get('enabled', True): continue payload = job.get('payload', {}) label = f'Automation #{index + 1}' # Never output job names, commands, or prompts. # Native heartbeat/system events use their own execution configuration. # Do not apply agentTurn-only model/timeout/lightContext rules to them. if payload.get('kind') in ('command', 'heartbeat', 'systemEvent'): continue if payload.get('kind') not in ('agentTurn', 'agent'): out.append(finding('automation_kind_unknown', 'info', f'{label}: payload kind not recognized; inspect manually.')) continue if not payload.get('model'): out.append(finding('automation_model_inherited', 'info', f'{label}: inherits its model; verify effective cost.')) else: check_model(payload['model'], label) if not payload.get('timeoutSeconds'): out.append(finding('automation_timeout', 'info', f'{label}: no explicit timeout.')) if not payload.get('lightContext'): out.append(finding('automation_context', 'info', f'{label}: consider lightContext only if required instructions remain available.')) every = job.get('schedule', {}).get('everyMs') if isinstance(every, (int, float)) and 0 < every < 3600000: out.append(finding('frequent_agent_job', 'warning', f'{label}: runs more than hourly; consider a command job if the task is deterministic.')) if not job.get('delivery'): out.append(finding('automation_delivery', 'info', f'{label}: delivery intent not explicit.')) out.append(finding('cache_economics', 'info', 'Do not schedule cache-only heartbeats without provider-specific TTL and measured net savings.')) return {'version': VERSION, 'mode': 'read-only', 'catalogCount': len(rows), 'findings': sorted(out, key=lambda x: {'warning': 0, 'info': 1}[x['severity']]), 'savingsEstimate': None, 'limitations': ['No inference canary or authentication probe performed.', 'Catalog availability is not exact-route inference proof.', 'No pricing or savings assumed.']} def context_report(files): results = [] seen = {} for name, content in files.items(): normalized = content.strip() item = {'file': name, 'characters': len(content), 'estimatedTokens': (len(content) + 3) // 4} if normalized and normalized in seen: item['duplicateOf'] = seen[normalized] seen[normalized] = name results.append(item) return {'version': VERSION, 'files': sorted(results, key=lambda x: -x['characters']), 'note': 'Character/4 heuristic, not measured prompt tokens. Native /context detail is authoritative; no truncation or edits performed.'} def budget(usage=None, limit=None): if usage is None: return {'version': VERSION, 'status': 'unknown', 'costUSD': None, 'tokens': None, 'reason': 'No usage supplied. Missing data is not zero usage.'} cost = usage.get('costUSD') if cost is not None and (isinstance(cost, bool) or not isinstance(cost, (int, float)) or not math.isfinite(cost) or cost < 0): raise ValueError('costUSD must be a non-negative number or null') complete = usage.get('complete') is True return {'version': VERSION, 'status': 'exceeded' if cost is not None and limit is not None and cost >= limit else ('ok' if complete and cost is not None else 'incomplete'), 'costUSD': cost, 'complete': complete, 'limitUSD': limit, 'note': 'Supplied aggregate only; native usage ingestion and automated budget alerts are planned for v4.1.'}scripts/token_tracker.py224 Baa9ccdd85684upstream ↗
#!/usr/bin/env python3 """v4 migration shim: legacy behavior removed; explicit v4 arguments required.""" import sys from optimizer import main if __name__ == '__main__': sys.argv.insert(1, 'budget') sys.exit(main())references/HERMES.md1.7 KBd0d26fce3fecupstream ↗
# Hermes Agent compatibility The read-only adapter was verified against NousResearch/hermes-agent commit `d7b836ab1c0cddaafc109ed24c9a83b6191cdc88`. Source: https://github.com/NousResearch/hermes-agent/tree/d7b836ab1c0cddaafc109ed24c9a83b6191cdc88 Maintainer integration: `python3 tools/test_hermes_compat.py --source /path/to/pinned/checkout`. This creates an isolated temporary profile using the actual upstream cron.jobs parse/save functions, audits the resulting files, and verifies every profile file remains unchanged. No scheduler, job script, provider authentication or paid inference is run. Inputs: explicit profile config.yaml and cron/jobs.json, or JSON/YAML config plus JSON jobs export. Missing selected files fail instead of reporting an empty successful audit. The adapter does not import Hermes, search profiles, read .env or resolve profile overlays. Ambient HERMES_MODEL is ignored; pass its known non-secret value with --hermes-model-env if needed. Model order follows upstream cron scheduler: job.model, cron.model, model_snapshot, explicit environment, global model.default (or model string). Provider evidence follows job.provider, cron.model_provider, provider_snapshot, global model.provider. Actual auth, aliases, runtime overrides and fallbacks remain unverified. The skill format uses SKILL.md. Preserve its scripts and references when installing. OpenClaw native commands are never invoked for a Hermes audit. JSON needs standard-library Python 3.10+; YAML additionally needs PyYAML, loaded with safe_load. Nothing is auto-installed. No native catalog/auth/usage ingestion, automatic configuration changes or guaranteed savings. Reports omit raw prompt/script/config content; selected identifiers can still be sensitive.references/PROVIDERS.md1.5 KBeab6f931b05eupstream ↗
# Provider policy Do not infer credentials from environment variables or hard-code a cheapest model. Use the selected agent's native catalog/status and an operator-owned ordered tier policy. The bundled policy is an optional OpenAI example, not a universal recommendation. Change the identifiers for the models your account exposes. Availability, allowlist membership, capability metadata, and successful inference are separate evidence. An available catalog row does not prove that OAuth, a particular runtime, or the exact model route will work. v4 never runs a paid canary automatically. Before activation, explicitly test the exact route and inspect the actual model used. Unknown image/tool/context capability blocks a requirement that needs it. Catalogs that omit tool metadata require a trustworthy normalized export with supportsTools=true; do not fill this field by guessing. Native route issues block recommendations until resolved. Tier ordering represents the user's quality/cost/latency preference. v4 does not scrape prices, claim live pricing, infer model quality from names, or estimate model latency. Retirements should be handled by refreshing catalog/status and reviewing provider notices. Prompt cache lifetime and billing vary by provider, account, and model. Compare measured cache writes, cache reads, input and output cost. Never assume that extra cache-warming heartbeats save money. Same-provider fallbacks do not guarantee resilience to auth outages. Sources: https://docs.openclaw.ai/releases/2026.9.4 https://developers.openai.com/codex/modelsreferences/QUICKSTART.md2.4 KB30d615824adfupstream ↗
# Technical quick start for agents and advanced users The human starts with a natural-language request. The agent runs these commands using real values from its trusted host context, with the script path resolved from SKILL.md. These commands never apply changes. Do not invent agent IDs, profile paths or evidence. ## OpenClaw ```bash python3 /path/to/skill/scripts/optimizer.py audit --runtime openclaw --live --agent ACTUAL_AGENT_ID --json ``` Append `--config /known/active/config.json` only when its path is established. Native reads use the installed CLI: version, models list/status and cron list. No config dump is printed. `plan` accepts the same inputs and emits review actions, not patches. ## Hermes ```bash python3 /path/to/skill/scripts/optimizer.py audit --runtime hermes --live --hermes-home /known/active/profile --json ``` Use the existing Hermes Python interpreter if it provides PyYAML. No `.env` loading or credential inspection. The adapter reads only config.yaml and cron/jobs.json. If a file is missing, do not create one or report an empty successful full audit. To inspect only an available config and honestly mark job coverage missing: ```bash python3 /path/to/skill/scripts/optimizer.py audit --runtime hermes --config /known/profile/config.yaml --json ``` Explicit JSON exports also work. If no usable interpreter/YAML parser is available, report that narrow limitation; do not auto-install dependencies. See HERMES.md for precedence. ## Optional focused checks ```bash python3 /path/to/skill/scripts/optimizer.py context /known/instruction-file.md --json python3 /path/to/skill/scripts/optimizer.py budget --json python3 /path/to/skill/scripts/optimizer.py route --runtime openclaw --live --agent ACTUAL_AGENT_ID --policy /known/policy.json --tier routine --json ``` Hermes route requires explicit normalized `--catalog` and `--status` exports, not --live. The example policy is illustrative, not a universal recommendation. Unknown usage returns unknown; no prices or savings are invented. Commands and advanced schemas are also in README. ## Ambiguity examples - Host says OpenClaw, current agent ID known: audit that agent without asking runtime again. - Host says Hermes, active profile known: audit that profile; no exports questionnaire. - Both CLIs installed, no active-host evidence: ask which runtime/profile to inspect. - Hermes profile known, cron file absent: inspect config only and mark jobs not checked.assets/config-patches.json255 B7f3bc41b0197upstream ↗
{ "version": "4.1.1", "patches": [], "note": "Legacy blind configuration patches removed. Use optimizer plan, validate proposed changes against your installed OpenClaw schema, and apply separately with an explicit backup and validation workflow." }assets/config.example.json267 Be51d5bf13905upstream ↗
{ "tiers": { "routine": ["openai/gpt-5.6-luna", "openai/gpt-5.6-terra"], "balanced": ["openai/gpt-5.6-sol"], "research": ["openai/gpt-6-astra"], "coding": ["openai/gpt-6-astra", "openai/gpt-5.6-sol"], "background": ["openai/gpt-5.6-luna"] } }assets/cronjob-model-guide.md803 Ba79cda485f03upstream ↗
# Automation review — OpenClaw 2026.9.4 Use `optimizer.py audit --live --agent YOUR_AGENT --json` to inspect enabled jobs. For each agent job, confirm effective model, timeout, delivery, failure policy, and required context. Consider `lightContext` only when the omitted instructions are not necessary. The linter marks candidates for review, not safe automatic fixes. Deterministic calculations, API polling, and fixed threshold alerts may use command jobs with no LLM inference. Commands can still have external API or infrastructure costs. Keep their secrets in native protected configuration, not in published examples. The CLI uses the installed native `cron list --all --json` command. If its response is paginated, the report explicitly notes partial coverage. It never runs or edits jobs.assets/HEARTBEAT.template.md590 B0d984ab565fcupstream ↗
# Heartbeat review checklist (not an installer) - Respect the user's monitoring, quiet-hours, and delivery requirements. - Return the runtime's quiet-success response when no actionable change exists. - Avoid repeated full-workspace reads; load only what the task needs. - Use deterministic command automations when inference is unnecessary. - Do not wake the model merely to keep a cache warm without measured net savings. - A cheaper model must still meet the required reliability, context, tools and modality. - This template does not change runtime configuration or schedule any work..clawhubignore181 B1f59fc8179a4upstream ↗
.git/ .github/ .gitignore tests/ docs/ __pycache__/ *.pyc *.log .env .env.* node_modules/ .mission-control/ openclaw.json *.state.json *.sqlite *.db PR-DESCRIPTION.md tools/ dist/.clawhubsafe1.8 KBf8c4bc4650f6upstream ↗
# ClawHub integrity manifest # Version: 4.1.1 # Integrity is not an independent security approval. 6deb5c5964d9aec121bc72221c0189db2c25fdf6d0f5abca504573f2c915d241 CHANGELOG.md cae3009b94a086590def655d997bf0a236f41b30dfddaeec059447243db1fde8 LICENSE.txt a392682bb2d2a442d460f78e39b781406023b7f1e9d471e5aa00e254167da545 README.md 672adadf958148742f0af05e14c959c9ea781bd3f1aa9578c0bf1052b5a30917 SECURITY.md dbb891806d21671a3dc757d7286d481ce8d2bf7ed034efa7a2175539aaeacc2c SKILL.md f93dd9d76568cf4edaabf54f2e0917c250a850396b501b71c3aa22c29a62a46b assets/HEARTBEAT.template.md 8a5739cf57d4f0810f85e80086dc5aee648ab80c423b437e7209dafe3d9feb15 assets/config-patches.json a95674eadd26e91b3f5bb4f90cb7e0f1de5dcfd96a050e7068286c3effaa4510 assets/config.example.json 571140051acceee68fc49edb68e095bc5c44457f112daf421052933c39b639ea assets/cronjob-model-guide.md d2a3a82779f72fda6385ee9f68ee82f0c0297cc563ce2f95c10ff99df8a92fe2 references/HERMES.md 201011cba849e63bde066f1328d128c72fb39532779c5825fe6c2dfb5df6b2fa references/PROVIDERS.md 4fda8b7fac415bdca7aef3e78b4ecb08d0ea2c28380273af58a5e589213421a1 references/QUICKSTART.md 383573284ad01da4e63015793f5399ed80f477a695e1eda8a00a472303456643 scripts/context_optimizer.py 7de333781278dc66026af5cb1ea7f4f33fd961da7af5d7c3877baccbf2606ab3 scripts/heartbeat_optimizer.py f14a06f3af6aa67767a28ba47b5ee3bd90434050f36737742744f005f71bd9e2 scripts/hermes_adapter.py 1e58db77f1417b8b6e0467141c7a8449f261bbb6955bfd78c3c6f48bef43cbf9 scripts/model_router.py 18b1d26dec3fa8009ec62325f2b161c5d5ed1bbf71c05f462f62e344c8eff0b8 scripts/optimize.sh 355db32d447aa8e2cfc87911db375ea20fe2e634edd87f575349289251f065a5 scripts/optimizer.py 6f03068622520bbc8f90106085d98194572b75bf357bcefcf45154eb135a3fc1 scripts/optimizer_core.py 12db8b727e62b82c2d39ce1c0f3ebf0d1d95657a8a2682cac1097d615a945a88 scripts/token_tracker.py.github/workflows/test.yml917 Bffdeef14f181upstream ↗
name: Verify on: [push, pull_request] permissions: contents: read jobs: test: runs-on: ubuntu-latest strategy: matrix: python: ['3.10', '3.12', '3.13'] steps: - uses: actions/checkout@v4 with: persist-credentials: false - uses: actions/setup-python@v5 with: python-version: '${{ matrix.python }}' - run: python -m pip install PyYAML==6.0.3 - run: python -m unittest discover -s tests -v - run: python -m py_compile scripts/*.py - run: sha256sum -c SHA256SUMS.txt - name: Verify pinned Hermes storage compatibility run: | git clone --filter=blob:none --no-checkout https://github.com/NousResearch/hermes-agent.git /tmp/hermes-compat git -C /tmp/hermes-compat checkout d7b836ab1c0cddaafc109ed24c9a83b6191cdc88 python tools/test_hermes_compat.py --source /tmp/hermes-compat.gitignore531 B114457ce2a32upstream ↗
# Python __pycache__/ *.py[cod] *$py.class *.so .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # Virtual environments .env .venv env/ venv/ ENV/ # IDE .idea/ .vscode/ *.swp *.swo *~ .DS_Store # State files (generated at runtime) memory/ *.state.json context-usage.json heartbeat-state.json token-tracker-state.json # OpenClaw workspace files (user-specific) AGENTS.md.optimized # Testing .pytest_cache/ .coverage htmlcov/ # Logs *.log logs/CHANGELOG.md8.3 KB035a029dabd5upstream ↗
# Changelog ## v4.1.1 - Lead with natural-language requests and plain-language benefits instead of Python commands. - Give agents a context-first OpenClaw/Hermes workflow with focused ambiguity handling. - Move technical steps into a lazy-loaded quick-start reference; keep all audits read-only. - Clarify missing profile/job evidence, installation needs and report expectations. ## v4.1.0 - Add explicit Hermes read-only adapter and isolated upstream cron-store compatibility test. - Resolve file-evidenced cron model precedence including creation snapshots. - Recognize no_agent/paused jobs; keep auth, runtime overlays and savings unverified. - Share the analysis engine and preserve OpenClaw behavior and existing installation slug. - Document runtime-specific requirements and compatibility boundaries. ## v4.0.2 — 2026-09-19 - Fix false unknown-kind findings for native heartbeat and systemEvent jobs. - Keep agent-turn-only checks scoped to agent turns; preserve unknown-kind reporting. - Add three regression tests for native kinds, future kinds and agent-turn linting. - Rewrite README and ClawHub description for clear OpenClaw token optimization, AI cost auditing, model routing and automation discovery, without savings guarantees. ## v4.0.1 — 2026-09-19 - Ship LICENSE.txt and SHA256SUMS.txt through extension-filtering registry clients. - Pin the installation example; verify actual published file hashes. - No change to the read-only audit behavior. ## v4.0.0 — 2026-09-19 - Combined compatibility refresh and native-aware audit core. - Added read-only audit/plan, ordered policy routing, context sizing/duplicates, automation linting, coverage flags and honest missing-usage handling. - Added optional fixed-command OpenClaw adapter and offline JSON mode. - Removed obsolete static model/pricing tables, blanket 55-minute cache guidance, generated workspace instructions, and unmeasured percentage-saving claims. - Preserved MIT license; unified slug/version; added regression tests and CI. - Breaking: legacy entrypoints now delegate to explicit v4 CLI arguments. - Native usage ingestion, automatic budgets, auto-apply and benchmarking remain outside v4.0. All notable changes to OpenClaw Token Optimizer are documented here. ## [3.2.0] - 2026-06-22 ### Changed - Modernized the ClawHub skill card to match newer Asif2BD releases: stronger title, badges, GitHub/security links, current compatibility, quick commands, savings table, file inventory, and security posture. - Moved the public listing away from old v3.0-era Haiku/no-system-modification copy and toward OpenClaw 2026.6.x Sonnet/Opus guidance. - Updated README version badge and license badge to match the repository license. ## [3.1.0] - 2026-06-22 ### Fixed - Addressed the ClawHub security audit's description/behavior mismatch by documenting explicit local workspace writes instead of claiming the skill makes no system modifications. - Changed `context_optimizer.py generate-agents` to print to stdout by default; writing `AGENTS.md.optimized` now requires `--output` or `--workspace-output`. - Changed `scripts/optimize.sh heartbeat` to preview by default; installing `HEARTBEAT.md` now requires `heartbeat install` and backs up an existing file first. - Updated model routing defaults for current OpenClaw 2026.6.x Sonnet/Opus deployments: routine work maps to Sonnet and complex reasoning maps to Opus. - Refreshed README, SECURITY.md, heartbeat, cronjob, and config-patch guidance for a safer release. ## [1.4.3] - 2026-02-18 ### Fixed - README completely rewritten: correct name ("OpenClaw Token Optimizer"), version badge (1.4.3), install command (clawhub install Asif2BD/openclaw-token-optimizer), license (Apache 2.0), all skill paths corrected to openclaw-token-optimizer, v1.4.x features documented. ## [1.4.2] - 2026-02-18 ### Fixed - **ClawHub security scanner: `Source: unknown` / `homepage: none`** — Added `homepage`, `source`, and `author` fields to SKILL.md frontmatter. Provenance is now fully declared in the registry. - **`optimize.sh` missing from integrity manifest** — Added `scripts/optimize.sh` to `.clawhubsafe`. The manifest now covers 13 files (previously 12). Every bundled file is SHA256-verified. - **`optimize.sh` undocumented** — New dedicated section in `SECURITY.md` with full source disclosure: what the wrapper does (delegates to bundled Python scripts only), security properties, and a one-line audit command for users who want to verify before running. - **Provenance undocumented** — New `Provenance & Source` section in `SECURITY.md` with explicit GitHub repo + ClawHub listing links and integrity verification instructions. ## [1.4.1] - 2026-02-18 ### Fixed - **ClawHub public visibility blocked** — `PR-DESCRIPTION.md` (a leftover dev file containing `git push` / `gh pr create` shell commands) was included in the v1.4.0 bundle, triggering ClawHub's security scanner hold. - **Added `.clawhubignore`** — Now excludes `PR-DESCRIPTION.md`, `docs/`, `.git/`, `.gitignore` from all future publishes. Only skill-relevant files are bundled. ## [1.4.0] - 2026-02-17 ### Added - **Session pruning config patch** — Native `contextPruning: { mode: "cache-ttl" }` support. Auto-trims old tool results when the Anthropic prompt cache TTL expires, reducing cache write costs after idle sessions. No scripts required — applies directly via `gateway config.patch`. - **Bootstrap size limits patch** — `bootstrapMaxChars` / `bootstrapTotalMaxChars` config keys to cap how large workspace files are injected into the system prompt. Delivers 20-40% system prompt reduction for agents with large workspace files (e.g., detailed AGENTS.md, MEMORY.md). Native 2026.2.15 feature. - **Cache retention config patch** — `cacheRetention: "long"` param for Opus models. Amortizes cache write costs across long reasoning sessions. - **Cache TTL heartbeat alignment** — New `heartbeat_optimizer.py cache-ttl` command. Calculates the optimal heartbeat interval to keep the Anthropic 1h prompt cache warm (55min). Prevents the "cold restart" cache re-write penalty after idle gaps. - **Native commands section in SKILL.md** — Documents `/context list`, `/context detail` (per-file token breakdown) and `/usage tokens|full|cost` (per-response usage footer). These are built-in OpenClaw 2026.2.15 diagnostics that complement the Python scripts. - **`native_openclaw` category in config-patches.json** — Clearly distinguishes patches that work today with zero external dependencies from those requiring API keys or beta features. ### Changed - `SKILL.md`: Configuration Patches section updated — `session_pruning`, `bootstrap_size_limits`, and `cache_retention_long` now listed as ✅ native (not ⏳ pending). - `config-patches.json`: Added `_categories.native_openclaw` grouping. Model routing patch updated to reflect Sonnet-primary setups (Haiku listed as optional with multi-provider note). - `heartbeat_optimizer.py`: Added `cache-ttl` subcommand and `CACHE_TTL_OPTIMAL_INTERVAL` constant (3300s = 55min). Plan output now includes cache TTL alignment recommendation when relevant. - Compliance with OpenClaw 2026.2.15 features: **72% → 92%+** ### Fixed - Model routing quick start: added note that Haiku requires multi-provider setup (OpenRouter/Together); Sonnet is the default minimum for single-provider Anthropic deployments. ## [1.3.3] - 2026-02-17 ### Fixed - Display name corrected to "OpenClaw Token Optimizer" on ClawHub (was truncated in 1.3.1/1.3.2) - Slug preserved: `openclaw-token-optimizer` ## [1.3.2] - 2026-02-17 ### Added - `SECURITY.md` — Full two-category security breakdown (executable scripts vs. reference docs) - `.clawhubsafe` — SHA256 integrity manifest for all 10 skill files ### Fixed - Resolved VT flag: SKILL.md previously claimed `no_network: true` for entire skill, but PROVIDERS.md and config-patches.json reference external APIs — scoped the guarantee to scripts only ## [1.3.1] - 2026-02-12 ### Added - `context_optimizer.py` — Context lazy-loading and complexity-based file recommendations - `cronjob-model-guide.md` — Model selection guide for cron-based tasks ### Changed - Enhanced model_router.py with communication pattern enforcement ## [1.2.0] - 2026-02-07 ### Added - Initial public release - `heartbeat_optimizer.py`, `model_router.py`, `token_tracker.py` - `PROVIDERS.md`, `config-patches.json`, `HEARTBEAT.template.md`docs/RESEARCH-NOTES.md4.6 KBae106ba67389upstream ↗
# Research Notes: Skill Marketplaces Research conducted 2026-02-06 by Morpheus. ## ClawHub.ai **URL:** https://clawhub.ai **GitHub:** https://github.com/openclaw/clawhub ### What It Is - Public skill registry for OpenClaw/Clawdbot - Publish, version, and search text-based agent skills - Vector search for discovery (not just keywords) - Star, comment, and moderation features ### Skill Format Requirements **SKILL.md Required Structure:** ```yaml --- name: skill-name description: One-line description of what the skill does version: 1.0.0 # Optional but recommended homepage: https://github.com/... # Optional metadata: {"openclaw":{...}} # Optional but recommended for ClawHub --- # Instructions and documentation... ``` **metadata.openclaw Fields:** - `emoji` — Icon for the skill - `homepage` — URL shown as "Website" in UI - `requires.bins` — Required binaries (e.g., ["python3"]) - `requires.env` — Required environment variables - `requires.config` — Required OpenClaw config paths - `primaryEnv` — Main API key environment variable - `install` — Array of installer specs (brew/node/go/uv/download) ### Publishing ```bash # Install ClawHub CLI clawhub install # Publish skill clawhub publish ./my-skill --slug my-skill --name "My Skill" --version 1.2.0 --changelog "Fixes + docs" # Update all installed skills clawhub update --all ``` ### What Makes Skills "Outstanding" Based on browsing ClawHub and OpenClaw docs: 1. **Clear SKILL.md** with proper YAML frontmatter 2. **One-line installation** instructions 3. **Works out-of-box** with minimal config 4. **Proper version** and changelog 5. **Good documentation** with examples 6. **metadata.openclaw** with requirements spelled out 7. **No external dependencies** if possible (stdlib only) --- ## SkillsMP.com **Status:** Could not fully research (403 Cloudflare protection) **What We Know:** - skills.sh appears to be related (skills.sh/openclaw/openclaw/clawhub) - May be an alternative skill directory - Need browser access to fully research **Recommendation:** Focus on ClawHub first as it's the official OpenClaw registry. --- ## onlycrabs.ai **URL:** https://onlycrabs.ai A SOUL.md registry (companion to ClawHub): - Publish and share system lore (personality files) - Same format principles as skills - SOUL.md only (no extra files for now) --- ## OpenClaw Skills System **Documentation:** https://docs.openclaw.ai/tools/skills ### Skill Locations (Precedence) 1. `<workspace>/skills` — Highest priority, per-agent 2. `~/.openclaw/skills` — Managed/local, shared across agents 3. Bundled skills — Lowest priority, shipped with OpenClaw ### AgentSkills Spec - OpenClaw uses AgentSkills-compatible format - Each skill is a directory with SKILL.md + supporting files - YAML frontmatter parsed at load time - `{baseDir}` can reference skill folder path in instructions ### Gating (Load-time Filters) Skills can be filtered by: - Required binaries (`requires.bins`) - Environment variables (`requires.env`) - OpenClaw config paths (`requires.config`) - OS platform (`os: ["darwin", "linux", "win32"]`) ### Config Overrides In `~/.openclaw/openclaw.json`: ```json { "skills": { "entries": { "token-optimizer": { "enabled": true, "env": { "SOME_VAR": "value" } } } } } ``` --- ## Token Optimizer Changes Made ### v1.1.0 Updates 1. **Multi-Provider Support** - Added OpenAI: gpt-4.1-nano → gpt-4.1-mini → gpt-4.1 → gpt-5 - Added Google: gemini-2.0-flash → gemini-2.5-flash → gemini-2.5-pro - Added OpenRouter: unified API with failover - Auto-detection based on available API keys 2. **Provider-Agnostic Tiers** - cheap = Haiku / Nano / Flash - balanced = Sonnet / Mini / 2.5 Flash - smart = Opus / GPT-4.1 / Pro - premium = GPT-5 (OpenAI only) 3. **New CLI Commands** - `model_router.py compare` — Show all models across providers - `model_router.py providers` — List available providers - `model_router.py detect` — Show auto-detected provider 4. **ClawHub-Ready SKILL.md** - Proper YAML frontmatter with metadata - One-line installation instructions - Complete script reference - Integration patterns 5. **CHANGELOG.md** - Semver format - Keep a Changelog standard - Version history table 6. **Updated Documentation** - README with quick start - PROVIDERS.md with full comparison - Better examples throughout --- ## Recommendations for Future 1. **Publish to ClawHub** once credentials available 2. **Add installer spec** for automated setup 3. **Consider Python package** for pip install 4. **Add tests** for model routing logic 5. **Dashboard integration** for real-time cost trackingLICENSE1.1 KB4f92758656ddupstream ↗
MIT License Copyright (c) 2026 OpenClaw Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.LICENSE.txt1.1 KB4f92758656ddupstream ↗
MIT License Copyright (c) 2026 OpenClaw Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.PR-DESCRIPTION.md1.6 KBc1880f6c03baupstream ↗
# Pull Request: v1.2.0 — Local Fallback + Revised Savings ## Summary This PR adds **Local Model Fallback (Emergency Fuel Mode)** and revises the savings estimates based on more accurate analysis. ## Changes ### 🛸 New: Local Model Fallback - Automatic failover to Ollama when cloud APIs fail (rate limits, billing, network) - Agent announces: "🛸 Emergency fuel mode — running on local backup" - Zero cost, no rate limits, works offline, full privacy - Supports Qwen 2.5, Llama 3.2, DeepSeek Coder ### 📊 Revised Savings Analysis Previous estimate: **50-80%** New estimate: **85-95%** Why the increase? 1. **Context optimization is more aggressive** — Simple chat loads only 2 files (SOUL.md + IDENTITY.md), which is 90% reduction, not 80% 2. **Model routing savings are multiplicative** — Haiku is 92% cheaper than Sonnet, not 60% 3. **Combined effect is multiplicative** — 1 - (0.22 × 0.36) = **92% savings** ### Files Changed - `README.md` — Updated headline, added local fallback section, revised cost analysis - `SKILL.md` — Updated version, savings estimates, added Ollama config section - `CHANGELOG.md` — Added v1.2.0 entry - `docs/LOCAL-FALLBACK.md` — **NEW** — Complete setup guide for Ollama integration ## Testing - [ ] All existing scripts still work - [ ] Ollama config example is valid JSON - [ ] Documentation is accurate ## To Push ```bash cd /root/.openclaw/workspace/agents/morpheus/token-optimizer-v1.2 git push -u origin morpheus/v1.2.0-updates ``` Then create PR via GitHub web UI or: ```bash gh pr create --title "feat: v1.2.0 - Local fallback + revised savings (85-95%)" \ --body "See PR-DESCRIPTION.md for details" ```SECURITY.md3.1 KB43b5c28653daupstream ↗
# Security policy — OpenClaw Token Optimizer 4.1.1 ## Trust boundary This is a local read-only analysis package. It contains Python standard-library scripts and a shell launcher. Hermes YAML parsing additionally uses optional PyYAML. There are no install hooks, telemetry, credential collectors, dynamic code evaluation, or automatic config changes. ## File behavior - `optimizer_core.py`: pure analysis functions; no files, network or processes. - `optimizer.py`: reads explicitly supplied JSON/context files and prints selected analysis. For the OpenClaw runtime, `--live` invokes only fixed `openclaw --version`, `openclaw models list`, `models status`, and `cron list` read commands with `subprocess.run`, argv lists, no shell, and a timeout. The installed OpenClaw executable and configured Gateway/providers are trusted dependencies. They may perform network requests; therefore we do NOT claim that live mode is offline or network-free. - `optimize.sh`: resolves its own directory and delegates arguments to optimizer.py. - Four old script names: migration shims to explicit v4 subcommands; no old writes remain. - `assets/`: public example policy, empty patch set, review templates; never auto-installed. - `references/PROVIDERS.md`: policy guidance, not executable setup or credential handling. - Markdown/license/manifest files: documentation and file integrity metadata only. ## Data handling Raw config/auth records, job commands/prompts and context contents are not printed. Only selected findings, model/agent identifiers and file basenames appear. Those selected identifiers can themselves be private: inspect reports before sharing. Errors deliberately withhold raw native stderr and invalid input values. No report upload occurs. Explicit config input can contain secrets; the file is read locally, never modified. Use sanitized exports where practical. Do not publish real config, session dumps or reports. Native status is held in process memory only. Live reads may update OpenClaw's own caches or logs; this package does not promise the native executable has zero side effects. ## Review and integrity The subprocess adapter may warrant scanner scrutiny: inspect its fixed argv call sites. A checksum manifest is not proof of safety and cannot guarantee a third-party review pass. Do not dismiss a scanner finding as a false positive without examining its evidence. Run `python3 -m unittest discover -s tests -v` from GitHub source and `sha256sum -c SHA256SUMS.txt` against the distributed package. Tests cover malformed inputs, missing usage, auth/capability gates, no-shell execution, and read-only behavior. No paid canary is run by the package. Catalog flags alone are not inference proof. Maintainer: [Asif2BD](https://github.com/Asif2BD) · [MissionDeck.ai](https://missiondeck.ai) ## Hermes file adapter Only explicitly selected profile config/jobs files are read. JSON uses the standard library; YAML uses optional PyYAML safe_load (never unsafe constructors). The adapter does not read .env or credentials, import Hermes, execute jobs, start schedulers or make network requests. Selected model identifiers may appear in reports; raw prompts/scripts/config do not.SHA256SUMS.txt1.8 KBf8c4bc4650f6upstream ↗
# ClawHub integrity manifest # Version: 4.1.1 # Integrity is not an independent security approval. 6deb5c5964d9aec121bc72221c0189db2c25fdf6d0f5abca504573f2c915d241 CHANGELOG.md cae3009b94a086590def655d997bf0a236f41b30dfddaeec059447243db1fde8 LICENSE.txt a392682bb2d2a442d460f78e39b781406023b7f1e9d471e5aa00e254167da545 README.md 672adadf958148742f0af05e14c959c9ea781bd3f1aa9578c0bf1052b5a30917 SECURITY.md dbb891806d21671a3dc757d7286d481ce8d2bf7ed034efa7a2175539aaeacc2c SKILL.md f93dd9d76568cf4edaabf54f2e0917c250a850396b501b71c3aa22c29a62a46b assets/HEARTBEAT.template.md 8a5739cf57d4f0810f85e80086dc5aee648ab80c423b437e7209dafe3d9feb15 assets/config-patches.json a95674eadd26e91b3f5bb4f90cb7e0f1de5dcfd96a050e7068286c3effaa4510 assets/config.example.json 571140051acceee68fc49edb68e095bc5c44457f112daf421052933c39b639ea assets/cronjob-model-guide.md d2a3a82779f72fda6385ee9f68ee82f0c0297cc563ce2f95c10ff99df8a92fe2 references/HERMES.md 201011cba849e63bde066f1328d128c72fb39532779c5825fe6c2dfb5df6b2fa references/PROVIDERS.md 4fda8b7fac415bdca7aef3e78b4ecb08d0ea2c28380273af58a5e589213421a1 references/QUICKSTART.md 383573284ad01da4e63015793f5399ed80f477a695e1eda8a00a472303456643 scripts/context_optimizer.py 7de333781278dc66026af5cb1ea7f4f33fd961da7af5d7c3877baccbf2606ab3 scripts/heartbeat_optimizer.py f14a06f3af6aa67767a28ba47b5ee3bd90434050f36737742744f005f71bd9e2 scripts/hermes_adapter.py 1e58db77f1417b8b6e0467141c7a8449f261bbb6955bfd78c3c6f48bef43cbf9 scripts/model_router.py 18b1d26dec3fa8009ec62325f2b161c5d5ed1bbf71c05f462f62e344c8eff0b8 scripts/optimize.sh 355db32d447aa8e2cfc87911db375ea20fe2e634edd87f575349289251f065a5 scripts/optimizer.py 6f03068622520bbc8f90106085d98194572b75bf357bcefcf45154eb135a3fc1 scripts/optimizer_core.py 12db8b727e62b82c2d39ce1c0f3ebf0d1d95657a8a2682cac1097d615a945a88 scripts/token_tracker.pytests/test_hermes.py3.8 KB252e892b616dupstream ↗
import contextlib import io import json import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts')) import optimizer from hermes_adapter import audit_hermes, resolve_job, read_config class HermesTests(unittest.TestCase): def test_job_precedence(self): c={'model':{'default':'global','provider':'global-provider'},'cron':{'model':'fleet','model_provider':'fleet-provider'}} r=resolve_job({'model':'pinned','provider':'pinned-provider','model_snapshot':'snapshot'},c,'env') self.assertEqual((r['model'],r['provider']),('pinned','pinned-provider')) def test_fleet_precedence(self): r=resolve_job({'model_snapshot':'snapshot'},{'cron':{'model':'fleet'}},'env') self.assertEqual((r['model'],r['modelSource']),('fleet','cron')) def test_snapshot_precedence(self): r=resolve_job({'model_snapshot':'snapshot'},{'model':'global'},'env') self.assertEqual((r['model'],r['modelSource']),('snapshot','snapshot')) def test_explicit_environment(self): self.assertEqual(resolve_job({}, {'model':'global'},'env')['model'],'env') def test_global_string_and_mapping(self): for model in ('global',{'default':'global'}):self.assertEqual(resolve_job({}, {'model':model})['model'],'global') def test_no_agent_not_charged_as_agent(self): r=audit_hermes({},[{'no_agent':True,'script':'SECRET SCRIPT','schedule':{'kind':'interval','minutes':1}}]) self.assertEqual(r['counts']['noAgent'],1) self.assertFalse(r['findings']) self.assertNotIn('SECRET SCRIPT',json.dumps(r)) def test_missing_script_flagged(self): self.assertEqual(audit_hermes({},[{'no_agent':True}])['findings'][0]['code'],'hermes_script_missing') def test_paused_skipped(self): r=audit_hermes({},[{'state':'paused'},{'enabled':False}]) self.assertEqual(r['counts']['enabled'],0) def test_frequent_agent(self): r=audit_hermes({'model':'m'},[{'schedule':{'kind':'interval','minutes':10}}]) self.assertIn('hermes_frequent_agent_job',[f['code'] for f in r['findings']]) def test_no_secret_content_output(self): sentinel='DO_NOT_EMIT_SECRET' r=audit_hermes({'api_key':sentinel,'model':'m'},[{'prompt':sentinel,'script':sentinel,'base_url':sentinel}]) self.assertNotIn(sentinel,json.dumps(r)) def test_invalid_boolean(self): with self.assertRaises(ValueError):audit_hermes({},[{'no_agent':'false'}]) def test_cli_hermes_never_invokes_openclaw(self): with tempfile.TemporaryDirectory() as d: c=Path(d)/'c.json';j=Path(d)/'j.json';c.write_text('{"model":"m"}');j.write_text('{"jobs":[]}') with patch('sys.argv',['optimizer','audit','--runtime','hermes','--config',str(c),'--jobs',str(j),'--json']),patch('optimizer.native') as native,contextlib.redirect_stdout(io.StringIO()): self.assertEqual(optimizer.main(),0);native.assert_not_called() def test_yaml_object_constructor_rejected(self): try:import yaml except ImportError:self.skipTest('Optional PyYAML unavailable') with tempfile.TemporaryDirectory() as d: p=Path(d)/'c.yaml';p.write_text('!!python/object/apply:os.system ["false"]') with self.assertRaises(ValueError):read_config(p) def test_hermes_live_requires_profile(self): with patch('sys.argv',['optimizer','audit','--runtime','hermes','--live']),contextlib.redirect_stderr(io.StringIO()): self.assertEqual(optimizer.main(),2) def test_hermes_live_route_not_fabricated(self): with patch('sys.argv',['optimizer','route','--runtime','hermes','--live','--hermes-home','/unused','--tier','routine','--policy','/unused']),contextlib.redirect_stderr(io.StringIO()): self.assertEqual(optimizer.main(),2)tests/test_optimizer.py5.8 KB3e3b4f076a90upstream ↗
import contextlib import io import json import subprocess import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'scripts')) from optimizer_core import audit, budget, context_report, route import optimizer CAT = {'models': [{'key': 'vendor/fast', 'available': True, 'input': 'text', 'contextWindow': 8000}, {'key': 'vendor/smart', 'available': True, 'input': 'text+image', 'contextWindow': 32000, 'supportsTools': True}]} STATUS = {'allowed': ['vendor/fast', 'vendor/smart'], 'auth': {'missingProvidersInUse': []}} POLICY = {'tiers': {'routine': ['vendor/fast', 'vendor/smart']}} class CoreTests(unittest.TestCase): def test_preference_and_capability(self): self.assertEqual(route(CAT, STATUS, POLICY, 'routine')['candidate'], 'vendor/fast') self.assertEqual(route(CAT, STATUS, POLICY, 'routine', image=True)['candidate'], 'vendor/smart') self.assertEqual(route(CAT, STATUS, POLICY, 'routine', tools=True)['candidate'], 'vendor/smart') self.assertIsNone(route(CAT, STATUS, POLICY, 'routine', context=40000)['candidate']) def test_route_issues_block(self): status = dict(STATUS, auth={'modelRouteIssues':[{'model':'vendor/fast'}]}) self.assertIsNone(route(CAT, status, POLICY, 'routine')['candidate']) def test_nonfinite_cost_rejected(self): for value in (float('nan'),float('inf'),-1,True): with self.assertRaises(ValueError): budget({'costUSD':value}) def test_unknown_does_not_become_available(self): self.assertIsNone(route({'models':[{'key':'vendor/fast','available':None}]}, STATUS, POLICY, 'routine')['candidate']) self.assertIsNone(route(CAT, {}, POLICY, 'routine')['candidate']) def test_auth_missing(self): self.assertIsNone(route(CAT, {'allowed':STATUS['allowed'],'auth':{'missingProvidersInUse':['vendor']}}, POLICY, 'routine')['candidate']) def test_missing_usage_not_zero(self): self.assertIsNone(budget()['costUSD']) self.assertEqual(budget()['status'], 'unknown') self.assertEqual(budget({'costUSD':2,'complete':False})['status'], 'incomplete') self.assertEqual(budget({'costUSD':6,'complete':False},5)['status'], 'exceeded') def test_context_duplicate(self): result = context_report({'a':'hello','b':'hello'}) self.assertEqual(result['files'][1]['duplicateOf'], 'a') def test_audit_does_not_output_private_fields(self): secret = 'PRIVATE_SENTINEL_NOT_FOR_REPORT' cfg = {'token':secret,'agents':{'defaults':{'model':'vendor/missing'},'entries':{}}} jobs = [{'enabled':True,'payload':{'kind':'agentTurn','message':secret},'name':secret,'schedule':{'everyMs':60000}}] result = audit(CAT, STATUS, cfg, jobs) self.assertNotIn(secret, json.dumps(result)) codes = {x['code'] for x in result['findings']} self.assertTrue({'model_absent','frequent_agent_job','automation_timeout'} <= codes) def test_disabled_and_command_jobs_not_flagged(self): jobs=[{'enabled':False,'payload':{'kind':'agentTurn'}},{'payload':{'kind':'command'}}] self.assertFalse(any(x['code'].startswith('automation') for x in audit(CAT,STATUS,{},jobs)['findings'])) def test_native_event_kinds_not_false_positives(self): for kind in ('heartbeat', 'systemEvent'): with self.subTest(kind=kind): result=audit(CAT,STATUS,{},[{'enabled':True,'payload':{'kind':kind},'schedule':{'everyMs':60000}}]) self.assertFalse(any(f['code'].startswith('automation_') or f['code']=='frequent_agent_job' for f in result['findings'])) def test_unknown_future_kind_still_reported(self): result=audit(CAT,STATUS,{},[{'payload':{'kind':'futureKind'}}]) self.assertIn('automation_kind_unknown',[f['code'] for f in result['findings']]) def test_agent_turn_lint_preserved(self): result=audit(CAT,STATUS,{},[{'payload':{'kind':'agentTurn'},'schedule':{'everyMs':60000}}]) codes={f['code'] for f in result['findings']} self.assertTrue({'automation_model_inherited','automation_timeout','automation_context','frequent_agent_job'} <= codes) def test_override(self): cfg={'agents':{'defaults':{'model':'vendor/fast'}}} self.assertIn('session_override',[x['code'] for x in audit(CAT,STATUS,cfg,[],[{'agentId':'a','model':'vendor/smart'}])['findings']]) def test_native_no_shell_or_probe(self): with patch('optimizer.subprocess.run') as run: run.return_value.returncode=0 run.return_value.stdout='{}' optimizer.native(['models','status','--json']) args, kwargs=run.call_args self.assertEqual(args[0],['openclaw','models','status','--json']) self.assertNotIn('shell',kwargs) self.assertEqual(kwargs['timeout'],45) def test_invalid_json_error_does_not_echo_input(self): with tempfile.TemporaryDirectory() as d: p=Path(d)/'bad.json';p.write_text('SECRET_SENTINEL') out=io.StringIO() with patch('sys.argv',['optimizer','audit','--config',str(p)]),contextlib.redirect_stderr(out): self.assertEqual(optimizer.main(),2) self.assertNotIn('SECRET_SENTINEL',out.getvalue()) def test_read_only_cli(self): with tempfile.TemporaryDirectory() as d: p=Path(d)/'config.json';p.write_text('{}') before=p.read_bytes() r=subprocess.run([sys.executable,str(Path(optimizer.__file__)),'audit','--config',str(p),'--json'],capture_output=True,text=True) self.assertEqual(r.returncode,0) self.assertEqual(p.read_bytes(),before) self.assertEqual(list(Path(d).iterdir()),[p]) self.assertFalse(json.loads(r.stdout)['coverage']['catalog']) if __name__=='__main__':unittest.main()tests/test_release.py1.2 KBa13690418974upstream ↗
import hashlib import re import unittest from pathlib import Path ROOT=Path(__file__).resolve().parents[1] class ReleaseTests(unittest.TestCase): def test_version_consistent(self): self.assertIn('version: 4.1.1',(ROOT/'SKILL.md').read_text()) self.assertIn('version-4.1.1-',(ROOT/'README.md').read_text()) self.assertIn('## v4.1.1',(ROOT/'CHANGELOG.md').read_text()) self.assertIn('# Version: 4.1.1',(ROOT/'SHA256SUMS.txt').read_text()) def test_manifest_and_secrets(self): for line in (ROOT/'SHA256SUMS.txt').read_text().splitlines(): if line.startswith('#'):continue digest,name=line.split(' ',1) data=(ROOT/name).read_bytes() self.assertEqual(hashlib.sha256(data).hexdigest(),digest,name) text=data.decode() for pattern in [r'gh[pousr]_[A-Za-z0-9]{30,}',r'sk-ant-[A-Za-z0-9_-]{20,}',r'-----BEGIN .*PRIVATE KEY-----',r'/root/\.openclaw',r'46\.225\.104\.65']: self.assertIsNone(re.search(pattern,text),name) def test_license(self): self.assertTrue((ROOT/'LICENSE').read_text().startswith('MIT License')) self.assertNotIn('Apache',(ROOT/'README.md').read_text())tools/build_release.py1.1 KB5d1da18f6bdcupstream ↗
#!/usr/bin/env python3 """Maintainer-only clean bundle builder; never shipped in the skill package.""" import hashlib import shutil from pathlib import Path ROOT = Path(__file__).resolve().parents[1] VERSION = '4.1.1' FILES = ['SKILL.md','README.md','CHANGELOG.md','LICENSE.txt','SECURITY.md'] for folder in ('scripts','assets','references'): FILES.extend(str(p.relative_to(ROOT)) for p in (ROOT/folder).iterdir() if p.is_file() and p.suffix in ('.py','.sh','.md','.json')) FILES = sorted(FILES) manifest = '# ClawHub integrity manifest\n# Version: '+VERSION+'\n# Integrity is not an independent security approval.\n' manifest += ''.join(hashlib.sha256((ROOT/f).read_bytes()).hexdigest()+' '+f+'\n' for f in FILES) (ROOT/'.clawhubsafe').write_text(manifest) (ROOT/'SHA256SUMS.txt').write_text(manifest) target = ROOT/'dist'/('openclaw-token-optimizer-'+VERSION) if target.exists(): shutil.rmtree(target) target.mkdir(parents=True) for name in FILES+['SHA256SUMS.txt','.clawhubsafe','.clawhubignore']: dest=target/name;dest.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(ROOT/name,dest) print(str(target))tools/test_hermes_compat.py2.4 KBb5482b4054a0upstream ↗
#!/usr/bin/env python3 """Maintainer integration test. Executes pinned Hermes storage code in a temp profile. Never shipped. Never launches the scheduler, a script or an inference request. """ import argparse import hashlib import json import os from pathlib import Path import subprocess import sys import tempfile ROOT=Path(__file__).resolve().parents[1] sys.path.insert(0,str(ROOT/'scripts')) from hermes_adapter import HERMES_SOURCE p=argparse.ArgumentParser();p.add_argument('--source',required=True);a=p.parse_args() source=Path(a.source).resolve() sha=subprocess.check_output(['git','-C',str(source),'rev-parse','HEAD'],text=True).strip() if sha!=HERMES_SOURCE:raise SystemExit('Hermes checkout differs from tested pin') with tempfile.TemporaryDirectory(prefix='optimizer-hermes-') as directory: home=Path(directory) (home/'config.yaml').write_text('model:\n default: global-model\n provider: global-provider\n') (home/'.env').write_text('SECRET_SENTINEL=NEVER_READ_OR_OUTPUT\n') env={'PATH':os.environ['PATH'],'HERMES_HOME':directory,'PYTHONPATH':str(source),'PYTHONDONTWRITEBYTECODE':'1'} code='''from cron.jobs import parse_schedule, save_jobs save_jobs([ {'enabled':True,'no_agent':True,'script':'never-executed.py','schedule':parse_schedule('every 5m')}, {'enabled':True,'model':'pinned','schedule':parse_schedule('every 15m')}, {'enabled':True,'model_snapshot':'snapshot','schedule':parse_schedule('every 2h')}, {'enabled':False,'schedule':parse_schedule('every 5m')} ])''' subprocess.run([sys.executable,'-c',code],env=env,cwd=source,check=True,capture_output=True) def digest():return {str(f.relative_to(home)):hashlib.sha256(f.read_bytes()).hexdigest() for f in home.rglob('*') if f.is_file()} before=digest() r=subprocess.run([sys.executable,str(ROOT/'scripts/optimizer.py'),'audit','--runtime','hermes','--live','--hermes-home',directory,'--json'],env=env,capture_output=True,text=True,check=True) result=json.loads(r.stdout) assert before==digest(), 'Profile modified' assert result['counts']=={'total':4,'enabled':3,'noAgent':1} assert result['automations'][1]['resolution']['model']=='pinned' assert result['automations'][2]['resolution']['model']=='snapshot' assert 'NEVER_READ_OR_OUTPUT' not in r.stdout print(json.dumps({'sourceCommit':sha,'nativeStoreRoundtrip':True,'profileUnchanged':True,'counts':result['counts'],'schedulerStarted':False,'inferencePerformed':False}))assetsupstream ↗
Contents are not inlined in the catalog. Open the upstream file.
docsupstream ↗
Contents are not inlined in the catalog. Open the upstream file.
referencesupstream ↗
Contents are not inlined in the catalog. Open the upstream file.
scriptsupstream ↗
Contents are not inlined in the catalog. Open the upstream file.
Plain-text copy, no login: /skill-bundles/openclaw-token-optimizer.md