richarjiang f429caf7e8 Switch dashboard to a light theme and drop Google Fonts.
- Replace the warm dark palette with an Apple-style light surface scheme.
- Inline fonts via the system stack instead of preconnecting to Google.
- Rename the document title from "Laya 路由看板" to "Laya 路由".

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 10:14:52 +08:00
2026-09-24 10:04:41 +08:00
2026-09-24 10:04:41 +08:00
2026-09-24 10:04:41 +08:00
2026-09-24 10:04:41 +08:00
2026-09-24 10:04:41 +08:00

Laya Router Hook

中文说明

A local Laya multilingual service that scores each coding prompt before Codex or Claude Code sees it. The hook adds a System-1 hint: task level, and whether the agent should plan, read the repo, look up docs, or reason carefully.

It does not switch models. Codex and Claude Code keep the model already configured for that session.

Prompt
  -> UserPromptSubmit hook (stdlib only, fail-open)
  -> http://127.0.0.1:8765
  -> Laya multilingual
  -> additionalContext
  -> Codex / Claude Code

A browser dashboard at http://127.0.0.1:8765/ shows each decision, grouped by session, and updates over server-sent events.

Cursor loads Claude Code hooks, but its prompt event cannot inject context. The hook sees CURSOR_VERSION and returns immediately.

Install

macOS, uv, and Python 3.10+.

./install.sh

The script:

  1. Creates ~/.laya-router/.venv and installs this repo into it
  2. Downloads the multilingual weights of convaiinnovations/laya
  3. Registers a launchd agent, com.laya-router, that starts at login and restarts if it exits
  4. Writes a hook when Codex or Claude Code is already installed

The install is a normal copy, not an editable install. launchd blocks forever if it has to import a checkout under ~/Documents. laya-router restart copies the repo into the venv again and restarts the service.

One client only:

./install.sh --only codex
./install.sh --only claude

The first Codex session must trust the hook. Start codex and run /hooks. Editing the Python files does not change the command string, so Codex does not ask for review again.

Commands

After install, the binaries live in ~/.laya-router/.venv/bin.

laya-router status
laya-router logs
laya-router logs -f
laya-router route "Rename the variables in this function"
laya-router restart
laya-router stop
laya-router start

Remove the hooks and the launchd agent, and keep the runtime directory:

./uninstall.sh

Also delete config, logs, and the virtualenv:

./uninstall.sh --purge

Configuration

~/.laya-router/config.toml is written on first install and is not overwritten later.

Key Meaning
host Bind address. Keep 127.0.0.1.
port Default 8765.
device auto, mps, cuda, or cpu. auto falls through if warmup fails.
log_prompts Write the raw prompt into data/routes.jsonl.
request_timeout Seconds the hook waits for the service. Default 2.5.
max_prompt_chars Max characters sent to the model. Longer prompts keep the head and tail.

Restart after config or server changes: laya-router restart.

How a decision is made

One forward pass asks five questions:

  • task_level: simple, normal, or complex
  • needs_plan, needs_repo, needs_web, needs_deep_reasoning: probabilities from 0 to 1

laya-multilingual ships without fitted temperatures, so a displayed 0.90 is not a calibrated 90%. The injected text says the numbers are hints. Ordinal score is not used; Laya's own benchmarks show it is the weakest primitive.

Every call is appended to ~/.laya-router/data/routes.jsonl (timestamp, client, working directory, session, prompt unless disabled, scores, latency, question version). That file is the material for a later coding-specific fine-tune.

If the service is down, the hook prints {} and exits 0. Codex and Claude Code continue. The error is appended to ~/.laya-router/logs/hook.log.

Develop

PYTHONPATH=src uv run --no-project --with pytest python -m pytest

Unit tests do not load the model. After the service is up, laya-router route runs a real inference.

File Role Picked up
src/laya_router/questions.py Question text. Bump QUESTIONS_VERSION when the wording changes. laya-router restart
src/laya_router/render.py Text injected into the agent laya-router restart, then the next prompt
src/laya_router/hook.py Timeout, slash-command skip, fail-open laya-router restart, then the next prompt
src/laya_router/server.py Model load, /route, dashboard laya-router restart
src/laya_router/dashboard.html Browser UI laya-router restart

Do not run the server with --reload. A reloader starts extra processes and loads the model more than once.

Security

This repository does not contain API keys, account tokens, or model weights. The installer never uploads ~/.claude/settings.json or ~/.codex.

The service has no authentication. It listens on 127.0.0.1 only. /route accepts a prompt, and the dashboard shows stored prompts. Binding any other address makes both reachable by anyone who can open that port. The process prints a warning if host is not a loopback address. Do not put this port on a public interface, and do not reverse-proxy it without adding auth yourself.

routes.jsonl stores the raw prompt by default, including anything you paste into Codex or Claude Code. Set log_prompts = false to keep only a SHA-256. The runtime directory is ~/.laya-router/, outside this repo. Do not commit it.

The installer rewrites ~/.codex/hooks.json and merges a UserPromptSubmit entry into ~/.claude/settings.json. That Claude file often holds API credentials. The tool preserves existing keys, writes a timestamped *.bak-* copy before changing a file, and removes only its own hook on uninstall. Read the diff before you publish a dotfile.

A web page on another origin cannot read these responses: the server does not send Access-Control-Allow-Origin. Keep the default bind address anyway.

The hook adds a hint. It does not copy the user prompt back into the injected instructions.

Limits

The multilingual base checkpoint is a fast model to specialize, not a zero-shot coding router. Public typed-decision numbers for the base checkpoints sit near chance until a domain fine-tune. Expect some complex requests to be labeled simple. Use the log, then fine-tune, before trusting the scores to choose a model.

License

No license file is in this repository yet. Add one before you publish it. The Laya model and library are Apache-2.0; this project's license is a separate choice.

Description
No description provided
Readme Apache-2.0 390 KiB
Languages
Python 88.3%
HTML 10.7%
Shell 1%