a4abcdefa3
embedder.heads_path is empty by default and deploy/mavend.json sets it. A missing or broken weights file logs and leaves the heads nil, because refusing to start over a routing accelerator would trade a working box for a better one. TestONNXRoutingHeads is the same cascade TestONNXBaseline scores with one arm added, so the two are directly comparable. It also checks the Go tokenizer against the Python one, since the heads were trained through transformers and are read through a hand-written tokenizer: a mismatch shows up here as a score below what Python measured on the same weights, and nowhere else. That is how the reversed word pieces were found. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ptwopxyo3Z2kwFckHkLvN
270 lines
12 KiB
JSON
270 lines
12 KiB
JSON
{
|
|
"db_path": "/var/lib/maven/maven.db.enc",
|
|
"db_tmpfs": "/dev/shm/maven-plain.db",
|
|
"db_key_env": "MAVEN_DB_KEY",
|
|
"socket_path": "/run/maven/mavend.sock",
|
|
"state_dir": "/var/lib/maven",
|
|
|
|
"//disabled_rules": [
|
|
"Nudge rules that are not wired at all. Names come from loop.DefaultRules:",
|
|
"water, meal, break, service_down, netdata_critical.",
|
|
"service_down is back on: mavpoll now writes one fact per kuma monitor",
|
|
"(service_down:<name>), so the nudge names the service and pausing a monitor",
|
|
"in kuma silences that monitor. It is also edge-triggered, so a service that",
|
|
"stays down is one nudge, not one every fifteen minutes."
|
|
],
|
|
"disabled_rules": [],
|
|
|
|
"phraser": {
|
|
"model_path": "/opt/maven/models/llm/qwen3/Qwen3-1.7B-UD-Q4_K_XL.gguf",
|
|
"bin_path": "llama-server",
|
|
"n_gpu_layers": 99,
|
|
"n_ctx": 4096,
|
|
"cache_ram_mib": 512,
|
|
"timeout": "60s",
|
|
"llm_nudges": false
|
|
},
|
|
|
|
"//ntfy": [
|
|
"The second reach (V-649). Until 07-08-2026 telegram was the only one, and",
|
|
"telegram needs api.telegram.org, the socks relay below and a matching ufw",
|
|
"rule — three things in series that have each failed once, and when they do",
|
|
"a sev4 nudge has nowhere to go. ntfy shares none of them: it is reached",
|
|
"directly, no relay.",
|
|
"It is not only a spare. The routing table sends sev3-away and away",
|
|
"reminders here and NOWHERE else, so with this block absent those two",
|
|
"routes hit a nil sink and vanish without a log or an outbox row.",
|
|
"The credential is an ntfy access token, scoped write-only to this one",
|
|
"topic, so a popped sink can push to it and cannot read it back. Set it in",
|
|
"deploy/telegram.env beside the telegram secrets; that file is gitignored."
|
|
],
|
|
"ntfy": {
|
|
"base_url": "https://ntfy.kvmx.ru",
|
|
"topic": "maven",
|
|
"token": "${NTFY_TOKEN}"
|
|
},
|
|
|
|
"telegram": {
|
|
"bot_token": "${TELEGRAM_BOT_TOKEN}",
|
|
"chat_id": "${TELEGRAM_CHAT_ID}",
|
|
|
|
"//proxy": [
|
|
"api.telegram.org is not reachable directly from this box, so every send",
|
|
"timed out. The relay is the x-ui socks inbound on the host, port 10808;",
|
|
"192.168.240.1 is the maven_default bridge gateway, which is how a",
|
|
"container addresses the host. mavend is on that network.",
|
|
"This needs a matching ufw rule or the container's SYN is dropped:",
|
|
" ufw allow from 192.168.240.0/20 to any port 10808 proto tcp"
|
|
],
|
|
"proxy": "socks5://192.168.240.1:10808",
|
|
"//intake": [
|
|
"Read the chat as well as write to it (V-637). The poller long-polls",
|
|
"getUpdates through the same relay and accepts chat_id as the only",
|
|
"sender. Deleting this key turns inbound off again.",
|
|
"chat_id must be numeric here or the daemon refuses to start: an inbound",
|
|
"update names its chat by number, so an @-name would match nothing."
|
|
],
|
|
"intake": true
|
|
},
|
|
|
|
"//workstation": [
|
|
"The big model on the desk PC (workpc, 7900 GRE 16GB), fronted by",
|
|
"mavgpud on port 8080. It runs gemma-4-12b and it is preferred over the",
|
|
"resident Qwen3-1.7B for routing and replies whenever the card is free.",
|
|
"The machine is never assumed up: it sleeps, and the card is often held by",
|
|
"a CPT run, in which case mavgpud answers 503 and Maven falls back to the",
|
|
"resident model without saying so. Deleting this block restores exactly",
|
|
"the behaviour homesrv had before it existed.",
|
|
"Addressed by LAN address, not container name: mavgpud runs on another",
|
|
"machine and there is no shared docker network to name it on."
|
|
],
|
|
"workstation": {
|
|
"url": "http://192.168.1.105:8080",
|
|
"probe": "15s",
|
|
"timeout": "90s"
|
|
},
|
|
|
|
"//search": [
|
|
"The live web, searched after his own notes and before Kiwix. Only the",
|
|
"query string leaves the box — never a note, a fact, the persona block or",
|
|
"the history — and a question about him never reaches here at all.",
|
|
"The instance must have `json` in search.formats (settings.yml); a stock",
|
|
"SearXNG answers 403 to format=json and every search then fails. It is",
|
|
"addressed by container name, so it needs the same maven_default",
|
|
"attachment kiwix has, and it must listen on 9563: 8080 is taken several",
|
|
"times over on this box. No instance reachable ⇒ she falls through to the",
|
|
"ZIMs and never says the search failed."
|
|
],
|
|
"search": {
|
|
"url": "http://searxng:9563",
|
|
"max_results": 4,
|
|
"snippet_runes": 1500,
|
|
"language": "auto",
|
|
"timeout": "8s"
|
|
},
|
|
|
|
"//kiwix": [
|
|
"The offline encyclopedia, searched after his own notes and before anything",
|
|
"on the network. kiwix-server publishes 8034 on loopback only, so a container",
|
|
"cannot reach it by address; it is attached to the maven_default network",
|
|
"instead and addressed by container name. That attachment is imperative and",
|
|
"does not survive recreating the kiwix stack — make it declarative there:",
|
|
" networks: [default, maven_default] # maven_default: external: true",
|
|
"The book is the catalog name from the /content/... href in",
|
|
"/catalog/v2/entries, not the display title. Others on the box:",
|
|
"ifixit_en_all_2025-06, devdocs_en_ansible_2025-10."
|
|
],
|
|
"kiwix": {
|
|
"url": "http://kiwix-server:8080",
|
|
"book": "wikipedia_en_all_maxi_2026-02",
|
|
"book_ru": "wikipedia_ru_all_maxi_2026-02",
|
|
"max_results": 5,
|
|
"snippet_runes": 1500
|
|
},
|
|
|
|
"//morning_routines": [
|
|
"The daily checklist (Vikunja #280). Each item is done when its fact_key",
|
|
"gets a non-voided fact inside the window, so 'выпил воды' closes water and",
|
|
"nothing has to be ticked by hand. nudge_at fires once, at the end of the",
|
|
"window, and only for what is still open. Weekdays empty = every day."
|
|
],
|
|
"morning_routines": [
|
|
{
|
|
"name": "утро",
|
|
"window_start": "08:00",
|
|
"window_end": "11:00",
|
|
"nudge_at": "10:30",
|
|
"severity": 1,
|
|
"items": [
|
|
{ "key": "medicine", "fact_key": "medicine", "label": "лекарство" },
|
|
{ "key": "water", "fact_key": "water", "label": "вода" },
|
|
{ "key": "pets", "fact_key": "pets", "label": "покормить кота" }
|
|
]
|
|
}
|
|
],
|
|
|
|
"//feeds": [
|
|
"RSS reading (Vikunja #258). Every item lands as a note with source",
|
|
"rss:<name>, which is also what puts entries in the intake journal that",
|
|
"/events reads. Only the feed URL leaves the box.",
|
|
"This is a starting pair, not a curated set — trim or extend it."
|
|
],
|
|
"feeds": {
|
|
"poll_interval": "30m",
|
|
"max_items": 5,
|
|
"max_age": "24h",
|
|
"sources": [
|
|
{ "name": "lwn", "url": "https://lwn.net/headlines/newrss", "category": "технологии" },
|
|
{ "name": "archlinux", "url": "https://archlinux.org/feeds/news/", "category": "технологии" }
|
|
]
|
|
},
|
|
|
|
"//crawl": [
|
|
"Reading a web page (Vikunja #259). on_demand answers 'посмотри <URL>'.",
|
|
"No allow_hosts, so any public host he names is readable; private",
|
|
"addresses are refused unconditionally by internal/webfetch and do not",
|
|
"need listing. Setting allow_hosts here would also narrow on-demand,",
|
|
"which is the point of leaving it empty."
|
|
],
|
|
"crawl": {
|
|
"on_demand": true,
|
|
"timeout": "10s",
|
|
"max_runes": 4000
|
|
},
|
|
|
|
"digest": {
|
|
"enabled": true,
|
|
"window": "30m",
|
|
"max_items": 5,
|
|
"severity_ceiling": 2
|
|
},
|
|
|
|
"pattern_proposals": {
|
|
"notify": false,
|
|
"cooldown": "24h"
|
|
},
|
|
|
|
"mcp": {
|
|
"timeout": "15s",
|
|
"servers": [
|
|
{
|
|
"name": "vikunja",
|
|
"url": "http://192.168.1.104:9100/mcp",
|
|
"allow_private": true,
|
|
"allow_tools": ["list_projects", "list_tasks", "get_task_details", "create_task"],
|
|
"max_tools": 6,
|
|
"enabled": false
|
|
}
|
|
]
|
|
},
|
|
|
|
"smarthome": {
|
|
"provider": "homeassistant",
|
|
"url": "http://192.168.1.50:8123",
|
|
"token": "${HA_TOKEN}",
|
|
"domains": ["light", "switch", "sensor"],
|
|
"max_entities": 40,
|
|
"timeout": "10s",
|
|
"refresh": "15m",
|
|
"enabled": false
|
|
},
|
|
|
|
"netscan": {
|
|
"subnets": ["192.168.1.0/24"],
|
|
"ports": [22, 80, 443, 8080],
|
|
"timeout": "400ms",
|
|
"rate": 100,
|
|
"max_hosts": 256,
|
|
"enabled": true
|
|
},
|
|
|
|
"nexus": { "url": "http://nexus:9740" },
|
|
"praxis": { "url": "http://praxis:8989" },
|
|
"hexis": { "url": "http://hexis:9741" },
|
|
|
|
"voice": {
|
|
"enabled": true,
|
|
"bind": "0.0.0.0:9100",
|
|
"lang": "ru",
|
|
"stt": { "socket": "/run/maven/stt.sock", "lang": "ru" },
|
|
"tts": { "socket": "/run/maven/tts.sock", "lang": "ru" },
|
|
"embedder": {
|
|
"model_path": "/opt/maven/models/embedder/multilingual-e5-small/model_quantized.onnx",
|
|
"tokenizer_path": "/opt/maven/models/embedder/multilingual-e5-small/tokenizer.json",
|
|
"lib_path": "/opt/maven/lib/libonnxruntime.so",
|
|
"heads_path": "/opt/maven/models/embedder/router-heads/router_heads.onnx"
|
|
},
|
|
"llm_router": true,
|
|
"query_min_score": 0.55,
|
|
"query_min_margin": 0.008,
|
|
"clarify_max_attempts": 3,
|
|
"tool_timeout": "30s",
|
|
"tools": [
|
|
{ "name": "status", "cmd": ["systemctl", "status"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["статус", "покажи статус", "проверь статус"] },
|
|
{ "name": "ps", "cmd": ["docker", "ps"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["статус докера", "лог докера", "покажи запущенные контейнеры", "покажи контейнеры", "список контейнеров", "что запущено"] },
|
|
{ "name": "uptime", "cmd": ["uptime"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["покажи uptime", "аптайм", "как работает сервер", "сколько работает сервер"] },
|
|
{ "name": "disk", "cmd": ["df", "-h"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["сколько места на диске", "сколько свободного места на диске", "место на диске", "покажи диск"] },
|
|
{ "name": "memory", "cmd": ["free", "-h"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["свободная память", "сколько оперативной памяти свободно", "покажи память"] },
|
|
{ "name": "logs", "cmd": ["journalctl", "-n", "50", "-u"], "scope": "homelab", "destructive": false,
|
|
"aliases": ["покажи логи", "логи", "лог"] },
|
|
{ "name": "restart", "cmd": ["systemctl", "restart"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["перезапусти", "перезагрузи", "рестарт"] },
|
|
{ "name": "stop", "cmd": ["systemctl", "stop"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["останови", "останови сервис"] },
|
|
{ "name": "start", "cmd": ["systemctl", "start"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["запусти", "запусти сервис"] },
|
|
{ "name": "docker-restart", "cmd": ["docker", "restart"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["перезапусти контейнер", "перезагрузи контейнер"] },
|
|
{ "name": "docker-stop", "cmd": ["docker", "stop"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["останови контейнер"] },
|
|
{ "name": "reboot", "cmd": ["systemctl", "reboot"], "scope": "homelab", "destructive": true,
|
|
"aliases": ["перезагрузи сервер", "перезагрузи хост"] }
|
|
]
|
|
}
|
|
}
|