З чого складається
Agentfy.ai 2.0 постачається як чотири речі, які можна задеплоїти. Це вся система — немає runner і немає окремого runtime-застосунку, бо ефемерний агент і є api.
| Частина | Простими словами | Роль |
|---|---|---|
api | Мозок + центр керування | Core і ефемерний мозок агента — одна кодова база/образ. Містить усі 8 шарів слайсів, включно з мозком (agent/orchestrator) і плейном керування воркерами (група слайсів runtime). «Рантайм» = образ api, запущений ефемерно. |
app | Сайт клієнта | Кабінет клієнта (Nuxt). |
admin | Панель керування | Адмін-панель (Nuxt). |
worker | Руки | Пісочниця на вимогу, що виконує зобов’язання агента (bash, файли, браузер, важкі/довгі задачі), які мозок не може сам. Stateful на задачу; гасне при простої. |
Три з них (api, app, admin) — звичайні постійно працюючі вебсервіси. worker — виняток: він з’являється лише коли є задача, потім завершується.

У свіжому обліковому записі рівно один агент — вбудований Консьєрж, якого створює продукт, а не людина. Це єдиний агент без власних Soul, Heartbeat, секретів, навичок, сайту, MCP та підключень: його робота — налаштувати решту.

Чому немає окремого «runner»
«Ефемерний рантайм», який усі собі уявляють, — це просто образ api, запущений на вимогу. Запуск тієї ж кодової бази на один хід дає нам мозок — тому ми не тримаємо другий runner-образ із власним циклом агента. worker — єдиний справді окремий виконуваний файл, бо йому потрібен інший, важкий образ: справжня ОС із bash + Chromium.
Межа api ↔ worker
Це найважливіша лінія:
api= мозок + менеджер. Цикл LLM, оркестрація та прямі (без інструментів) відповіді, плюс плейн, що керує воркерами (група слайсівruntime: черга, життєвий цикл сесії, k8s, події), і збереження виводів черезsystem/file.worker= руки. Контейнер із bash / файлами / Chromium (Playwright). Stateful на задачу (жива сесія браузера, робоча директорія). Не тримає довгоживучих секретів — отримує короткоживучий session-токен відapi(user/auth), що спливає разом із сесією.
Одне ім'я в однієї речі
«Пісочниця» і «воркер» раніше називали одне й те саме в різних половинах коду. Більше ні: усюди worker — каталог, образ, перепустка, ці сторінки, слайси й об'єкти, які видно в kubectl. Два імені в одного поняття — це те, через що читач перестає розуміти, одна перед ним річ чи дві.
Слово ділять два слайси, і це навмисно, а не недороблено: runtime/worker — половина, яка піднімає й гасить воркери, а agent/worker — половина, яка вирішує, що ходу потрібні руки. На дроті слова «пісочниця» не було ніколи, тому контракт від усього цього не змінився.
Відкинуте ім'я одного разу повернулося — за три тижні, у коді тих, хто цю врізку не читав. Тому тепер це справа гейта, а не домовленості: make naming відхиляє його будь-де в дереві, в імені файлу так само, як у реченні, а scripts/naming-check.mjs — реєстр відкинутих імен і єдине місце, де відкинуте написання ще виписане повністю.
Конфігурація, яка відмовляє, а не розходиться
- В адреси API рівно одне джерело.
appіadminчитають її з nuxt'івськогоruntimeConfig.public.apiBase, який наповнюєNUXT_PUBLIC_API_BASE(за замовчуваннямhttp://localhost:3333). Більше її не задає ніхто:import.meta.envне доїжджає до браузерного бандла, тому покладене туди значення читається якundefined, і мовчки виграє захардкоджена запасна адреса — причому лише на тих машинах, де адреса відрізняється від дефолтної. apiне підніметься на плейсхолдерному секреті. ПозаdevelopmentJWT_SECRET, який не заданий, усе ще дорівнює закоміченому плейсхолдеру або коротший за 32 символи, зупиняє старт і називає, що саме не так. Плейсхолдер, з яким застосунок піднімається, — це плейсхолдер, який поїде в прод, а знанняJWT_SECRETдає токен за будь-якого користувача.
Один транспорт у браузері, і що на ньому їде
app і admin розмовляють з api через один клієнт, побудований на штатному fetch. Другого шляху немає: згенерований SDK, стріми і завантаження-вивантаження пакета йдуть однаково, тому продовження сесії та обробка помилок діють на кожен запит, а не на половину. Коли транспортів було два, петлю refresh лагодили на перехопленій половині, а на стрімах її не було зовсім.
На цьому єдиному клієнті їдуть три поведінки, і кожна стоїть там тому, що її відсутність одного разу обійшлася у вимірювану ціну:
- Один повтор на запит, а не ланцюжок. Невиправний
401раніше давав сотні пар запитів, доки не втручався рейт-лімітер. - Одне продовження на пачку. Кілька паралельних
401продовжують сесію рівно один раз, і латчем слугує сама сесія, а не прапорець у модулі. - Повтор іде зі свіжим токеном, а термінальна відмова чистить сесію і веде на
/loginз причиною: людина, викинута на екран входу без пояснення, вирішує, що продукт зламано.
Далі
- Як ми це будуємо — як влаштований код усередині
api. - Docker-образи — як збирається й постачається кожна частина.
- Шари-слайси — вісім груп слайсів детально.