{"id":480987,"date":"2026-05-25T17:56:26","date_gmt":"2026-05-25T17:56:26","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=480987"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=480987","title":{"rendered":"\u0421\u0432\u043e\u0439 AI-\u0430\u0433\u0435\u043d\u0442 \u0438\u0437 \u043f\u043e\u0447\u0442\u044b, systemd \u0438 LLM"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u044f \u0441\u0442\u0440\u043e\u0438\u043b \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u043e\u0431\u043b\u0430\u043a\u043e \u043d\u0430 Proxmox. \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0436\u0438\u0432\u0451\u0442 \u043a\u043e\u0435-\u0447\u0442\u043e \u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u2014 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439 AI-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u043c\u043e\u0433\u0443 \u043f\u043d\u0443\u0442\u044c \u043f\u0438\u0441\u044c\u043c\u043e\u043c \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0432 Telegram, \u0438 \u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u0442, \u043f\u043e\u0434\u0443\u043c\u0430\u0432. \u041f\u0440\u0438\u0447\u0451\u043c \u043f\u043e\u0434\u0443\u043c\u0430\u0432 \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443: \u0441 \u043c\u043d\u043e\u0433\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435\u043c, \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u0417\u043e\u0432\u0443\u0442 \u0435\u0433\u043e Threlium, \u0438 \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043e\u043d \u0447\u0435\u0440\u0442\u043e\u0432\u0441\u043a\u0438 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c \u0441\u0435\u0431\u044f.<\/p>\n<p>\u0417\u0430\u0447\u0435\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0438 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u2014 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043d\u0438\u0436\u0435.<\/p>\n<hr\/>\n<h3>\u0417\u0430\u0447\u0435\u043c \u0441\u0432\u043e\u0439 \u0430\u0433\u0435\u043d\u0442<\/h3>\n<p>\u0412\u0441\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 LLM-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u044b \u2014 \u0447\u0443\u0436\u0438\u0435. \u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430, \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043e\u0434\u043d\u0438\u043c \u043e\u043a\u043d\u043e\u043c \u0447\u0430\u0442\u0430, \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u0442, \u0435\u0441\u0442\u044c \u0447\u0430\u0442-\u0441\u0435\u0441\u0441\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443\u043c\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u0436\u0435 \u0431\u0435\u0433\u0430\u044e\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u0441\u0440\u0435\u0434\u043d\u0435\u043d\u044c\u043a\u043e\u043c GPU: Qwen, Llama, Mistral. \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0436\u0438\u0442\u044c \u043d\u0430 \u043c\u043e\u0451\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043c\u043e\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0446\u0438\u043a\u043b \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439 \u2014 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0441\u043f\u0440\u043e\u0441\u0438\u043b \u2192 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u00bb, \u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u0441 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438, \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u041f\u0440\u0438\u0447\u0435\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0431\u044b \u043a\u043e\u0434\u0430 \u0432 \u043d\u0435\u043c \u0431\u044b\u043b\u043e, \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0430\u043d\u0430\u043b\u043e\u0433\u0430\u043c\u0438 \u0438 \u043e\u043d \u043c\u043e\u0433 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0430\u043c \u0441\u0435\u0431\u044f \u0438\u043b\u0438 \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e. \u041f\u0440\u0438\u0447\u0451\u043c \u0438\u0437 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 Unix-\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u043e\u0432.<\/p>\n<hr\/>\n<h3>\u0427\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0438\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0445\u043e\u0434<\/h3>\n<ol>\n<li>\n<p>\u041c\u0430\u043b\u043e \u043a\u043e\u0434\u0430, \u0435\u0441\u043b\u0438 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u043a\u043b\u0435\u0435\u043a\u043e\u0434 \u0438 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044e (\u043c\u043e\u0434\u0443\u043b\u044c types), \u0442\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 6\u043a \u0441\u0442\u0440\u043e\u043a \u043f\u0430\u0439\u0442\u043e\u043d \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0423 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u043e \u0436\u0435 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0442\u043d\u044f\u043c\u0438 \u0442\u044b\u0441\u044f\u0447 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0435\u0441\u0442\u044c, \u0432\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0430\u0433\u0435\u043d\u0442\u0430 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u0430 \u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0442\u043e\u0440\u0430 ansible playbook.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0430\u0433\u0435\u043d\u0442 \u0432\u043b\u0435\u0437\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u0443\u044e \u0434\u0435\u0448\u0435\u0432\u0443\u044e VPS.<\/p>\n<\/li>\n<li>\n<p>\u0410\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0431\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u044f \u044d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u043e\u0432\u0441\u0435, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0432\u044b\u0442\u0435\u043a\u0430\u0435\u0442 \u0438\u0445 \u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044d\u0442\u043e\u0439 \u0448\u0442\u0443\u043a\u0438 \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u0442\u044c ssh \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0430\u0433\u0435\u043d\u0442\u0443 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0433\u0434\u0435 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442, \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f.<\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<h3>\u0424\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 = \u043f\u0438\u0441\u044c\u043c\u043e<\/h3>\n<p>\u0421\u0430\u043c\u043e\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 Threlium \u2014 \u0432 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0438\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430. \u041d\u0435 \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 \u00ab\u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c\u00bb, \u0430 \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041b\u044e\u0431\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u2014 \u044d\u0442\u043e RFC 5322 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e MIME-\u0444\u0430\u0439\u043b \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 \u0438 \u0442\u0435\u043b\u043e\u043c. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u2014 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0438\u0441\u044c\u043c\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 Maildir. \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u2014 \u0442\u043e\u0436\u0435 Maildir (\u0444\u043e\u0440\u043c\u0430\u0442 <code>tmp\/<\/code>, <code>new\/<\/code>, <code>cur\/<\/code>, \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0447\u0435\u0440\u0435\u0437 <code>rename(2)<\/code>). \u0418\u043d\u0434\u0435\u043a\u0441 \u2014 notmuch \u043f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 Maildir\u2019\u043e\u0432. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u043c\u0438 \u044f\u0449\u0438\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0442\u0430\u043a \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u043a\u0442\u043e\u0440\u043e\u0432 \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0417\u0432\u0443\u0447\u0438\u0442 \u0431\u0435\u0437\u0443\u043c\u043d\u043e? \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041d\u043e \u0432\u043e\u0442 \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u0430\u0451\u0442:<\/p>\n<ul>\n<li>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u2014 \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u0438\u0441\u043a\u0435. \u041c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c mutt\u2019\u043e\u043c, grep\u2019\u043d\u0443\u0442\u044c, \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. Maildir \u2014 \u044d\u0442\u043e \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438 canonical event store.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438: \u0444\u0430\u0439\u043b \u043b\u0438\u0431\u043e \u0432 <code>new\/<\/code>, \u043b\u0438\u0431\u043e \u0432 <code>cur\/<\/code>, \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u043d\u0435 \u0434\u0430\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c: \u0443\u043f\u0430\u043b \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u2014 \u0444\u0430\u0439\u043b \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0432 <code>new\/<\/code>, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e\u0434\u0431\u0435\u0440\u0451\u0442.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430: \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u0430\u0439\u043b \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442 \u0432 <code>cur\/&lt;id&gt;:2,S<\/code>, \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0434\u0438\u043d <code>notmuch search '*'<\/code> \u2014 \u0438 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f. \u042d\u0442\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u00ab\u0430\u0440\u0445\u0438\u0432\u00bb. \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u201c\u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f\u201d \u0430\u0433\u0435\u043d\u0442\u0430.<\/p>\n<hr\/>\n<h3>\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u043d\u0430 Maildir\u2019\u0430\u0445<\/h3>\n<p>Threlium \u2014 IRT-tree FSM. \u0420\u0430\u0441\u0448\u0438\u0444\u0440\u0443\u044e: \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u2014 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 Maildir, \u0430 \u0433\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f In-Reply-To \u0446\u0435\u043f\u043e\u0447\u043a\u0430\u043c\u0438 \u043f\u0438\u0441\u0435\u043c. \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430 \u043d\u0435\u0442. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0430 (\u0431\u044e\u0434\u0436\u0435\u0442 \u0448\u0430\u0433\u043e\u0432, \u043f\u0440\u0430\u0432\u0430) \u0436\u0438\u0432\u0451\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u043f\u0438\u0441\u044c\u043c\u0430 \u2014 <code>X-Threlium-Hop-Budget<\/code>, <code>X-Threlium-Capabilities<\/code>.<\/p>\n<h4>\u0421\u0442\u0430\u0434\u0438\u0438 FSM<\/h4>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0438\u0445 \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0431\u0430\u0437\u0443 \u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u0443\u0434\u0443 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0435\u0435 \u0434\u0430\u043b\u0435\u0435, \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0442\u044f\u043d\u0443\u0442\u044c \u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0435.<\/p>\n<ul>\n<li>\n<p><code><strong>ingress<\/strong><\/code> \u2014 \u0435\u0434\u0438\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430. \u0421\u044e\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0432\u0441\u0435\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><code><strong>enrich<\/strong><\/code> \u2014 \u043e\u0431\u043e\u0433\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u0417\u0434\u0435\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f LightRAG (\u0433\u0440\u0430\u0444 \u0437\u043d\u0430\u043d\u0438\u0439) \u0438 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0442\u0440\u0435\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p><code><strong>reasoning<\/strong><\/code> \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435. LLM \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0440\u043e\u043c\u043f\u0442 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 tool calls.<\/p>\n<\/li>\n<li>\n<p><code><strong>egress_router<\/strong><\/code> \u2014 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440 \u0432\u044b\u0445\u043e\u0434\u0430. \u041f\u043e depth IRT-\u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0440\u0435\u0448\u0430\u0435\u0442: \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0441\u0443\u0431\u0430\u0433\u0435\u043d\u0442.<\/p>\n<\/li>\n<li>\n<p><code><strong>egress_email<\/strong><\/code>, <code><strong>egress_telegram<\/strong><\/code>, <code><strong>egress_matrix<\/strong><\/code> \u2014 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0434\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u0430\u0440\u0443\u0436\u0443.<\/p>\n<\/li>\n<li>\n<p><code><strong>cli_intent<\/strong><\/code> \u2014 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430: \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443?<\/p>\n<\/li>\n<li>\n<p><code><strong>cli_exec<\/strong><\/code> \u2014 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f shell-\u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<\/li>\n<li>\n<p><code><strong>thread_memory<\/strong><\/code>, <code><strong>global_memory<\/strong><\/code> \u2014 FSM-\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e.<\/p>\n<\/li>\n<li>\n<p><code><strong>archive<\/strong><\/code> \u2014 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0431 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435.<\/p>\n<\/li>\n<\/ul>\n<h4>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441\u0442\u0430\u0434\u0438\u0438<\/h4>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0430\u0434\u0438\u044f \u2014 Python-\u043c\u043e\u0434\u0443\u043b\u044c <code>threlium.states.&lt;stage&gt;<\/code> \u0441 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"python\">def main(msg: EmailMessage, stage: FsmStage, *, config: Config) -&gt; EmailMessage | None:<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u043e \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u043f\u0438\u0441\u044c\u043c\u043e (\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0434\u0430\u043b\u044c\u0448\u0435) \u0438\u043b\u0438 <code>None<\/code> (\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0434\u0438\u044f). \u0412\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2014 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 \u0438 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u2014 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0441\u0442\u0430\u0434\u0438\u0438. \u0421\u0442\u0430\u0434\u0438\u044f \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b, \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 systemctl, \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e fdm. \u0427\u0438\u0441\u0442\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430\u0434 stdlib <code>email.message.EmailMessage<\/code>. \u041f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<h4>\u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlleft to right directionpackage \"\u0412\u0445\u043e\u0434\" {  actor \"\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\" as User  rectangle \"bridge-email\" as EB  rectangle \"bridge-telegram\" as TB  rectangle \"bridge-matrix\" as MB  User --&gt; EB : Email  User --&gt; TB : Telegram  User --&gt; MB : Matrix}rectangle \"fdm \u2192 notmuch insert\" as FDMEB --&gt; FDM : run_fdmTB --&gt; FDM : run_fdmMB --&gt; FDM : run_fdmrectangle \"ingress\" as INGrectangle \"enrich\" as ENRrectangle \"reasoning\" as REAFDM --&gt; INGING --&gt; ENRENR --&gt; REArectangle \"egress_router\" as EGRrectangle \"cli_intent\" as CLIrectangle \"thread_memory\" as TMrectangle \"global_memory\" as GMrectangle \"subagent_intent\" as SIrectangle \"reflect\" as REFREA --&gt; EGR : \"tool: egress_router\"REA --&gt; CLI : \"tool: cli_intent\"REA --&gt; TM : \"tool: thread_memory\"REA --&gt; GM : \"tool: global_memory\"REA --&gt; SI : \"tool: subagent_intent\"REA --&gt; REF : \"tool: reflect\"rectangle \"cli_exec\" as EXECrectangle \"cli_hitl_out\" as HITLCLI --&gt; EXEC : allowCLI --&gt; ING : denyCLI --&gt; HITL : HITLHITL --&gt; EGREXEC --&gt; INGTM --&gt; INGGM --&gt; INGREF --&gt; INGSI --&gt; INGrectangle \"egress_email\" as EErectangle \"egress_telegram\" as ETrectangle \"egress_matrix\" as EMrectangle \"subagent_end\" as SErectangle \"archive\" as ARCEGR --&gt; EE : \"depth == 0\"EGR --&gt; ET : \"depth == 0\"EGR --&gt; EM : \"depth == 0\"EGR --&gt; SE : \"depth &gt; 0\"SE --&gt; INGEE --&gt; ARCET --&gt; ARCEM --&gt; ARCactor \"\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\" as UserOutEE --&gt; UserOutET --&gt; UserOutEM --&gt; UserOut@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/6ed\/bba\/0d5\/6edbba0d5b9aa9d44fd2aac06db78456.png\" alt=\"\u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/6ed\/bba\/0d5\/6edbba0d5b9aa9d44fd2aac06db78456.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/6ed\/bba\/0d5\/6edbba0d5b9aa9d44fd2aac06db78456.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM<\/figcaption><\/div>\n<\/figure>\n<hr\/>\n<h3>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f: fdm + notmuch insert<\/h3>\n<p>\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043f\u0438\u0441\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0430\u0434\u0438\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>fdm<\/code> \u2014 \u043b\u0451\u0433\u043a\u0438\u0439 mail delivery agent. \u041a\u043e\u043d\u0444\u0438\u0433 <code>~\/.fdm.conf<\/code> (\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f Ansible \u0438\u0437 Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u0430) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 <code>To:<\/code>:<\/p>\n<pre><code>match \"To\" ... action pipe \"notmuch insert --folder=stages\/reasoning\/Maildir ... &amp;&amp; threlium-dispatch.sh\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435: <code>notmuch insert<\/code> \u2014 \u044d\u0442\u043e \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0424\u0430\u0439\u043b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 Maildir <strong>\u0438<\/strong> \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 notmuch \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e <code>notmuch new<\/code> \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e insert \u0442\u0443\u0442 \u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f dispatch-\u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u043e\u0440\u043a\u0435\u0440 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>\u041f\u043e\u0447\u0442\u0443 \u0434\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438, \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0435 \u0441\u043d\u043e\u0432\u0430 \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0430\u043a\u0442\u043e\u0440\u043e\u0432. \u041d\u0430\u043c \u043d\u0435\u0442 \u043e\u0441\u0442\u0440\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0442\u0430\u043a \u043a\u0430\u043a \u0430\u0433\u0435\u043d\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0434\u0435\u0441\u044f\u0442\u043a\u0442\u0438 \u043c\u0438\u043d\u0443\u0442.<\/p>\n<hr\/>\n<h3>\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f: systemd &#8212;user<\/h3>\n<p>\u041d\u0438\u043a\u0430\u043a\u0438\u0445 Celery, RabbitMQ, Kubernetes. \u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u2014 \u044d\u0442\u043e <code>systemd --user<\/code>. \u0412\u043e\u0442 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0446\u0435\u043f\u043e\u0447\u043a\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f systemd<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumltop to bottom directionrectangle \"fdm \u2192 notmuch insert\\n--folder=stages\/\u2039stage\u203a\/Maildir\" as FDMrectangle \"threlium-dispatch.sh\\nnotmuch search tag:unread\\nAND folder:\u2039stage\u203a\/Maildir\\n\u2192 systemctl start --no-block\" as DISPrectangle \"threlium-work@\u2039stage\u203a:\u2039thread_id\u203a\\nType=exec\\npython -m threlium.runners.engine_submit %i\\n\u2192 JSON \u0432 UNIX-\u0441\u043e\u043a\u0435\u0442\" as WORKrectangle \"threlium-engine.service\\n\u0414\u043e\u043b\u0433\u043e\u0436\u0438\u0432\u0443\u0449\u0438\u0439 \u0434\u0435\u043c\u043e\u043d\\nparse_rfc822 \u2192 main() \u2192 run_fdm()\" as ENGINErectangle \"nm_settle()\\nnew\/\u2039id\u203a \u2192 cur\/\u2039id\u203a:2,S\\ntags.discard unread + to_maildir_flags\" as SETTLErectangle \"threlium-sweep@\u2039stage\u203a:\u2039thread_id\u203a\\nRace backstop\\nthrelium-dispatch.sh %i\\n\u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 backlog\" as SWEEPrectangle \"RAG-loop \u0432 engine\\nrag.ainsert + tag +lightrag_indexed\" as RAGrectangle \"JSON error \u2192 submit exit 1\\nRestart=on-failure\\n\u0431\u0435\u0437 sweep\" as ERRFDM --&gt; DISP : \"&amp;&amp; threlium-dispatch.sh\"DISP --&gt; WORKWORK --&gt; ENGINEENGINE --&gt; SETTLESETTLE --&gt; SWEEP : \"exit 0 \u2192 OnSuccess\"SWEEP ..&gt; DISP : \"\u0445\u0432\u043e\u0441\u0442 unread\"SETTLE ..&gt; RAG : \"schedule_index_pending\"ENGINE --&gt; ERR : \"exception\"@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ea4\/06b\/4ef\/ea406b4ef0eda78cbbbd10337658d6c3.png\" alt=\"\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f systemd\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/ea4\/06b\/4ef\/ea406b4ef0eda78cbbbd10337658d6c3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ea4\/06b\/4ef\/ea406b4ef0eda78cbbbd10337658d6c3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f systemd<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u043c\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 <code>threlium-work@enrich:000000000012ab.service<\/code> \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u043c\u044c\u044e\u0442\u0435\u043a\u0441. systemd \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442: \u043e\u0434\u0438\u043d \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u2014 \u043e\u0434\u0438\u043d \u0442\u0440\u0435\u0434. \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0440\u0435\u0434\u044b (\u0440\u0430\u0437\u043d\u044b\u0435 <code>thread_id<\/code>), \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u2014 \u043f\u0438\u0441\u044c\u043c\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0434\u0430 (oldest-first FIFO).<\/p>\n<p>\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e <code>flock<\/code>. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e coordinator. \u0412\u0441\u0451 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0438\u0437 systemd: \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0438 \u043f\u0440\u0438 \u0441\u0431\u043e\u044f\u0445 (<code>Restart=on-failure<\/code>), \u043b\u0438\u043c\u0438\u0442\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (<code>threlium-work.slice<\/code> \u0441 <code>TasksMax<\/code>, <code>MemoryMax<\/code>, <code>CPUQuota<\/code>), cgroup-\u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044f, \u043b\u043e\u0433\u0438 \u0447\u0435\u0440\u0435\u0437 <code>journalctl<\/code>.<\/p>\n<p>\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0432 \u0441\u043e\u0442\u044b\u0439 \u0440\u0430\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u043d\u0443\u043b\u044f \u0441 \u043a\u043e\u0441\u044f\u043a\u0430\u043c\u0438 superviser for actors \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, KISS\u2026my ass. \u041f\u0440\u0438\u0447\u0435\u043c systemd &#8212;user \u0432\u044b\u0431\u0440\u0430\u043d \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 unit, \u043e\u043d\u0438 \u0436\u0438\u0432\u0443\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0432 \u043e\u0434\u043d\u043e\u043c git \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0432\u0441\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 \u0430\u0433\u0435\u043d\u0442\u0443 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<hr\/>\n<h3>\u041c\u043d\u043e\u0433\u043e\u043a\u0430\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0445\u043e\u0434: Email, Telegram, Matrix<\/h3>\n<p>Threlium \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 \u0442\u0440\u0451\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u2014 \u044d\u0442\u043e \u043c\u043e\u0441\u0442 (<code>threlium-bridge@&lt;chan&gt;.service<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0441\u0438\u0433\u043d\u0430\u043b \u0432 \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 RFC 5322 \u043f\u0438\u0441\u044c\u043c\u043e:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u0430\u043d\u0430\u043b<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\"><code>From:<\/code><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Email<\/p>\n<\/td>\n<td>\n<p align=\"left\">IMAP IDLE (imap-tools)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>email@localhost<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Telegram<\/p>\n<\/td>\n<td>\n<p align=\"left\">Long-poll (Bot API)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>telegram@localhost<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Matrix<\/p>\n<\/td>\n<td>\n<p align=\"left\">Sync-loop (matrix-nio)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>matrix@localhost<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u0430 (<code>chat_id<\/code>, <code>room_id<\/code>, <code>update_id<\/code>, reply targets) \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>X-Threlium-Route<\/code> \u043a\u0430\u043a <code>base62(JSON)<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u043e\u0432\u043d\u043e \u0432 \u0442\u043e\u0442 \u0447\u0430\u0442\/\u043a\u043e\u043c\u043d\u0430\u0442\u0443\/\u044f\u0449\u0438\u043a, \u043e\u0442\u043a\u0443\u0434\u0430 \u043e\u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e.<\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 <code>egress_router<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043d\u0430\u043b \u043f\u043e <code>X-Threlium-Route<\/code> \u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0432 <code>egress_email<\/code>, <code>egress_telegram<\/code> \u0438\u043b\u0438 <code>egress_matrix<\/code>. \u0421\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u044f: \u0432\u0445\u043e\u0434 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: Ingress\/Egress \u043c\u043e\u0441\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlleft to right directionpackage \"Ingress-\u043c\u043e\u0441\u0442\u044b\" {  rectangle \"Email\\nIMAP IDLE\" as E  rectangle \"Telegram\\nLong-poll\" as T  rectangle \"Matrix\\nmatrix-nio sync\" as M}rectangle \"run_fdm\\n\u2192 fdm \u2192 notmuch insert\\nstages\/ingress\/Maildir\" as FDMrectangle \"FSM\\ningress \u2192 enrich \u2192 reasoning \u2192 ...\" as FSMrectangle \"egress_router\\nresolve X-Threlium-Route\\n\u2192 channel\" as EGRE --&gt; FDM : \"From: email@localhost\\nX-Threlium-Route: b62(JSON)\"T --&gt; FDM : \"From: telegram@localhost\\nX-Threlium-Route: b62(JSON)\"M --&gt; FDM : \"From: matrix@localhost\\nX-Threlium-Route: b62(JSON)\"FDM --&gt; FSMFSM --&gt; EGRpackage \"Egress\" {  rectangle \"egress_email\\nmsmtp \u2192 SMTP\" as EE  rectangle \"egress_telegram\\nBot API\" as ET  rectangle \"egress_matrix\\nClient-Server API\" as EM}EGR --&gt; EEEGR --&gt; ETEGR --&gt; EM@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a5a\/df2\/a76\/a5adf2a76e26a0350326f6bcdd1585ee.png\" alt=\"Ingress\/Egress \u043c\u043e\u0441\u0442\u044b\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/a5a\/df2\/a76\/a5adf2a76e26a0350326f6bcdd1585ee.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a5a\/df2\/a76\/a5adf2a76e26a0350326f6bcdd1585ee.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Ingress\/Egress \u043c\u043e\u0441\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432\u043d\u0435 union-\u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043d\u0435\u0442. \u041f\u0440\u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0435 \u043c\u043e\u0441\u0442 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u043a\u0443\u0440\u0441\u043e\u0440 \u0438\u0437 <code>X-Threlium-Route<\/code> \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0438\u0441\u044c\u043c\u0430 \u0447\u0435\u0440\u0435\u0437 notmuch-\u043f\u043e\u0438\u0441\u043a. \u041d\u0438\u043a\u0430\u043a\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0411\u0414 offset\u2019\u043e\u0432. \u0422\u043e\u0442 \u0436\u0435 KISS.<\/p>\n<hr\/>\n<h3>LLM: tool calls \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c<\/h3>\n<p>\u0421\u0442\u0430\u0434\u0438\u044f <code>reasoning<\/code> \u2014 \u0442\u043e\u0447\u043a\u0430 \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0430 \u0441 LLM. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>litellm<\/code> (Python SDK \u0434\u043b\u044f OpenAI-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0445 API, \u0432\u0435\u0440\u0441\u0438\u044f 1.83 \u0443\u0436\u0435 \u0431\u0435\u0437 \u0432\u0437\u043b\u043e\u043c\u043e\u0432 \ud83d\ude42 ). \u041c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442:<\/p>\n<ol>\n<li>\n<p><strong>System-\u043f\u0440\u043e\u043c\u043f\u0442<\/strong> \u0438\u0437 Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u0430 <code>reasoning\/system.j2<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>User-\u043f\u0440\u043e\u043c\u043f\u0442<\/strong> \u0441 \u043e\u0431\u043e\u0433\u0430\u0449\u0451\u043d\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438\u0437 <code>enrich<\/code> (\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0433\u0440\u0430\u0444\u0430 \u0437\u043d\u0430\u043d\u0438\u0439 + \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0442\u0440\u0435\u0434\u0430).<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043f\u0438\u0441\u043e\u043a tool_specs<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430: <code>egress_router<\/code>, <code>cli_intent<\/code>, <code>thread_memory<\/code>, <code>global_memory<\/code>, <code>subagent_intent<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <strong>tool call\u2019\u043e\u043c<\/strong>, \u0430 \u043d\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u042d\u0442\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435: LLM \u2014 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u044f, FSM \u2014 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c. \u041f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437 tool call \u2014 <code>ReasoningStageError<\/code>, \u043f\u0438\u0441\u044c\u043c\u043e \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432 <code>new\/+unread<\/code>, \u0432\u043e\u0440\u043a\u0435\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u0441 <code>exit 1<\/code>, systemd \u0434\u0435\u043b\u0430\u0435\u0442 retry. \u041f\u043e\u0437\u0436\u0435 \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0434\u0438\u0438 FSM \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c.<\/p>\n<p>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b tool call \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u044e\u0442\u0441\u044f <code>jsonschema<\/code> (JSON Schema \u0441 <code>additionalProperties: false<\/code> \u0438 <code>maxLength<\/code>-\u043b\u0438\u043c\u0438\u0442\u0430\u043c\u0438). \u041f\u0440\u043e\u0448\u043b\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u2014 \u0438\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0435 \u043f\u0438\u0441\u044c\u043c\u043e \u0441 <code>To: &lt;next_stage&gt;@localhost<\/code> \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>run_fdm<\/code> \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0430\u0434\u0438\u044e.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u2014 \u0440\u0430\u0437\u043d\u044b\u0435 JSON-Schema \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0440\u0430\u0437\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0442\u0435\u043b\u0430 \u0438 \u0442\u0435\u043c\u044b \u043f\u0438\u0441\u044c\u043c\u0430. \u0412\u0441\u0451 \u0436\u0438\u0432\u0451\u0442 \u0432 <code>prompts\/reasoning\/&lt;route&gt;\/tool_spec.j2<\/code>, <code>email_body.j2<\/code>, <code>email_subject.j2<\/code>. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043c\u043f\u0442\u044b \u0431\u0435\u0437 \u043f\u0440\u0430\u0432\u043a\u0438 Python-\u043a\u043e\u0434\u0430.<\/p>\n<hr\/>\n<h3>\u0422\u0440\u0451\u0445\u0441\u043b\u043e\u0439\u043d\u0430\u044f \u043f\u0430\u043c\u044f\u0442\u044c<\/h3>\n<p>\u0423 \u0430\u0433\u0435\u043d\u0442\u0430 \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<h4>1. \u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0440\u0435\u0434<\/h4>\n<p>\u0425\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0434\u0438\u0430\u043b\u043e\u0433\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0438\u0437 union notmuch index\u2019\u0430. \u0421\u0442\u0430\u0434\u0438\u044f <code>enrich<\/code> \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0446\u0435\u043f\u043e\u0447\u043a\u0435 <code>In-Reply-To<\/code> \u0434\u043e \u043a\u043e\u0440\u043d\u044f \u0432\u0435\u0442\u043a\u0438 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 <code>unified_messages<\/code> \u2014 \u043f\u043e\u043b\u043d\u0443\u044e \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044e.<\/p>\n<h4>2. \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u043a\u0442\u044b<\/h4>\n<p><code>global_memory<\/code> \u0438 <code>thread_memory<\/code> \u2014 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 FSM-\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. <code>reasoning<\/code> \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c tool call <code>thread_memory<\/code> \u0438\u043b\u0438 <code>global_memory<\/code>, \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0430\u043a\u0442, \u0438 \u043e\u043d \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u0432 <code>ingress<\/code> \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<h4>3. \u0413\u0440\u0430\u0444 \u0437\u043d\u0430\u043d\u0438\u0439 (LightRAG)<\/h4>\n<p>Embedded LightRAG (<code>lightrag-hku<\/code>) \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a single-writer \u0432\u043d\u0443\u0442\u0440\u0438 <code>threlium-engine<\/code>. \u041f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>nm_settle()<\/code> (\u043a\u043e\u0433\u0434\u0430 \u043f\u0438\u0441\u044c\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0438 \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u043b\u043e \u0432 <code>cur\/<\/code>) \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f <code>schedule_index_pending<\/code> \u2014 RAG-loop \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0435\u0442 settled-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0449\u0451 \u043d\u0435 \u043f\u0440\u043e\u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u044b (<code>NOT tag:unread AND NOT tag:lightrag_indexed<\/code>), \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0433\u0440\u0430\u0444 \u0447\u0435\u0440\u0435\u0437 <code>rag.ainsert()<\/code>. \u042d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e RAG, \u0430 \u0433\u0440\u0430\u0444 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u043d\u0438\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: LightRAG write\/read<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlleft to right directionpackage \"\u0417\u0430\u043f\u0438\u0441\u044c (async, \u043f\u043e\u0441\u043b\u0435 settle)\" {  rectangle \"nm_settle()\" as SETTLE  rectangle \"schedule_index_pending\" as SCHED  rectangle \"\u0421\u0435\u043b\u0435\u043a\u0442\u043e\u0440:\\nNOT tag:unread\\nAND NOT tag:lightrag_indexed\" as SEL  rectangle \"rag.ainsert(batch)\" as INS  rectangle \"+lightrag_indexed\" as TAG  SETTLE --&gt; SCHED  SCHED --&gt; SEL  SEL --&gt; INS  INS --&gt; TAG}package \"\u0427\u0442\u0435\u043d\u0438\u0435 (sync, \u0432 FSM)\" {  rectangle \"enrich\" as ENR  rectangle \"LLM: enrich_query_plan.j2\" as PLAN  rectangle \"rag.aquery(...)\" as AQ  rectangle \"Payload:\\n--- user message ---\\n--- lightrag context ---\" as PAY  rectangle \"reasoning\" as REA  ENR --&gt; PLAN  PLAN --&gt; AQ  AQ --&gt; PAY  PAY --&gt; REA}INS ..&gt; AQ : \"\u043e\u0431\u0449\u0438\u0439\\nworking_dir\/\"@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a4b\/b54\/95d\/a4bb5495d264916697034540a5c1e121.png\" alt=\"LightRAG write\/read\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/a4b\/b54\/95d\/a4bb5495d264916697034540a5c1e121.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a4b\/b54\/95d\/a4bb5495d264916697034540a5c1e121.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>LightRAG write\/read<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0442\u0430\u0434\u0438\u044f <code>enrich<\/code> \u043f\u0440\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f <code>reasoning<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>rag.aquery()<\/code> \u2014 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0433\u0440\u0430\u0444\u0443. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u0442\u0440\u0435\u0434\u0430 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u043b\u043e \u043f\u0438\u0441\u044c\u043c\u0430 \u0434\u043b\u044f <code>reasoning<\/code> \u0447\u0435\u0440\u0435\u0437 Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u044b. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043c\u043e\u0449\u044c GraphRAG \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434\u0430 \u0441\u043e\u0432\u0441\u0435\u043c \u043c\u0430\u043b\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e, \u0434\u0430\u0436\u0435 \u043d\u0435 \u0448\u0438\u0431\u043a\u043e \u0443\u043c\u043d\u044b\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043a\u0438 \u0432\u0430\u0439\u0431\u043a\u043e\u0434\u044f\u0442 \u043f\u0440\u0438 \u0442\u0430\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043c\u0430\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043b\u0435\u0433\u043a\u043e.<\/p>\n<p>\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0445 \u0446\u0435\u043f\u043e\u0447\u0435\u043a \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u2014 \u0432\u0435\u0441\u044c \u0442\u0440\u0435\u0434 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0444\u043e\u0440\u043a\u0430\u043c\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0430\u044f \u0431\u0430\u0437\u0430 \u0437\u043d\u0430\u043d\u0438\u0439 (\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430). Mutex \u043d\u0430 \u0432\u0435\u0441\u044c \u0442\u0440\u0435\u0434 \u043e\u0442 ingress \u0434\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<hr\/>\n<h3>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c: \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \/ \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \/ \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0421\u043b\u043e\u0439 CLI \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u043d\u0430 \u0441\u0442\u0440\u043e\u0433\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0438:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0421\u0442\u0430\u0434\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>reasoning<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 tool call: \u00ab\u0445\u043e\u0447\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c echo hello\u00bb<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>cli_intent<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430: allow \/ deny \/ ask-human. \u041a\u043e\u043c\u0430\u043d\u0434\u044b <strong>\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>cli_exec<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435 <code>systemd-run --scope<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>cli_intent<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0433\u0440\u0443\u0431\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440: \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438 (<code>;<\/code>, <code>|<\/code>, <code>$(<\/code>, <code>&amp;&amp;<\/code>), \u0431\u0435\u043b\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434. \u041e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u043e \u0436\u0451\u0441\u0442\u043a\u0438\u0439 \u2014 \u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u0430\u044f \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f. \u0415\u0441\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0430 \u043d\u0438 \u0432 allow, \u043d\u0438 \u0432 deny \u2014 \u0443\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043a \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0443 (HITL). \u042d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 \u0434\u0440\u0443\u0433\u0438\u0435, \u0441\u0443\u0442\u044c \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 systemd-run \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043f\u043e\u043a\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0430.<\/p>\n<h4>HITL-\u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: HITL-\u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlparticipant \"reasoning\" as Rparticipant \"cli_intent\" as CIparticipant \"cli_hitl_out\" as HOparticipant \"egress_router\" as ERactor \"\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\" as Uparticipant \"ingress\" as Iparticipant \"cli_resume\" as CRparticipant \"cli_exec\" as CER -&gt; CI : tool call: rm -rf \/tmp\/dataCI -&gt; CI : classify: \u043d\u0435 \u0432 allow, \u043d\u0435 \u0432 denyCI -&gt; HO : HITL: \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044fHO -&gt; ER : \u043f\u0438\u0441\u044c\u043c\u043e \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043cER -&gt; U : \u00ab\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c rm -rf \/tmp\/data?\u00bbU -&gt; I : \u00ab\u0414\u0430\u00bb (\u043e\u0442\u0432\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043d\u0430\u043b)I -&gt; I : IRT-\u043e\u0431\u0445\u043e\u0434 \u2192 From: cli_hitl_outI -&gt; CR : cli_resumeCR -&gt; CE : cli_exec (\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e)CE -&gt; I : observation (\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442)@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e22\/d7d\/e36\/e22d7de361332400edc0315ccd7db5d1.png\" alt=\"HITL-\u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/e22\/d7d\/e36\/e22d7de361332400edc0315ccd7db5d1.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e22\/d7d\/e36\/e22d7de361332400edc0315ccd7db5d1.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>HITL-\u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435<\/figcaption><\/div>\n<\/figure>\n<p><code>cli_exec<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0447\u0435\u0440\u0435\u0437 <code>systemd-run --scope<\/code> \u0441 \u043b\u0438\u043c\u0438\u0442\u0430\u043c\u0438 \u0438\u0437 <code>X-Threlium-Capabilities<\/code> \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0430: <code>MemoryMax<\/code>, <code>CPUQuota<\/code>, <code>TasksMax<\/code>, <code>timeout<\/code>.<\/p>\n<hr\/>\n<h3>\u0421\u0443\u0431\u0430\u0433\u0435\u043d\u0442\u044b: \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0447\u0435\u0440\u0435\u0437 IRT-\u0446\u0435\u043f\u043e\u0447\u043a\u0443<\/h3>\n<p>Threlium \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0430\u0433\u0435\u043d\u0442\u043e\u0432 (L0 \u2192 L1 \u2192 L2). \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u2014 \u043c\u0430\u0440\u043a\u0435\u0440\u044b <code>subagent_intent<\/code> \/ <code>subagent_end<\/code> \u0432 IRT-\u0434\u0435\u0440\u0435\u0432\u0435:<\/p>\n<ul>\n<li>\n<p><code>reasoning<\/code> \u043d\u0430 L0 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 tool <code>subagent_intent<\/code> \u2192 \u043c\u0430\u0440\u043a\u0435\u0440 \u0432 IRT-\u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u0441 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c hop\/cap.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0443\u0431\u0430\u0433\u0435\u043d\u0442 \u043d\u0430 L1 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u043a\u0442\u043e \u0435\u0433\u043e \u0432\u044b\u0437\u0432\u0430\u043b. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 <code>egress_router<\/code> \u043f\u043e depth &gt; 0 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u043d\u0430\u0440\u0443\u0436\u0443, \u0430 \u0432 <code>subagent_end<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>subagent_end<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>subagent_intent<\/code> \u043f\u043e IRT, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 hop\/cap \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u043e \u0432 <code>ingress<\/code>.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u0421\u0443\u0431\u0430\u0433\u0435\u043d\u0442\u044b L0\/L1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumltop to bottom directionpackage \"L0 \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0434\u0438\u0430\u043b\u043e\u0433\" {  rectangle \"reasoning L0\" as R0  rectangle \"subagent_intent\\n(\u043c\u0430\u0440\u043a\u0435\u0440 + \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 hop\/cap)\" as SI  rectangle \"ingress\" as ING1  R0 --&gt; SI : \"tool: subagent_intent\"  SI --&gt; ING1}package \"L1 \u2014 \u0441\u0443\u0431\u0430\u0433\u0435\u043d\u0442\" {  rectangle \"enrich\" as ENR1  rectangle \"reasoning L1\" as R1  rectangle \"egress_router\\ndepth=1 &gt; 0\" as EGR1  ING1 --&gt; ENR1  ENR1 --&gt; R1  R1 --&gt; EGR1 : \"tool: egress_router\"}rectangle \"subagent_end\\nIRT-\u043e\u0431\u0445\u043e\u0434 \u2192 subagent_intent\\n\u043a\u043e\u043f\u0438\u044f hop\/cap \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f\" as SErectangle \"ingress L0\" as ING0rectangle \"enrich L0\" as ENR0rectangle \"reasoning L0\\n(\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0441\u0443\u0431\u0430\u0433\u0435\u043d\u0442\u0430)\" as R0_2rectangle \"egress_router\\ndepth=0\" as EGR0rectangle \"egress_\u2039chan\u203a\\n\u2192 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\" as OUTEGR1 --&gt; SESE --&gt; ING0ING0 --&gt; ENR0ENR0 --&gt; R0_2R0_2 --&gt; EGR0 : \"tool: egress_router\"EGR0 --&gt; OUT@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/824\/475\/16a\/82447516a1cafc503a33bd47b893e6bc.png\" alt=\"\u0421\u0443\u0431\u0430\u0433\u0435\u043d\u0442\u044b L0\/L1\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/824\/475\/16a\/82447516a1cafc503a33bd47b893e6bc.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/824\/475\/16a\/82447516a1cafc503a33bd47b893e6bc.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0443\u0431\u0430\u0433\u0435\u043d\u0442\u044b L0\/L1<\/figcaption><\/div>\n<\/figure>\n<p>\u0413\u043b\u0443\u0431\u0438\u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c \u043e\u0431\u0445\u043e\u0434\u043e\u043c IRT-\u0446\u0435\u043f\u043e\u0447\u043a\u0438: \u043a\u0430\u0436\u0434\u044b\u0439 <code>subagent_intent<\/code> \u2192 depth+1, \u043a\u0430\u0436\u0434\u044b\u0439 <code>subagent_end<\/code> \u2192 depth\u22121. \u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e in-memory state \u043d\u0435\u0442. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e \u043a\u0430\u043a \u0438 \u0432\u0441\u044f \u0438\u0434\u0435\u044f subagent \u0434\u043b\u044f \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, subagent \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a \u0431\u044b \u201c\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u0432\u043e\u0430\u0442\u0435\u043b\u044f\u201d, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u044d\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0430\u0433\u0435\u043d\u0442. \u041f\u043e\u0437\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0433\u0435\u043d\u0442\u044b \u044d\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0443\u0436\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u043e, \u0441\u0434\u0435\u043b\u0430\u044e \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u0432\u0441\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u0430 \u0444\u043e\u0440\u043a\u0430\u0445 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u0434\u0430 \u0438 \u0441\u0442\u0430\u0434\u0438\u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u044f \u0432 FSM &#8212; \u044d\u0442\u043e \u0432\u0435\u0434\u044c \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u201c\u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u0447\u0442\u0435\u201d. \u041f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u043e\u0447\u0442\u043e\u0439 \u0442\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u043e\u043c\u0431 \u0432 \u0433\u0440\u0430\u0444\u0435, \u043d\u043e \u044d\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u043c\u043e \u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<hr\/>\n<h3>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b: base62 \u0438 msgspec<\/h3>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432\u0441\u0435 <code>Message-ID<\/code> \u043a\u0430\u043d\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 \u0444\u043e\u0440\u043c\u0443 <code>&lt;base62(payload)@localhost&gt;<\/code>:<\/p>\n<ul>\n<li>\n<p><strong>Email:<\/strong> <code>payload = msgspec JSON EmailNativeId(v=1, message_id=\"&lt;\u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 MID&gt;\")<\/code><\/p>\n<\/li>\n<li>\n<p><strong>Telegram\/Matrix:<\/strong> <code>payload = utf8(composite_inner)<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0445\u0435\u043c\u0430 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0430: <code>base62.decodebytes<\/code> + <code>msgspec.json.decode<\/code> \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 struct. \u041d\u0430 egress \u0434\u043b\u044f email \u2014 \u043f\u043e\u043b\u043d\u043e\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e <code>Message-ID<\/code>, <code>In-Reply-To<\/code>, <code>References<\/code> \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p><code>base62<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0430\u043b\u0444\u0430\u0432\u0438\u0442 <code>[0-9A-Za-z]<\/code> \u2014 \u0441\u0442\u0440\u043e\u0433\u043e\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e <code>atext<\/code> RFC 5322, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0439 <code>Message-ID<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0430\u043b\u0438\u0434\u0435\u043d. \u0414\u0432\u043e\u0435\u0442\u043e\u0447\u0438\u044f Matrix, \u0441\u043b\u044d\u0448\u0438 msgid, <code>$<\/code> Matrix-v3 \u2014 \u0432\u0441\u0451 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0443\u0445\u043e\u0434\u0438\u0442 \u0432 base62.<\/p>\n<p>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0447\u0435\u0440\u0435\u0437 <code>msgspec<\/code> \u2014 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f (\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e\u043b\u0435\u0439, \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432). \u041d\u0438\u043a\u0430\u043a\u0438\u0445 mapping-\u0442\u0430\u0431\u043b\u0438\u0446 \u0438 state: \u0432\u0441\u0451 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e id \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043b\u044e\u0431\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430. \u0412\u043d\u0443\u0442\u0440\u0438 \u0430\u0433\u0435\u043d\u0442 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u043f\u043e\u043a \u0441 eml \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438 \u0432\u0441\u0435.<\/p>\n<hr\/>\n<h3>\u041f\u0440\u043e\u043c\u043f\u0442\u044b: Jinja2 \u0448\u0430\u0431\u043b\u043e\u043d\u044b, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c<\/h3>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u0432\u0438\u0434\u0438\u0442 LLM \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437 Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432 <code>$THRELIUM_HOME\/prompts\/&lt;stage&gt;\/&lt;purpose&gt;.j2<\/code>. \u041a\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e <code>render_prompt(name, **vars)<\/code>. \u0428\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u0435\u043f\u043b\u043e\u044f\u0442\u0441\u044f Ansible \u0438\u0437 <code>roles\/threlium\/files\/prompts\/<\/code>.<\/p>\n<p>\u042d\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u00ab\u043e\u0431\u044b\u0447\u043d\u044b\u0445\u00bb \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u0432, \u043d\u043e \u0438:<\/p>\n<ul>\n<li>\n<p><strong>Overlay \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u0432 LightRAG<\/strong> \u2014 12 \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u043f\u0438\u0438 <code>lightrag.prompt.PROMPTS<\/code> \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 <code>lightrag-hku<\/code>.<\/p>\n<\/li>\n<li>\n<p><code><strong>addon_params<\/strong><\/code> \u0434\u043b\u044f LightRAG \u2014 language, entity_types \u2014 JSON \u0438\u0437 Jinja2.<\/p>\n<\/li>\n<li>\n<p><strong>Per-route tool-specs<\/strong> \u0434\u043b\u044f reasoning \u2014 6 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u00d7 3 \u0444\u0430\u0439\u043b\u0430 = 18 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043c\u0435\u043d\u0430 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430 \u2014 \u043f\u0440\u0430\u0432\u043a\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 <code>systemctl --user restart threlium-engine.service<\/code>. \u0411\u0435\u0437 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0432 Python. \u041d\u043e \u043c\u043e\u0436\u043d\u043e \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u043e \u043d\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u044f\u0437\u044b\u043a \u0438 \u044d\u0442\u043e \u0441\u043e\u0437\u043d\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0430\u043c \u0430\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043e\u043d \u0435\u0441\u0442 \u043c\u0430\u043b\u043e, \u0442\u043e \u043d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u043c\u0430\u0448\u0438\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0438 \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u0438\u043d \u0430\u0433\u0435\u043d\u0442 \u0434\u043e\u043b\u043e\u043c\u0430\u043b \u0441\u0435\u0431\u044f, \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c git \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0436\u0438\u0432\u0435\u0442 \u043f\u043e\u0447\u0438\u0432\u0448\u0438\u0439. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e.<\/p>\n<hr\/>\n<h3>\u0420\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435: Ansible push-\u043c\u043e\u0434\u0435\u043b\u044c<\/h3>\n<p>Threlium \u043d\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f <code>git clone<\/code>-\u043e\u043c \u043d\u0430 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0445\u043e\u0441\u0442. \u0420\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u2014 push-\u043c\u043e\u0434\u0435\u043b\u044c: <code>ansible-playbook ansible\/playbooks\/site.yml<\/code> \u0441 control node \u0437\u0430\u043b\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0451 \u043d\u0430 target.<\/p>\n<h4>\u0427\u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 target<\/h4>\n<ul>\n<li>\n<p>Python-\u043f\u0430\u043a\u0435\u0442 <code>threlium<\/code> (editable install \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 <code>.venv<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438: <code>threlium.yaml<\/code>, <code>env\/*.env<\/code>, <code>~\/.fdm.conf<\/code>, <code>~\/.msmtprc<\/code>.<\/p>\n<\/li>\n<li>\n<p>systemd-\u044e\u043d\u0438\u0442\u044b (\u0441\u0438\u043c\u043b\u0438\u043d\u043a\u0438 \u0432 <code>~\/.config\/systemd\/user\/<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043c\u043f\u0442\u044b (Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u044b).<\/p>\n<\/li>\n<li>\n<p>Dispatch-\u0441\u043a\u0440\u0438\u043f\u0442 \u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<h4>\u0416\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0445\u043e\u0441\u0442\u0430<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0434\u0435\u043f\u043b\u043e\u044f Ansible \u0441\u0432\u043e\u044e \u0440\u043e\u043b\u044c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442. \u0414\u0430\u043b\u044c\u0448\u0435 \u0445\u043e\u0441\u0442 \u0436\u0438\u0432\u0451\u0442 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e: \u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u044f\u0442\u0441\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 git \u0432 <code>threlium_repo_path<\/code>, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u0438\u043b\u0438 \u0441\u0430\u043c\u0438\u043c \u0430\u0433\u0435\u043d\u0442\u043e\u043c (\u0447\u0435\u0440\u0435\u0437 <code>cli_exec<\/code>, \u0435\u0441\u043b\u0438 capability-\u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442). \u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u043e\u043d Ansible \u2014 disaster-recovery.<\/p>\n<h4>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f LLM<\/h4>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f LLM (endpoints, \u043c\u043e\u0434\u0435\u043b\u0438, \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b) \u0436\u0438\u0432\u0451\u0442 \u0432 <code>threlium.yaml<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0445 Ansible-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0414\u0432\u0430 \u0441\u043b\u043e\u0442\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438? \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430:<\/p>\n<pre><code class=\"yaml\">llm_endpoints:  - model: \"openai\/qwen3-35b\"    api_base: \"http:\/\/vllm-host:8000\/v1\"    score: 0.0    chat_template_kwargs:      enable_thinking: false  - model: \"openai\/qwen3-35b\"    api_base: \"http:\/\/vllm-host:8000\/v1\"    score: 1.0    chat_template_kwargs:      enable_thinking: true<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u2014 \u043f\u043e <code>LitellmRoutingSite<\/code> (reasoning, enrich_plan, lightrag_llm \u0438 \u0442.\u0434.), \u043a\u0430\u0436\u0434\u044b\u0439 site \u043c\u043e\u0436\u0435\u0442 \u0435\u0445\u0430\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0439 endpoint \u0441 \u0440\u0430\u0437\u043d\u044b\u043c score. \u042d\u0442\u043e \u0432\u0441\u0435 \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u043f\u043e\u043a\u0430 \u0441\u043a\u043e\u0440\u0435\u0435 \u043a\u0430\u043a \u043a\u043e\u043d\u0446\u0435\u043f\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u043e \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0434\u043e\u0440\u043e\u0433\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0434\u0435\u043b\u0430\u0435\u0442 reasoning, \u0430 \u0434\u0435\u0448\u0435\u0432\u044b\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 GraphRAG.<\/p>\n<hr\/>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435: e2e \u0447\u0435\u0440\u0435\u0437 Docker \u0438 WireMock<\/h3>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 pytest-gate \u2014 e2e \u0432 <code>tests\/e2e\/<\/code>. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 unit-\u0442\u0435\u0441\u0442\u043e\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043d\u0438 \u0434\u043b\u044f \u0432\u0430\u0439\u0431\u043a\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b, \u0431\u044b\u043b\u043e 400 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0438, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0435\u0440\u043d\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u044d\u043c\u0435\u0440\u0434\u0436\u0435\u043d\u0442\u043d\u043e: \u0441\u0432\u044f\u0437\u043a\u0430 fdm + notmuch + systemd + FSM + LLM \u2014 \u0435\u0451 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c.<\/p>\n<h4>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumltop to bottom directionrectangle \"pytest\\n(control node)\" as PYpackage \"Docker Compose\" {  rectangle \"sut\\nUbuntu 24.04 + \u043f\u043e\u043b\u043d\u044b\u0439 site.yml\\nprivileged, cgroup host\\n\u0436\u0438\u0432\u043e\u0439 threlium-engine\" as SUT  rectangle \"greenmail\\nSMTP :3025\\nIMAP :3143\\nIMAPS :3993\" as GM  rectangle \"wiremock\\nOpenAI + Matrix mock\\nState Extension\\nhost :9080 \u2192 :8080\" as WM}PY --&gt; SUT : \"compose up\/down\"PY --&gt; SUT : \"docker exec\"PY --&gt; WM : \"Admin API\"SUT --&gt; GM : \"docker DNS: greenmail\"SUT --&gt; WM : \"docker DNS: wiremock\\nthrelium_openai_api_base\"@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/71e\/a42\/fe3\/71ea42fe340b6cf742625a3d942a1a8d.png\" alt=\"\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/71e\/a42\/fe3\/71ea42fe340b6cf742625a3d942a1a8d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/71e\/a42\/fe3\/71ea42fe340b6cf742625a3d942a1a8d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a<\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f baked-\u043e\u0431\u0440\u0430\u0437\u0430 SUT:<\/strong> \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 <code>site.yml<\/code> \u043d\u0430 \u0433\u043e\u043b\u043e\u043c Ubuntu \u2192 <code>docker commit<\/code> \u2192 <code>threlium\/e2e-sut:baked<\/code>. \u0414\u0430\u043b\u044c\u0448\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u0438\u0437 baked-\u043e\u0431\u0440\u0430\u0437\u0430.<\/p>\n<p><strong>WireMock \u0441 State Extension<\/strong> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432: \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 State \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a <code>X-Threlium-Route<\/code> \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430. \u0414\u0435\u0441\u044f\u0442\u044c xdist-\u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u0431\u044c\u044e\u0442 \u0432 \u043e\u0434\u0438\u043d SUT \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u2014 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043e \u0441\u0432\u043e\u0438\u043c notmuch-\u0442\u0440\u0435\u0434\u043e\u043c \u0438 \u0441\u0432\u043e\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0432 WireMock. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0443\u0441\u043f\u0435\u0445\u043e\u043c, \u043d\u043e \u043c\u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442.<\/p>\n<h4>L0 happy-path<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: L0 happy-path<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlleft to right directionrectangle \"SMTP inject\" as SMTPrectangle \"GreenMail\\nINBOX\" as GM1rectangle \"IMAP bridge\\n(IDLE \u2192 fetch)\" as IMAPrectangle \"ingress\" as INGrectangle \"enrich\\n(LightRAG aquery)\" as ENRrectangle \"reasoning\\n(WireMock: tool call)\" as REArectangle \"egress_router\" as EGRrectangle \"egress_email\\n(msmtp)\" as EErectangle \"GreenMail\\nINBOX pytest@\" as GM2rectangle \"pytest\\nassert In-Reply-To\" as ASSERTSMTP --&gt; GM1GM1 --&gt; IMAPIMAP --&gt; INGING --&gt; ENRENR --&gt; REAREA --&gt; EGREGR --&gt; EEEE --&gt; GM2GM2 --&gt; ASSERT@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/bfd\/114\/5c1\/bfd1145c1e0f4134af2099a754a2c03e.png\" alt=\"L0 happy-path\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/bfd\/114\/5c1\/bfd1145c1e0f4134af2099a754a2c03e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/bfd\/114\/5c1\/bfd1145c1e0f4134af2099a754a2c03e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>L0 happy-path<\/figcaption><\/div>\n<\/figure>\n<hr\/>\n<h3>\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c<\/h3>\n<ul>\n<li>\n<p><strong>\u041a\u0440\u044d\u0448 \u0441\u0442\u0430\u0434\u0438\u0438:<\/strong> \u0444\u0430\u0439\u043b \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432 <code>new\/+unread<\/code>. <code>Restart=on-failure<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u043f\u043e\u043f\u044b\u0442\u043a\u0443. Sweep (\u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0445\u0430) \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 backlog.<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0440\u044d\u0448 \u043c\u0435\u0436\u0434\u0443 <\/strong><code><strong>rename(2)<\/strong><\/code><strong> \u0438 Xapian-commit:<\/strong> \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u0432 <code>cur\/<\/code>, \u043d\u043e notmuch \u0434\u0443\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d \u0432 <code>new\/<\/code>. <code>settle_recovery_for_stage()<\/code> \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u043b\u0435\u0447\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 <code>from_maildir_flags()<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0440\u044d\u0448 \u043c\u043e\u0441\u0442\u0430:<\/strong> <code>sys.exit(1)<\/code> + <code>Restart=on-failure<\/code>. \u041a\u0443\u0440\u0441\u043e\u0440 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 notmuch.<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0440\u044d\u0448 \u0434\u0432\u0438\u0436\u043a\u0430:<\/strong> \u0432\u0441\u0435 submit\u2019\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 <code>BindsTo<\/code> \u043d\u0430 <code>threlium-engine.service<\/code>. \u041f\u0440\u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0435 \u0434\u0432\u0438\u0436\u043a\u0430 \u0432\u043e\u0440\u043a\u0435\u0440\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>LightRAG drain \u043f\u0440\u0435\u0440\u0432\u0430\u043b\u0441\u044f:<\/strong> \u0442\u0435\u0433 <code>+lightrag_indexed<\/code> \u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u2192 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 drain \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442 <code>ainsert<\/code>. LightRAG dedup \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 <code>errors\/<\/code> \u0438 error-mail \u043d\u0435\u0442. \u0421\u0431\u043e\u0438 \u2014 structured log \u0432 journald \u0438 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0439 exit code. \u041f\u0440\u043e\u0441\u0442\u043e \u0438 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e, \u0430 \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u201c\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f\u201d \u0432\u0438\u0434\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u043f\u043e\u0447\u0442\u0435.<\/p>\n<hr\/>\n<h3>\u0410\u0434\u043c\u0438\u043d\u043a\u0430: Cockpit + Caddy + Roundcube + Dovecot<\/h3>\n<p>\u0420\u0430\u0437 \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u2014 \u043f\u0438\u0441\u044c\u043c\u043e, \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0443 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u00ab\u043c\u044b\u0441\u043b\u0438\u00bb \u0430\u0433\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430 target \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0435\u043a \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u0430\u0434\u043c\u0438\u043d-\u043f\u0430\u043d\u0435\u043b\u044c.<\/p>\n<h4>Dovecot: IMAP \u043f\u043e\u0432\u0435\u0440\u0445 Maildir\u2019\u043e\u0432 \u0441\u0442\u0430\u0434\u0438\u0439<\/h4>\n<p>Dovecot \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a \u0442\u0435\u043c \u0436\u0435 Maildir\u2019\u0430\u043c, \u0447\u0442\u043e \u0438 FSM. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 \u2014 drop-in <code>99-threlium-webmail.conf<\/code>:<\/p>\n<pre><code>namespace inbox {  inbox = yes  location = maildir:$THRELIUM_HOME\/stages:LAYOUT=fs:DIRNAME=Maildir}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0430\u0434\u0438\u044f FSM (<code>ingress<\/code>, <code>enrich<\/code>, <code>reasoning<\/code>, \u2026) \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f IMAP-\u043f\u0430\u043f\u043a\u043e\u0439. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d virtual namespace \u2014 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u00abAll\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u0430 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u0434\u0438\u0439 \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u043b\u0435\u043d\u0442\u0443. \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u2014 \u0447\u0435\u0440\u0435\u0437 PAM (\u0442\u043e\u0442 \u0436\u0435 POSIX-\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0447\u0442\u043e \u0438 \u0430\u0433\u0435\u043d\u0442).<\/p>\n<p>ACL \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0440\u0435\u0436\u0438\u043c read-only: <code>lr<\/code> (list + read) \u2014 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c, \u043d\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u0444\u043b\u0430\u0433\u0438, \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0442\u044c, \u043d\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c. Maildir \u043f\u0438\u0448\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e Threlium \u0438 notmuch, Dovecot \u2014 \u0447\u0438\u0441\u0442\u043e \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435.<\/p>\n<h4>Roundcube: \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430<\/h4>\n<p>Roundcube \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 Dovecot (localhost:143, plaintext \u2014 \u0432\u0441\u0451 \u043d\u0430 loopback). SMTP \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u2014 \u044d\u0442\u043e read-only \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d:<\/p>\n<ul>\n<li>\n<p>\u0420\u0435\u0436\u0438\u043c <code>threads<\/code> \u0441 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u043f\u043e \u0434\u0430\u0442\u0435 \u2014 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439 \u0432\u0438\u0434\u043d\u044b \u043a\u0430\u043a \u043d\u0438\u0442\u0438 \u043f\u0438\u0441\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 <code>Virtual\/All<\/code> \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043a\u0430\u043a \u0430\u0440\u0445\u0438\u0432 \u0438 \u0432 <code>default_folders<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>mail_read_time = -1<\/code> \u2014 Roundcube \u043d\u0435 \u0441\u0442\u0430\u0432\u0438\u0442 \u0444\u043b\u0430\u0433 \u00ab\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e\u00bb \u043f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 (\u0432 \u043f\u0430\u0440\u0435 \u0441 ACL Dovecot).<\/p>\n<\/li>\n<li>\n<p>SQLite \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0439 \u2014 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e MySQL\/PostgreSQL.<\/p>\n<\/li>\n<\/ul>\n<h4>Caddy: \u0435\u0434\u0438\u043d\u044b\u0439 edge-proxy<\/h4>\n<p>Caddy \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044f Cockpit \u0438 Roundcube \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443:<\/p>\n<pre><code>:8080 {    handle_path \/webmail\/* {        root * \/usr\/share\/roundcube        php_fastcgi unix\/\/run\/php\/php-fpm.sock        file_server    }    route * {        reverse_proxy 127.0.0.1:9090 {            transport http { tls_insecure_skip_verify }        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f: <code>\/webmail\/*<\/code> \u2192 Roundcube \u0447\u0435\u0440\u0435\u0437 PHP-FPM, \u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2192 Cockpit \u043d\u0430 <code>:9090<\/code>. TLS \u2014 <code>tls internal<\/code> (self-signed) \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430, \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u0432 e2e. \u041f\u043e\u0440\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>threlium_mail_archive_caddy_bind_port<\/code>.<\/p>\n<h4>Cockpit: \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0430\u044f \u0430\u0434\u043c\u0438\u043d-\u043f\u0430\u043d\u0435\u043b\u044c \u0441 Roundcube \u0432\u043d\u0443\u0442\u0440\u0438<\/h4>\n<p>Cockpit \u0434\u0430\u0451\u0442 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438: \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 journald-\u043b\u043e\u0433\u043e\u0432 (\u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0432\u0441\u0435\u0445 \u043b\u043e\u0433\u043e\u0432 \u0430\u0433\u0435\u043d\u0442\u0430), \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 systemd-\u044e\u043d\u0438\u0442\u0430\u043c\u0438 (\u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0434\u0438\u0438, \u043c\u043e\u0441\u0442\u044b, engine), \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 (\u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <code>cockpit-files<\/code> \u0438\u0437 backports).<\/p>\n<p>\u0412 Cockpit \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 <code>threlium-mail-archive<\/code> \u2014 \u044d\u0442\u043e <code>manifest.json<\/code> + <code>index.html<\/code> \u0441 iframe \u043d\u0430 <code>\/webmail\/<\/code>. \u0412 \u0438\u0442\u043e\u0433\u0435 Roundcube \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0432\u043a\u043b\u0430\u0434\u043a\u0430 \u0432 Cockpit. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u0442 \u0432 \u043e\u0434\u043d\u043e\u043c \u043e\u043a\u043d\u0435: \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043b\u043e\u0433\u0438, \u044e\u043d\u0438\u0442\u044b \u0438 \u043f\u043e\u043b\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0443 \u0430\u0433\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0432\u0441\u0435 \u0432\u043e\u0432\u0441\u0435 \u0431\u0435\u0437 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u044b, \u043e\u043d\u043e \u0435\u0449\u0435 \u0438 \u043d\u0435 \u0435\u0441\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u043e\u0447\u0442\u0438.<\/p>\n<p>Cockpit \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 <code>127.0.0.1:9090<\/code> \u2014 \u043d\u0430\u0440\u0443\u0436\u0443 \u043d\u0435 \u0442\u043e\u0440\u0447\u0438\u0442. Origin-\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 (\u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 CSWSH) \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>threlium_mail_archive_cockpit_origins_extra<\/code> \u0432 host_vars. \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 oneshot-\u044e\u043d\u0438\u0442 <code>threlium-cockpit-tls-clean.service<\/code> \u0447\u0438\u0441\u0442\u0438\u0442 <code>\/run\/cockpit\/tls<\/code> \u043f\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043e\u043c Cockpit \u2014 workaround \u0434\u043b\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0431\u0430\u0433\u0430 \u0441 <code>cockpit-certificate-ensure<\/code>.<\/p>\n<h4>\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043c\u0435\u0441\u0442\u0435<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u0410\u0434\u043c\u0438\u043d\u043a\u0430: \u0441\u0442\u0435\u043a Cockpit\/Caddy\/Roundcube\/Dovecot<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumlleft to right directionactor \"\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\" as OPpackage \"Target host\" {  package \"Caddy :8080\" as CADDY {    rectangle \"\/webmail\/*\" as WM    rectangle \"\/* (\u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435)\" as ROOT  }  rectangle \"Roundcube\\nPHP-FPM\" as RC  rectangle \"Cockpit :9090\\n(loopback only)\" as CP  rectangle \"Dovecot :143\\n(loopback, PAM)\" as DOV  WM --&gt; RC  ROOT --&gt; CP  RC --&gt; DOV : \"IMAP localhost:143\"  package \"$THRELIUM_HOME\/stages\/\" {    rectangle \"ingress\/Maildir\" as MD1    rectangle \"enrich\/Maildir\" as MD2    rectangle \"reasoning\/Maildir\" as MD3    rectangle \"\u2026\/Maildir\" as MDN  }  DOV --&gt; MD1 : \"read-only\\nACL: lr\"  rectangle \"Cockpit package\\nthrelium-mail-archive\\niframe \u2192 \/webmail\/\" as PKG  CP -- PKG  PKG ..&gt; WM : \"iframe src\"}OP --&gt; CADDY : \"\u0431\u0440\u0430\u0443\u0437\u0435\u0440\"@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/be2\/fbd\/7f7\/be2fbd7f764acbc437665d1da7e3ac80.png\" alt=\"\u0410\u0434\u043c\u0438\u043d\u043a\u0430: \u0441\u0442\u0435\u043a Cockpit\/Caddy\/Roundcube\/Dovecot\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/be2\/fbd\/7f7\/be2fbd7f764acbc437665d1da7e3ac80.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/be2\/fbd\/7f7\/be2fbd7f764acbc437665d1da7e3ac80.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0410\u0434\u043c\u0438\u043d\u043a\u0430: \u0441\u0442\u0435\u043a Cockpit\/Caddy\/Roundcube\/Dovecot<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0435\u0441\u044c \u0441\u0442\u0435\u043a \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>threlium_mail_archive_web_enabled: true<\/code> (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043a\u043b\u044e\u0447\u0451\u043d) \u0438 \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u043b\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 (<code>--tags deploy<\/code>). \u041f\u0440\u0438 <code>--tags refresh<\/code> \u0432\u0435\u0431-\u0441\u0442\u0435\u043a \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442\u0441\u044f.<\/p>\n<hr\/>\n<h3>Ansible playbook: \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438 \u0440\u0435\u0436\u0438\u043c\u044b \u0440\u0430\u0431\u043e\u0442\u044b<\/h3>\n<p>\u042f \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b push-\u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0441\u0430\u043c\u043e\u043c \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0435 \u2014 \u043e\u043d \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u043e \u043d\u0435\u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 Ansible-\u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<h4>\u041e\u0434\u0438\u043d \u043f\u043b\u0435\u0439\u0431\u0443\u043a, \u043e\u0434\u043d\u0430 \u0440\u043e\u043b\u044c<\/h4>\n<p>\u0412\u0435\u0441\u044c \u0434\u0435\u043f\u043b\u043e\u0439 \u2014 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>ansible\/playbooks\/site.yml<\/code>. \u0417\u0430\u0434\u0430\u0447\u0438 \u0436\u0438\u0432\u0443\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 \u043d\u0451\u043c, \u0430 \u043d\u0435 \u0432 <code>roles\/threlium\/tasks\/<\/code>. \u041f\u043e\u0447\u0435\u043c\u0443? \u0424\u0430\u0439\u043b \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439, \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0432 \u0440\u043e\u043b\u044c \u0434\u0430\u043b \u0431\u044b <code>include_role<\/code> \u0441 \u0442\u0435\u043c \u0436\u0435 \u0447\u0438\u0441\u043b\u043e\u043c \u0441\u0442\u0440\u043e\u043a \u0438 \u0441\u043b\u043e\u043c\u0430\u043b \u0431\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0443\u0442\u0438. \u0420\u043e\u043b\u044c <code>threlium<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432, \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043e\u0432.<\/p>\n<pre><code>ansible\/  playbooks\/    site.yml                    # \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439    tasks\/      refresh.yml               # \u0443\u0437\u043a\u0438\u0439 \u0442\u0435\u0433: \u0447\u0438\u0441\u0442\u043a\u0430 + \u0440\u0435\u0441\u0442\u0430\u0440\u0442      mail_archive_web.yml      # \u0432\u0435\u0431-\u0441\u0442\u0435\u043a (Cockpit\/Caddy\/\u2026)      mail_archive_web_acceptance.yml      ssh_hardening.yml  roles\/threlium\/    defaults\/main.yml           # \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435    vars\/main.yml               # \u043a\u0430\u043d\u043e\u043d FSM-\u0441\u0442\u0430\u0434\u0438\u0439    files\/      scripts\/                  # Python-\u043a\u043e\u0434 FSM + bash-\u0441\u043a\u0440\u0438\u043f\u0442\u044b      prompts\/                  # Jinja2-\u043f\u0440\u043e\u043c\u043f\u0442\u044b \u0434\u043b\u044f LLM      mail-archive\/             # \u0441\u0442\u0430\u0442\u0438\u043a\u0430: dovecot-virtual    templates\/      config\/                   # fdm.conf, msmtprc, threlium.yaml      systemd\/user\/             # \u0448\u0430\u0431\u043b\u043e\u043d\u044b unit-\u0444\u0430\u0439\u043b\u043e\u0432      mail-archive\/             # Caddyfile, cockpit.conf, \u2026      env\/threlium.env.j2      pyproject.toml.j2  host_vars\/                    # per-host: LLM endpoints, \u0441\u0435\u043a\u0440\u0435\u0442\u044b  group_vars\/                   # \u043e\u0431\u0449\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 e2e-\u043e\u0432\u0435\u0440\u0440\u0430\u0439\u0434\u044b  inventory\/                    # hosts (\u043f\u0440\u043e\u0434 \u0438 e2e)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0424\u0430\u0437\u044b \u0434\u0435\u043f\u043b\u043e\u044f<\/h4>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0444\u0430\u0437\u0430 \u2014 \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">#<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0424\u0430\u0437\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">Assert<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0433\u043e\u043d <strong>\u0434\u043e<\/strong> \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u044b\u0445 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">Bootstrap \u041e\u0421<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>apt<\/code>: fdm, msmtp, notmuch, python3, python3-venv<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0442\u0430\u043b\u043e\u0433 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>threlium_repo_path\/<\/code> + \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u0439 <code>git init<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0430 <code>$THRELIUM_HOME<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0442\u0430\u0434\u0438\u0439\u043d\u044b\u0435 Maildir\u2019\u044b \u0438\u0437 <code>vars\/main.yml<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">5<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u0434 FSM<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>copy<\/code> Python-\u043f\u0430\u043a\u0435\u0442\u0430 + dispatch-\u0441\u043a\u0440\u0438\u043f\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">6<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043d\u0444\u0438\u0433\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>template<\/code>: fdm.conf, msmtprc, threlium.yaml, threlium.env<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">7<\/p>\n<\/td>\n<td>\n<p align=\"left\">Unit-\u0444\u0430\u0439\u043b\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0428\u0430\u0431\u043b\u043e\u043d\u044b systemd: engine, work@, sweep@, bridge@<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">8<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0438\u043c\u043b\u0438\u043d\u043a\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>~\/.fdm.conf<\/code>, <code>~\/.msmtprc<\/code>, \u0432\u0441\u0435 \u044e\u043d\u0438\u0442\u044b \u0432 <code>~\/.config\/systemd\/user\/<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">9<\/p>\n<\/td>\n<td>\n<p align=\"left\">Venv + pip<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>pyproject.toml.j2<\/code> \u2192 target, <code>pip install .<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10<\/p>\n<\/td>\n<td>\n<p align=\"left\">linger + start<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>loginctl enable-linger<\/code> + <code>daemon-reload<\/code> + <code>state: started<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">11<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0435\u0431-\u0441\u0442\u0435\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">Cockpit + Caddy + Roundcube + Dovecot (\u0435\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">12<\/p>\n<\/td>\n<td>\n<p align=\"left\">Acceptance<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043a\u0432\u043e\u0437\u043d\u0430\u044f \u0441\u0430\u043c\u043e\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430: Maildir\u2019\u044b, \u044e\u043d\u0438\u0442\u044b, notmuch, fdm.conf, Python<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">13<\/p>\n<\/td>\n<td>\n<p align=\"left\">Bundle<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>tar.gz<\/code> \u0441\u043d\u0438\u043c\u043e\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u2192 fetch \u043d\u0430 control node<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h4>\u0414\u0432\u0430 \u0437\u0430\u043a\u043e\u043d\u0430 \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438<\/h4>\n<p>\u041f\u043b\u0435\u0439\u0431\u0443\u043a \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442 \u0434\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/p>\n<p><strong>\u041a\u043b\u0430\u0441\u0441 A \u2014 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/strong> (apt, pip): <code>state: present<\/code> \u2014 \u00abinstall if missing\u00bb. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c Ansible. \u041d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435.<\/p>\n<p><strong>\u041a\u043b\u0430\u0441\u0441 B \u2014 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b Threlium<\/strong> (\u043a\u043e\u0434, \u043a\u043e\u043d\u0444\u0438\u0433\u0438, \u044e\u043d\u0438\u0442\u044b, \u0441\u0438\u043c\u043b\u0438\u043d\u043a\u0438): <strong>\u043f\u0435\u0440\u0435\u0442\u0438\u0440\u0430\u043d\u0438\u0435<\/strong> \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u043e\u0433\u043e\u043d. \u0424\u0430\u0439\u043b \u043d\u0430 target \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u0440\u0435\u043f\u043e \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0438. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 <code>creates:<\/code> \u0438\u043b\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u2014 \u0447\u0435\u0440\u0435\u0437 baked-\u043e\u0431\u0440\u0430\u0437 \u043e\u043d\u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0437\u0430\u0448\u0438\u0442\u044b\u0439 T\u2080.<\/p>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 B: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 <code>.git<\/code> (\u043d\u0435 \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430) \u0438 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0430 durable Maildir\u2019\u043e\u0432 (\u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c event store \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438).<\/p>\n<h4>\u0414\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430: deploy \u0438 refresh<\/h4>\n<details class=\"spoiler\">\n<summary>PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: Deploy vs Refresh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>@startumltop to bottom directionpackage \"--tags deploy (\u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u043e\u043d)\" {  rectangle \"apt: fdm, notmuch,\\npython3, cockpit, caddy\u2026\" as D1  rectangle \"\u041a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 + Maildir'\u044b\" as D2  rectangle \"copy: Python-\u043a\u043e\u0434 FSM\" as D3  rectangle \"template: \u043a\u043e\u043d\u0444\u0438\u0433\u0438,\\nunit-\u0444\u0430\u0439\u043b\u044b, env\" as D4  rectangle \"pip install + venv\" as D5  rectangle \"\u0412\u0435\u0431-\u0441\u0442\u0435\u043a\\n(Cockpit\/Caddy\/\u2026)\" as D6  rectangle \"Acceptance\" as D7  rectangle \"Bundle\" as D8  D1 --&gt; D2  D2 --&gt; D3  D3 --&gt; D4  D4 --&gt; D5  D5 --&gt; D6  D6 --&gt; D7  D7 --&gt; D8}package \"--tags refresh (\u0443\u0437\u043a\u0438\u0439 \u043f\u0440\u043e\u0433\u043e\u043d)\" {  rectangle \"\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 engine + \u043c\u043e\u0441\u0442\u043e\u0432\" as R1  rectangle \"\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f:\\nscripts\/, env,\\n\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432\/\u044e\u043d\u0438\u0442\u043e\u0432\" as R2  rectangle \"daemon-reload\" as R3  rectangle \"\u0427\u0438\u0441\u0442\u043a\u0430 Maildir\/notmuch\/\\nLightRAG\" as R4  rectangle \"\u0420\u0435\u0441\u0442\u0430\u0440\u0442 user-units\" as R5  R1 --&gt; R2  R2 --&gt; R3  R3 --&gt; R4  R4 --&gt; R5}@enduml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/b23\/911\/c60\/b23911c603e9a00e751cd3d7ae5ce553.png\" alt=\"Deploy vs Refresh\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/b23\/911\/c60\/b23911c603e9a00e751cd3d7ae5ce553.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/b23\/911\/c60\/b23911c603e9a00e751cd3d7ae5ce553.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Deploy vs Refresh<\/figcaption><\/div>\n<\/figure>\n<p><strong>deploy<\/strong> \u2014 \u043f\u043e\u043b\u043d\u044b\u0439 bootstrap: apt, venv, pip, \u0432\u0435\u0431-\u0441\u0442\u0435\u043a, acceptance, bundle. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0445\u043e\u0441\u0442\u0430 \u0438\u043b\u0438 disaster-recovery.<\/p>\n<p><strong>refresh<\/strong> \u2014 \u0443\u0437\u043a\u0438\u0439 \u043f\u0440\u043e\u0433\u043e\u043d: \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0441 control node + \u0441\u0431\u0440\u043e\u0441 Maildir\/notmuch\/LightRAG + \u0440\u0435\u0441\u0442\u0430\u0440\u0442 user-units. <strong>\u0411\u0435\u0437<\/strong> apt, <strong>\u0431\u0435\u0437<\/strong> pip, <strong>\u0431\u0435\u0437<\/strong> \u0432\u0435\u0431-\u0441\u0442\u0435\u043a\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0435\u0436\u0438\u043c \u0434\u043b\u044f e2e-\u0442\u0435\u0441\u0442\u043e\u0432: baked-\u043e\u0431\u0440\u0430\u0437 SUT \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, refresh \u043d\u0430\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e.<\/p>\n<p>\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0442\u0435\u0433\u043e\u0432 \u2014 \u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u043e\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\"><code>--tags refresh<\/code><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>deploy<\/code> \u0442\u043e\u043b\u044c\u043a\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>deploy<\/code> + <code>refresh<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>never<\/code> + <code>refresh<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u043d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0434\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h4>\u041f\u043e\u0441\u043b\u0435 bootstrap: \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u0430\u044f \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044f<\/h4>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0445 Ansible-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432: <strong>\u043f\u043b\u0435\u0439\u0431\u0443\u043a \u2014 \u043d\u0435 governor \u0445\u043e\u0441\u0442\u0430<\/strong>. \u041f\u043e\u0441\u043b\u0435 bootstrap \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 <code>git<\/code> \u0432 <code>threlium_repo_path<\/code>.<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440<\/strong> \u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\/\u043a\u043e\u043d\u0444\u0438\u0433 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 target \u2192 <code>daemon-reload<\/code> \u2192 <code>git commit<\/code>. \u0421\u0438\u043c\u043b\u0438\u043d\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u044f\u0442 \u043d\u043e\u0432\u043e\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>\u0410\u0433\u0435\u043d\u0442<\/strong> \u2014 \u0447\u0435\u0440\u0435\u0437 <code>cli_exec<\/code> \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 capability-\u043f\u0440\u043e\u0444\u0438\u043b\u044f. \u041c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u043e\u043c\u043f\u0442\u044b, \u043a\u043e\u043d\u0444\u0438\u0433\u0438, \u0434\u0430\u0436\u0435 Python-\u043a\u043e\u0434, \u043a\u043e\u043c\u043c\u0438\u0442\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 git.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438<\/strong> target \u2192 control \u043d\u0435\u0442 \u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f. \u041a\u0430\u0436\u0434\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043f\u043e\u043b\u043d\u044b\u0439 <code>ansible-playbook site.yml<\/code> \u043d\u0430 \u0436\u0438\u0432\u043e\u043c \u0445\u043e\u0441\u0442\u0435 \u2014 <strong>\u0442\u043e\u043b\u044c\u043a\u043e disaster-recovery<\/strong>. \u041e\u043d \u043f\u0435\u0440\u0435\u0442\u0440\u0451\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u044b. \u0414\u043b\u044f \u0448\u0442\u0430\u0442\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u2014 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u043a\u0438 \u0438\u043b\u0438 refresh.<\/p>\n<h4>\u041a\u0430\u043d\u043e\u043d \u0441\u0442\u0430\u0434\u0438\u0439 \u2014 \u043e\u0434\u043d\u0430 \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u0430\u0432\u0434\u044b<\/h4>\n<p>\u0412\u0441\u0435 FSM-\u0441\u0442\u0430\u0434\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435: <code>roles\/threlium\/vars\/main.yml<\/code> (<code>threlium_fsm_mailbox_stages<\/code>). \u0412\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0430 \u2014 \u0446\u0438\u043a\u043b\u044b \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443. \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0434\u0438\u044e = \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u0447\u043a\u0443. \u0420\u0430\u0441\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0436\u0434\u0443 Maildir\u2019\u0430\u043c\u0438, fdm.conf \u0438 systemd-\u044e\u043d\u0438\u0442\u0430\u043c\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u043f\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438.<\/p>\n<hr\/>\n<h3>\u0427\u0442\u043e \u0438\u043c\u0435\u0435\u043c \u0432 \u0438\u0442\u043e\u0433\u0435<\/h3>\n<p>Threlium \u2014 \u0441\u0430\u043c\u043e\u0445\u043e\u0441\u0442\u043d\u044b\u0439 AI-\u0430\u0433\u0435\u043d\u0442, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 Unix-\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">Maildir (\u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0434\u0438\u0441\u043a\u0435)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043d\u0434\u0435\u043a\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">notmuch (Xapian)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0447\u0435\u0440\u0435\u0434\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">Maildir <code>new\/<\/code> \u2192 <code>cur\/<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">systemd &#8212;user<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">fdm (<code>~\/.fdm.conf<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0420\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">litellm + tool calls<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0430\u043c\u044f\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">LightRAG (NanoVectorDB + NetworkX)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u0430\u043d\u0430\u043b\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">IMAP IDLE, Telegram Bot API, Matrix (nio)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u043c\u043f\u0442\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">Jinja2 \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0420\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">Ansible push-\u043c\u043e\u0434\u0435\u043b\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">pydantic-settings + YAML (<code>threlium.yaml<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">pytest e2e + Docker + WireMock + GreenMail<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c CLI<\/p>\n<\/td>\n<td>\n<p align=\"left\">cli_intent (\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430) \u2192 cli_exec (\u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u2014 \u043e\u0434\u0438\u043d Python-\u043f\u0430\u043a\u0435\u0442 \u0441 \u0435\u0434\u0438\u043d\u044b\u043c venv, \u043e\u0434\u0438\u043d <code>systemd --user<\/code> manager, \u043e\u0434\u0438\u043d notmuch union-\u0438\u043d\u0434\u0435\u043a\u0441. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 Docker-compose\u2019\u043e\u0432 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432. \u0424\u0430\u0439\u043b\u044b \u043d\u0430 \u0434\u0438\u0441\u043a\u0435, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0432 systemd, \u043f\u0440\u043e\u043c\u043f\u0442\u044b \u0432 Jinja2.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u0438 \u044d\u0442\u043e? \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u042f \u043f\u0438\u0448\u0443 \u0430\u0433\u0435\u043d\u0442\u0443 \u043f\u0438\u0441\u044c\u043c\u043e \u2014 \u043e\u043d \u0434\u0443\u043c\u0430\u0435\u0442, \u043e\u0431\u043e\u0433\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438\u0437 \u0433\u0440\u0430\u0444\u0430 \u0437\u043d\u0430\u043d\u0438\u0439, \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0435\u0442, \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b (\u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0438\u043b\u0438 \u0431\u0435\u0437), \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442. Telegram \u0438 Matrix \u2014 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b \ud83d\ude42 \u0412\u0441\u0435 \u043a\u0430\u043d\u0430\u043b\u044b \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u044b, \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u0435\u0447\u043d\u043e, \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u0435\u043d.<\/p>\n<p><em>P.S. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e LLM \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0430\u0446\u0438\u0439 \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u0435\u0431\u0430\u0436\u0438\u0448\u044c, \u043f\u043e\u0447\u0435\u043c\u0443 notmuch insert \u043f\u043e\u0432\u0435\u0441\u0438\u043b <\/em><code><em>+unread<\/em><\/code><em>, \u0430 dispatch-\u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u043f\u043e\u0434\u043d\u044f\u043b \u0432\u043e\u0440\u043a\u0435\u0440. \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u2014 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0430 \u0432 <\/em><code><em>folder:<\/em><\/code><em> \u0442\u0435\u0440\u043c\u0438\u043d\u0435. \u042d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u0430 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0430\u0433\u0435\u043d\u0442\u0430\u043c\u0438! \ud83d\ude42<\/em><\/p>\n<p>\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d <a href=\"https:\/\/github.com\/3DRaven\/threlium\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a><\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1039286\/\">https:\/\/habr.com\/ru\/articles\/1039286\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u044f \u0441\u0442\u0440\u043e\u0438\u043b \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u043e\u0431\u043b\u0430\u043a\u043e \u043d\u0430 Proxmox. \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0436\u0438\u0432\u0451\u0442 \u043a\u043e\u0435-\u0447\u0442\u043e \u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u2014 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439 AI-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u043c\u043e\u0433\u0443 \u043f\u043d\u0443\u0442\u044c \u043f\u0438\u0441\u044c\u043c\u043e\u043c \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0432 Telegram, \u0438 \u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u0442, \u043f\u043e\u0434\u0443\u043c\u0430\u0432. \u041f\u0440\u0438\u0447\u0451\u043c \u043f\u043e\u0434\u0443\u043c\u0430\u0432 \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443: \u0441 \u043c\u043d\u043e\u0433\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435\u043c, \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u0417\u043e\u0432\u0443\u0442 \u0435\u0433\u043e Threlium, \u0438 \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043e\u043d \u0447\u0435\u0440\u0442\u043e\u0432\u0441\u043a\u0438 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c \u0441\u0435\u0431\u044f.\u0417\u0430\u0447\u0435\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0438 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u2014 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043d\u0438\u0436\u0435.\u0417\u0430\u0447\u0435\u043c \u0441\u0432\u043e\u0439 \u0430\u0433\u0435\u043d\u0442\u0412\u0441\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 LLM-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u044b \u2014 \u0447\u0443\u0436\u0438\u0435. \u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430, \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043e\u0434\u043d\u0438\u043c \u043e\u043a\u043d\u043e\u043c \u0447\u0430\u0442\u0430, \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u0442, \u0435\u0441\u0442\u044c \u0447\u0430\u0442-\u0441\u0435\u0441\u0441\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443\u043c\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u0436\u0435 \u0431\u0435\u0433\u0430\u044e\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u0441\u0440\u0435\u0434\u043d\u0435\u043d\u044c\u043a\u043e\u043c GPU: Qwen, Llama, Mistral. \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0436\u0438\u0442\u044c \u043d\u0430 \u043c\u043e\u0451\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043c\u043e\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0446\u0438\u043a\u043b \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439 \u2014 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0441\u043f\u0440\u043e\u0441\u0438\u043b \u2192 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u00bb, \u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u0441 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438, \u043f\u0430\u043c\u044f\u0442\u044c\u044e \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u041f\u0440\u0438\u0447\u0435\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0431\u044b \u043a\u043e\u0434\u0430 \u0432 \u043d\u0435\u043c \u0431\u044b\u043b\u043e, \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0430\u043d\u0430\u043b\u043e\u0433\u0430\u043c\u0438 \u0438 \u043e\u043d \u043c\u043e\u0433 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0430\u043c \u0441\u0435\u0431\u044f \u0438\u043b\u0438 \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.\u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e. \u041f\u0440\u0438\u0447\u0451\u043c \u0438\u0437 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 Unix-\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u043e\u0432.\u0427\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0438\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0445\u043e\u0434\u041c\u0430\u043b\u043e \u043a\u043e\u0434\u0430, \u0435\u0441\u043b\u0438 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u043a\u043b\u0435\u0435\u043a\u043e\u0434 \u0438 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044e (\u043c\u043e\u0434\u0443\u043b\u044c types), \u0442\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 6\u043a \u0441\u0442\u0440\u043e\u043a \u043f\u0430\u0439\u0442\u043e\u043d \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0423 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u043e \u0436\u0435 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0442\u043d\u044f\u043c\u0438 \u0442\u044b\u0441\u044f\u0447 \u0441\u0442\u0440\u043e\u043a.\u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0435\u0441\u0442\u044c, \u0432\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0430\u0433\u0435\u043d\u0442\u0430 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u0430 \u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.\u041f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0442\u043e\u0440\u0430 ansible playbook.\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0430\u0433\u0435\u043d\u0442 \u0432\u043b\u0435\u0437\u0435\u0442 \u043d\u0430 \u0441\u0430\u043c\u0443\u044e \u0434\u0435\u0448\u0435\u0432\u0443\u044e VPS.\u0410\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0431\u044f.\u0412\u0441\u044f \u044d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u043e\u0432\u0441\u0435, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0432\u044b\u0442\u0435\u043a\u0430\u0435\u0442 \u0438\u0445 \u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044d\u0442\u043e\u0439 \u0448\u0442\u0443\u043a\u0438 \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u0442\u044c ssh \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0430\u0433\u0435\u043d\u0442\u0443 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0433\u0434\u0435 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442, \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f.\u0424\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 = \u043f\u0438\u0441\u044c\u043c\u043e\u0421\u0430\u043c\u043e\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 Threlium \u2014 \u0432 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0438\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430. \u041d\u0435 \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 \u00ab\u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c\u00bb, \u0430 \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445.\u041b\u044e\u0431\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u2014 \u044d\u0442\u043e RFC 5322 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e MIME-\u0444\u0430\u0439\u043b \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 \u0438 \u0442\u0435\u043b\u043e\u043c. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u2014 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0438\u0441\u044c\u043c\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 Maildir. \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u2014 \u0442\u043e\u0436\u0435 Maildir (\u0444\u043e\u0440\u043c\u0430\u0442 tmp\/, new\/, cur\/, \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0447\u0435\u0440\u0435\u0437 rename(2)). \u0418\u043d\u0434\u0435\u043a\u0441 \u2014 notmuch \u043f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 Maildir\u2019\u043e\u0432. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u043c\u0438 \u044f\u0449\u0438\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0442\u0430\u043a \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0430\u043a\u0442\u043e\u0440\u043e\u0432 \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f.\u0417\u0432\u0443\u0447\u0438\u0442 \u0431\u0435\u0437\u0443\u043c\u043d\u043e? \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041d\u043e \u0432\u043e\u0442 \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u0430\u0451\u0442:\u041a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u2014 \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u0438\u0441\u043a\u0435. \u041c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c mutt\u2019\u043e\u043c, grep\u2019\u043d\u0443\u0442\u044c, \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442.\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. Maildir \u2014 \u044d\u0442\u043e \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438 canonical event store.\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438: \u0444\u0430\u0439\u043b \u043b\u0438\u0431\u043e \u0432 new\/, \u043b\u0438\u0431\u043e \u0432 cur\/, \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u043d\u0435 \u0434\u0430\u043d\u043e.\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c: \u0443\u043f\u0430\u043b \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u2014 \u0444\u0430\u0439\u043b \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0432 new\/, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e\u0434\u0431\u0435\u0440\u0451\u0442.\u041f\u043e\u043b\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430: \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u0430\u0439\u043b \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442 \u0432 cur\/&lt;id&gt;:2,S, \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.\u041e\u0434\u0438\u043d notmuch search &#8216;*&#8217; \u2014 \u0438 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f. \u042d\u0442\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u00ab\u0430\u0440\u0445\u0438\u0432\u00bb. \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u201c\u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f\u201d \u0430\u0433\u0435\u043d\u0442\u0430.\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u043d\u0430 Maildir\u2019\u0430\u0445Threlium \u2014 IRT-tree FSM. \u0420\u0430\u0441\u0448\u0438\u0444\u0440\u0443\u044e: \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u2014 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 Maildir, \u0430 \u0433\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f In-Reply-To \u0446\u0435\u043f\u043e\u0447\u043a\u0430\u043c\u0438 \u043f\u0438\u0441\u0435\u043c. \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430 \u043d\u0435\u0442. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0430 (\u0431\u044e\u0434\u0436\u0435\u0442 \u0448\u0430\u0433\u043e\u0432, \u043f\u0440\u0430\u0432\u0430) \u0436\u0438\u0432\u0451\u0442 \u043f\u0440\u044f\u043c\u043e \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u043f\u0438\u0441\u044c\u043c\u0430 \u2014 X-Threlium-Hop-Budget, X-Threlium-Capabilities.\u0421\u0442\u0430\u0434\u0438\u0438 FSM\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0438\u0445 \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0431\u0430\u0437\u0443 \u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u0443\u0434\u0443 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0435\u0435 \u0434\u0430\u043b\u0435\u0435, \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0442\u044f\u043d\u0443\u0442\u044c \u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0435.ingress \u2014 \u0435\u0434\u0438\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430. \u0421\u044e\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0432\u0441\u0435\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432.enrich \u2014 \u043e\u0431\u043e\u0433\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u0417\u0434\u0435\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f LightRAG (\u0433\u0440\u0430\u0444 \u0437\u043d\u0430\u043d\u0438\u0439) \u0438 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0442\u0440\u0435\u0434\u0430.reasoning \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0435. LLM \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0440\u043e\u043c\u043f\u0442 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 tool calls.egress_router \u2014 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440 \u0432\u044b\u0445\u043e\u0434\u0430. \u041f\u043e depth IRT-\u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0440\u0435\u0448\u0430\u0435\u0442: \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0441\u0443\u0431\u0430\u0433\u0435\u043d\u0442.egress_email, egress_telegram, egress_matrix \u2014 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0434\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u0430\u0440\u0443\u0436\u0443.cli_intent \u2014 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430: \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443?cli_exec \u2014 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f shell-\u043a\u043e\u043c\u0430\u043d\u0434.thread_memory, global_memory \u2014 FSM-\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e.archive \u2014 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0431 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435.\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441\u0442\u0430\u0434\u0438\u0438\u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0430\u0434\u0438\u044f \u2014 Python-\u043c\u043e\u0434\u0443\u043b\u044c threlium.states.&lt;stage&gt; \u0441 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439:def main(msg: EmailMessage, stage: FsmStage, *, config: Config) -&gt; EmailMessage | None:\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u043e \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u043f\u0438\u0441\u044c\u043c\u043e (\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0434\u0430\u043b\u044c\u0448\u0435) \u0438\u043b\u0438 None (\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0434\u0438\u044f). \u0412\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2014 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 \u0438 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u2014 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0441\u0442\u0430\u0434\u0438\u0438. \u0421\u0442\u0430\u0434\u0438\u044f \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b, \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 systemctl, \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e fdm. \u0427\u0438\u0441\u0442\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430\u0434 stdlib email.message.EmailMessage. \u041f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e.\u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSMPlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM@startumlleft to right directionpackage &#171;\u0412\u0445\u043e\u0434&#187; {  actor &#171;\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c&#187; as User  rectangle &#171;bridge-email&#187; as EB  rectangle &#171;bridge-telegram&#187; as TB  rectangle &#171;bridge-matrix&#187; as MB  User &#8212;&gt; EB : Email  User &#8212;&gt; TB : Telegram  User &#8212;&gt; MB : Matrix}rectangle &#171;fdm \u2192 notmuch insert&#187; as FDMEB &#8212;&gt; FDM : run_fdmTB &#8212;&gt; FDM : run_fdmMB &#8212;&gt; FDM : run_fdmrectangle &#171;ingress&#187; as INGrectangle &#171;enrich&#187; as ENRrectangle &#171;reasoning&#187; as REAFDM &#8212;&gt; INGING &#8212;&gt; ENRENR &#8212;&gt; REArectangle &#171;egress_router&#187; as EGRrectangle &#171;cli_intent&#187; as CLIrectangle &#171;thread_memory&#187; as TMrectangle &#171;global_memory&#187; as GMrectangle &#171;subagent_intent&#187; as SIrectangle &#171;reflect&#187; as REFREA &#8212;&gt; EGR : &#171;tool: egress_router&#187;REA &#8212;&gt; CLI : &#171;tool: cli_intent&#187;REA &#8212;&gt; TM : &#171;tool: thread_memory&#187;REA &#8212;&gt; GM : &#171;tool: global_memory&#187;REA &#8212;&gt; SI : &#171;tool: subagent_intent&#187;REA &#8212;&gt; REF : &#171;tool: reflect&#187;rectangle &#171;cli_exec&#187; as EXECrectangle &#171;cli_hitl_out&#187; as HITLCLI &#8212;&gt; EXEC : allowCLI &#8212;&gt; ING : denyCLI &#8212;&gt; HITL : HITLHITL &#8212;&gt; EGREXEC &#8212;&gt; INGTM &#8212;&gt; INGGM &#8212;&gt; INGREF &#8212;&gt; INGSI &#8212;&gt; INGrectangle &#171;egress_email&#187; as EErectangle &#171;egress_telegram&#187; as ETrectangle &#171;egress_matrix&#187; as EMrectangle &#171;subagent_end&#187; as SErectangle &#171;archive&#187; as ARCEGR &#8212;&gt; EE : &#171;depth == 0&#8243;EGR &#8212;&gt; ET : &#171;depth == 0&#8243;EGR &#8212;&gt; EM : &#171;depth == 0&#8243;EGR &#8212;&gt; SE : &#171;depth &gt; 0&#8243;SE &#8212;&gt; INGEE &#8212;&gt; ARCET &#8212;&gt; ARCEM &#8212;&gt; ARCactor &#171;\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c&#187; as UserOutEE &#8212;&gt; UserOutET &#8212;&gt; UserOutEM &#8212;&gt; UserOut@enduml\u0413\u0440\u0430\u0444 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 FSM\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f: fdm + notmuch insert\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043f\u0438\u0441\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0430\u0434\u0438\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f fdm \u2014 \u043b\u0451\u0433\u043a\u0438\u0439 mail delivery agent. \u041a\u043e\u043d\u0444\u0438\u0433 ~\/.fdm.conf (\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f Ansible \u0438\u0437 Jinja2-\u0448\u0430\u0431\u043b\u043e\u043d\u0430) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 To::match &#171;To&#187; &#8230; action pipe &#171;notmuch insert &#8212;folder=stages\/reasoning\/Maildir &#8230; &amp;&amp; threlium-dispatch.sh&#187;\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435: notmuch insert \u2014 \u044d\u0442\u043e \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0424\u0430\u0439\u043b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 Maildir \u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 notmuch \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e notmuch new \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e insert \u0442\u0443\u0442 \u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f dispatch-\u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u043e\u0440\u043a\u0435\u0440 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.\u041f\u043e\u0447\u0442\u0443 \u0434\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438, \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0435 \u0441\u043d\u043e\u0432\u0430 \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0430\u043a\u0442\u043e\u0440\u043e\u0432. \u041d\u0430\u043c \u043d\u0435\u0442 \u043e\u0441\u0442\u0440\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0442\u0430\u043a \u043a\u0430\u043a \u0430\u0433\u0435\u043d\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0434\u0435\u0441\u044f\u0442\u043a\u0442\u0438 \u043c\u0438\u043d\u0443\u0442.\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f: systemd &#8212;user\u041d\u0438\u043a\u0430\u043a\u0438\u0445 Celery, RabbitMQ, Kubernetes. \u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u2014 \u044d\u0442\u043e systemd &#8212;user. \u0412\u043e\u0442 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0446\u0435\u043f\u043e\u0447\u043a\u0430:PlantUML-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a: \u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f systemd@startumltop to bottom directionrectangle &#171;fdm \u2192 notmuch insert\\n&#8212;folder=stages\/\u2039stage\u203a\/Maildir&#187; as FDMrectangle &#171;threlium-dispatch.sh\\nnotmuch search tag:unread\\nAND folder:\u2039stage\u203a\/Maildir\\n\u2192 systemctl start &#8212;no-block&#187; as DISPrectangle &#171;threlium-work@\u2039stage\u203a:\u2039thread_id\u203a\\nType=exec\\npython -m threlium.runners.engine_submit %i\\n\u2192 JSON \u0432 UNIX-\u0441\u043e\u043a\u0435\u0442&#187; as WORKrectangle &#171;threlium-engine.service\\n\u0414\u043e\u043b\u0433\u043e\u0436\u0438\u0432\u0443\u0449\u0438\u0439 \u0434\u0435\u043c\u043e\u043d\\nparse_rfc822 \u2192 main() \u2192 run_fdm()&#187; as ENGINErectangle &#171;nm_settle()\\nnew\/\u2039id\u203a \u2192 cur\/\u2039id\u203a:2,S\\ntags.discard unread + to_maildir_flags&#187; as SETTLErectangle &#171;threlium-sweep@\u2039stage\u203a:\u2039thread_id\u203a\\nRace backstop\\nthrelium-dispatch.sh %i\\n\u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 backlog&#187; as SWEEPrectangle &#171;RAG-loop \u0432 engine\\nrag.ainsert + tag +lightrag_indexed&#187; as RAGrectangle &#171;JSON error \u2192 submit exit 1\\nRestart=on-failure\\n\u0431\u0435\u0437 sweep&#187; as ERRFDM &#8212;&gt; DISP : &#171;&amp;&amp; threlium-dispatch.sh&#187;DISP &#8212;&gt; WORKWORK &#8212;&gt; ENGINEENGINE &#8212;&gt; SETTLESETTLE &#8212;&gt; SWEEP : &#171;exit 0 \u2192 OnSuccess&#187;SWEEP ..&gt; DISP : &#171;\u0445\u0432\u043e\u0441\u0442 unread&#187;SETTLE ..&gt; RAG : &#171;schedule_index_pending&#187;ENGINE &#8212;&gt; ERR : &#171;exception&#187;@enduml\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f systemd\u0418\u043c\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 threlium-work@enrich:000000000012ab.service \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u043c\u044c\u044e\u0442\u0435\u043a\u0441. systemd \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442: \u043e\u0434\u0438\u043d \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u2014 \u043e\u0434\u0438\u043d \u0442\u0440\u0435\u0434. \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0440\u0435\u0434\u044b (\u0440\u0430\u0437\u043d\u044b\u0435 thread_id), \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u2014 \u043f\u0438\u0441\u044c\u043c\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0434\u0430 (oldest-first FIFO).\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e flock. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e coordinator. \u0412\u0441\u0451 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0438\u0437 systemd: \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0438 \u043f\u0440\u0438 \u0441\u0431\u043e\u044f\u0445 (Restart=on-failure), \u043b\u0438\u043c\u0438\u0442\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (threlium-work.slice \u0441 TasksMax, MemoryMax, CPUQuota), cgroup-\u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044f, \u043b\u043e\u0433\u0438 \u0447\u0435\u0440\u0435\u0437 journalctl.\u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0432 \u0441\u043e\u0442\u044b\u0439 \u0440\u0430\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u043d\u0443\u043b\u044f \u0441 \u043a\u043e\u0441\u044f\u043a\u0430\u043c\u0438 superviser for actors \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, KISS\u2026my ass. \u041f\u0440\u0438\u0447\u0435\u043c systemd &#8212;user \u0432\u044b\u0431\u0440\u0430\u043d \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 unit, \u043e\u043d\u0438 \u0436\u0438\u0432\u0443\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0432 \u043e\u0434\u043d\u043e\u043c git \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0432\u0441\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 \u0430\u0433\u0435\u043d\u0442\u0443 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e.\u041c\u043d\u043e\u0433\u043e\u043a\u0430\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0445\u043e\u0434: Email, Telegram, MatrixThrelium \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 \u0442\u0440\u0451\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u2014 \u044d\u0442\u043e \u043c\u043e\u0441\u0442 (threlium-bridge@&lt;chan&gt;.service), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0441\u0438\u0433\u043d\u0430\u043b \u0432 \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 RFC 5322 \u043f\u0438\u0441\u044c\u043c\u043e:\u041a\u0430\u043d\u0430\u043b\u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442From:EmailIMAP IDLE (imap-tools)email@localhostTelegramLong-poll (Bot API)telegram@localhostMatrixSync-loop (matrix-nio)matrix@localhost\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u0430 (chat_id, room_id, update_id, reply targets) \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a X-Threlium-Route \u043a\u0430\u043a base62(JSON). \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u043e\u0432\u043d\u043e \u0432 \u0442\u043e\u0442 \u0447\u0430\u0442\/\u043a\u043e\u043c\u043d\u0430\u0442\u0443\/\u044f\u0449\u0438\u043a, \u043e\u0442\u043a\u0443\u0434\u0430 \u043e\u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e.\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 egress_router \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043d\u0430\u043b &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-480987","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/480987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=480987"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/480987\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=480987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=480987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=480987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}