Skip to content

Пристрої

Пристрій — це воркер, якого підняли не ми. З'явилося в AGNT2-267.

Усе, що продукт до цього ганяв каналом інструментів, було подом: ми його створювали, ми давали йому перепустку, виписану на одну сесію, і жив він кілька хвилин. Пристрій — інший вид співрозмовника на тому самому каналі: річ, якою хтось володіє, яка стоїть у домі, увімкнена місяцями й вимкнена тиждень, і яка телефонує нам сама.

Чому це взагалі працює

Через перший структурний факт зі сторінки каналу інструментів: воркер телефонує назовні, і ніхто не телефонує всередину. Це писалося про под — і виявилося саме тією властивістю, якої потребує Raspberry Pi за домашнім роутером. До нього не можна достукатися ззовні, і не треба.

Це не нова архітектура. Це наявна, повернута.

Що спільного із сесією — а спільного майже все

Дріт, цілком: субпротокол, обрамлення JSON-RPC, рукостискання MCP, відповідь tools/list, співвіднесення tools/call і коди закриття. Усе це — канал інструментів без змін, і один клас веде його для обох видів співрозмовника. Коду протоколу у слайсі пристрою немає взагалі.

Чого не спільного — і яка за це ціна

Сесія визначається своїми стелями: ttlSeconds, maxExecSeconds, вікно простою, яке читає жнець, сім станів, шість причин відмови, четверо дверей розбирання. Пристрій не має жодної з них, тож це власна таблиця, а не сесія з дев'ятьма обнуленими колонками.

Ціна названа, а не залишена на виявлення:

  • Тепер на одному каналі два види співрозмовника. Кожному майбутньому читачеві групи runtime/ доведеться питати «сесія чи пристрій?» там, де раніше була одна відповідь, а тому, хто розбирає сокет, — дивитися у дві таблиці замість однієї.
  • Чотири механізми до пристрою не застосовуються. Каталог профілів (наскільки великий), жнець дедлайнів (коли помре), четверо дверей розбирання (як прибирається) і шість причин відмови (чому не стартував) — усе це машинерія сесії. Читач, який гадає, що група runtime/ має один життєвий цикл, помилиться.

Дешевший варіант програв із конкретної причини: зробити сесію безстроковою означає перетворити дев'ять її колонок на «null тут означає, що рядок не зовсім сесія», і кожному читачеві — жнецеві, підмітальнику, розбиранню, екрану стану — довелося б вивчити другу форму рядка. Однією необнуленою колонкою менше — і жнець видаляє чиюсь камеру за те, що вона дев'яносто секунд мовчала.

Рядок — він же й обліковий запис

publicId + secretHash, той самий поділ, що в ключа вбудовування: зберігається не робочий ключ.

Відмінність від ключа вбудовування — у тому, що саме називає обліковий запис. Там ключ називає команду, і одна команда може мати їх скільки завгодно. Тут ключ і є особистістю пристрою, один на рядок — бо відкликання має зупиняти один пристрій, і бо канал зобов'язаний знати, який саме пристрій щойно зателефонував.

Ключ висить на команді, а не на агентові, тож видалена команда не може лишити по собі робочий обліковий запис.

Маршрути

GET    /teams/:teamId/devices                       усі пристрої команди
GET    /agents/:id/devices                          ті, до яких цей агент має право звертатися
POST   /agents/:id/devices                          прив'язати
POST   /agents/:id/devices/:deviceId/disconnect     обірвати живе з'єднання
DELETE /agents/:id/devices/:deviceId                відв'язати

Де код

сам пристрій, його канал, ключapi/src/slices/runtime/device
прив'язка до агента, набір інструментів, темп викликівapi/src/slices/agent/device

Див. також Використання та Канал інструментів.