neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
翻譯準備中
Rust crates for a local AI API gateway: rule-based routing, mid-stream failover, cost accounting, outbound secret redaction and tool-call inspection. Ships the twcore binary.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
ThinkWatch Core is a set of Rust crates and the twcore gateway binary built
from them. Claude Code, Codex and other clients of the Anthropic, OpenAI and
Gemini APIs send their requests to twcore, which routes each request by rule,
fails over to another upstream before the response begins, records what each
request cost, redacts secrets before a request is sent, and inspects the tool
calls an upstream returns.檢視完整 README ↗ThinkWatch Core is the gateway engine behind ThinkWatch: a set of Rust crates
and the twcore binary built from them. Claude Code, Codex and other clients of
the Anthropic, OpenAI and Gemini APIs point at twcore once. From then on,
credentials can be kept out of outgoing requests, the tool calls that come back
are checked, and every request is recorded with where it went and what it cost. twcore runs inside the
desktop app ThinkWatch Lite
or on its own on a Linux server, and
ThinkWatch Enterprise builds
on four of its crates.
Documentation: configuration reference · running core on a server · thinkwat.ch/core
config.yaml; a change from
an editor, the CLI or the control plane applies within a second once it
validates, and the last fifty versions can be restored.Desktop. ThinkWatch Lite
includes twcore and updates it with the app; nothing else to download.
Linux server (x86_64 or aarch64, glibc 2.35+: Ubuntu 22.04, Debian 12 or
later). One command installs twcore as a systemd service with its own user:
curl -fsSL https://raw.githubusercontent.com/ThinkWatchProject/ThinkWatch-Core/main/scripts/install.sh | sudo sh
The script does not start the service. Then, as the service user:
alias twc='sudo -u thinkwatch THINKWATCH_HOME=/var/lib/thinkwatch twcore'
twc remote enable --allow 192.168.1.0/24 # open the remote control port to this network
twc check # validate config.yaml
sudo systemctl enable --now twcore # start the service, now and at boot
twc control-key # the key for ThinkWatch Lite on stdout; address and port on stderr
In ThinkWatch Lite, Settings → Connection → Add remote connection takes the
address, control port and key. The app connects only to the core version it
includes; sudo twcore upgrade --version <version> --restart switches the
server to it. Neither port uses TLS, so keep both on trusted networks.
Running core on a server covers secrets, network exposure,
upgrades and uninstalling.
Prebuilt binaries for macOS (Apple silicon), Windows (x64, ARM64) and Linux
(x86_64, aarch64) are attached to every
release,
each with a .sha256 checksum; the Linux .tar.gz includes the systemd unit.
twcore keeps its configuration and data in ~/.thinkwatch
(%APPDATA%\ThinkWatch on Windows), or in THINKWATCH_HOME. Every field is in
the configuration reference. The configuration holds keys in
plain text and only its owner can read it, which keeps out other users but not
programs running as the same user; outbound redaction protects what leaves the
machine, not the file. Where the file is
describes what protects it.
The control plane is an HTTP API inside an encrypted channel: a unix socket
(a loopback port on Windows), plus the optional remote port. Every connection
starts with a Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s handshake keyed by
listen.control.key; there are no certificates. curl cannot reach it;
twcore call can:
twcore call /status
twcore call -X POST -d '{"model":"claude-sonnet-4-5","route":"default"}' /dryrun
twcore control-key --rotate # replace the key; connections made with the old key are closed
The remote port admits only sources in allow_from, at most 32 connections at
a time, and cannot stop core, take the diagnostic bundle or change
listen.control.
| Crate | Role |
|---|---|
tw-dialect | Conversion between the four API formats; usage parsing |
tw-guard | The three protections and their rules: outbound redaction, tool-call inspection, content filter |
tw-breaker | Circuit-breaker state machine |
tw-bedrock | Amazon Bedrock on the wire: SigV4 signing, eventstream, addresses, model catalog |
tw-types | Messages for people: stable code, arguments, English sentence |
tw-engine | Routing rules and groups |
tw-pricing | Price table, price sheets, measured / estimated / unpriced cost |
tw-yaml | Minimal edits to the original YAML text |
tw-secret | Environment and command-sourced credentials, masking |
tw-watch | Debounced directory watching |
tw-api | Control-plane contract: types and client |
tw-link | Control-channel handshake and encryption |
tw-config | Configuration schema, loading and validation |
tw-store | Request history and runtime state on SQLite |
tw-observe | Event bus |
tw-gateway | Data plane: the life of a request |
tw-plugin | Script-plugin sandbox: QuickJS compiled to WebAssembly, run by Wasmtime |
tw-pack | Configuration packs (.twconfig): format, encryption, local backups, and the item model import and sync compare on |
tw-control | Control-plane server |
ThinkWatch Enterprise depends only on the first four, which depend only on one
another; CI checks that Enterprise compiles against every change to them.
ThinkWatch Lite pins tw-api, tw-types, tw-yaml, tw-guard, tw-watch and
tw-link to a release tag and bundles the twcore of the same release. Setting
up AI clients and scanning their configuration happen in Lite, on the machine
it runs on; twcore issues each client its own gateway key. The binary lives
in bin/twcore. Only tw-gateway and twcore may depend on tw-plugin, the
one crate whose build needs more than Rust (see below), so building Lite or
Enterprise against these crates never does.
Requires a recent stable Rust toolchain (1.94.1 or later), plus an LLVM clang
that can compile C to WebAssembly and the llvm-ar that comes with it. The
plugin sandbox (tw-plugin) compiles QuickJS to WebAssembly while it builds;
Apple's clang cannot target WebAssembly.
| System | Install |
|---|---|
| macOS | brew install llvm (found where Homebrew puts it; it does not need to be on PATH) |
| Debian, Ubuntu | sudo apt install clang llvm |
| Fedora | sudo dnf install clang llvm |
| Windows | the LLVM installer from LLVM's releases, or winget install LLVM.LLVM |
The build tries Homebrew's LLVM, then clang and clang-N (clang-19,
clang-18, …) on PATH, and uses the first that really produces WebAssembly.
To pick one yourself, set TW_WASM_CLANG, and TW_WASM_AR when its llvm-ar
is not next to it. Rust's wasm32-unknown-unknown target is listed in
rust-toolchain.toml, so rustup installs it; the linking is done by the
rust-lld that ships with Rust. Nothing is downloaded during the build. Each
build records which clang it used and the SHA-256 of the WebAssembly module
(tw_plugin::GUEST_CLANG, tw_plugin::GUEST_WASM_SHA256).
cargo build --release -p twcore # target/release/twcore
cargo run -p twcore -- init # write an initial config.yaml
cargo run -p twcore -- serve # start the gateway and the control plane
cargo test --workspace # unit and integration tests
scripts/smoke.sh # every path on the real binary, in a temporary HOME
CONTRIBUTING.md lists the checks a pull request has to pass and describes the configuration reference, the price list and releases.