picogent/README.md
2026-02-21 02:41:39 +03:00

14 KiB
Raw Permalink Blame History

picogent

Минимальный AI-агент с in-process agentic loop на базе Pi Agent Core. Два режима работы: WebSocket-чат и интеграция с Team Board Tracker.

Требования

  • Node.js 22+
  • npm

Установка

npm install
npm run build

Режимы работы

Picogent автоматически определяет режим по наличию конфигурации:

1. WebSocket-режим (чат)

Без конфига запускается как WebSocket-сервер для прямого общения через браузерный клиент.

npm run dev
# или
npm start

Откройте client.html в браузере, подключение к ws://localhost:3100.

Настройка через переменные окружения (или .env файл):

Переменная Описание Default
PICOGENT_PORT Порт WebSocket-сервера 3100
PICOGENT_WORK_DIR Рабочая директория агента cwd
PICOGENT_MODEL Модель LLM sonnet
PICOGENT_PROVIDER Провайдер LLM anthropic
PICOGENT_API_KEY API ключ
ANTHROPIC_API_KEY API ключ (альтернатива)

2. Agent-режим (Team Board Tracker)

Агент регистрируется в трекере, получает задачи и выполняет их. Поддерживает два транспорта:

  • http (по умолчанию) — агент поднимает HTTP-сервер, трекер шлёт события через POST. Требует открытый порт (listen_port).
  • ws — агент сам подключается к трекеру по WebSocket. Не требует открытого порта и callback_url. Автоматический reconnect с exponential backoff.

Активируется при наличии agent.json, директории с конфигом, или переменной TRACKER_URL.

Параметры запуска

# Режим директории — папка с agent.json, skills/, sessions/
npm run dev -- ./agents/coder/

# Режим файла — путь к JSON-конфигу
npm run dev -- ./my-agent.json

# Через переменную окружения
PICOGENT_CONFIG=./agent.json npm run dev

# Только через env (без файла конфига)
TRACKER_URL=http://localhost:8100 AGENT_TOKEN=tb-xxx npm run dev

# Production
npm start -- ./agents/coder/

Приоритет конфигурации

  1. CLI аргумент (директория или файл)
  2. Переменная PICOGENT_CONFIG
  3. ./agent.json в текущей директории (если существует)
  4. Env-переменные (TRACKER_URL + AGENT_TOKEN)

Env-переменные всегда имеют приоритет над значениями из JSON-файла.

Конфигурация агента (agent.json)

Все поля опциональны (кроме tracker_url и token для agent-режима). Полный пример с описаниями — agent.example.json.

{
  "name": "Кодер",
  "slug": "coder",
  "prompt": "Ты опытный Go-разработчик...",
  "tracker_url": "http://localhost:8100",
  "token": "tb-agent-abc123",
  "transport": "http",
  "listen_port": 3200,
  "work_dir": "/projects/my-app",
  "model": "sonnet",
  "provider": "anthropic",
  "capabilities": ["coding", "review"],
  "max_concurrent_tasks": 2,
  "heartbeat_interval_sec": 30,
  "allowed_paths": []
}
Поле Env Default Описание
name AGENT_NAME Agent Имя агента в трекере
slug AGENT_SLUG agent Уникальный ID (латиница)
prompt AGENT_PROMPT Системный промпт — роль агента
tracker_url TRACKER_URL URL Team Board Tracker (обязательно)
token AGENT_TOKEN Bearer-токен для Tracker API (обязательно)
transport AGENT_TRANSPORT http Транспорт: http или ws
listen_port AGENT_PORT 3200 Порт HTTP (только transport=http)
work_dir PICOGENT_WORK_DIR agentHome / cwd Рабочая директория
model PICOGENT_MODEL sonnet Модель LLM
provider PICOGENT_PROVIDER anthropic Провайдер LLM
api_key PICOGENT_API_KEY / ANTHROPIC_API_KEY API ключ провайдера
capabilities ["coding"] Возможности для трекера
max_concurrent_tasks 2 Макс. параллельных задач
heartbeat_interval_sec 30 Интервал heartbeat (сек.)
allowed_paths [] (без ограничений) Ограничение доступа к FS

Алиасы моделей

Алиас Полный ID
sonnet claude-sonnet-4-6
opus claude-opus-4-6
haiku claude-haiku-4-5
sonnet-4 claude-sonnet-4-6
opus-4 claude-opus-4-6
sonnet-3.5 claude-3-5-sonnet-20241022

Режим директории (рекомендуется)

Самый удобный способ — создать папку со всем необходимым:

agents/coder/
  agent.json          # конфиг
  skills/             # скилы агента
    review/
      SKILL.md
  sessions/           # сессии (создаётся автоматически)

Запуск:

npm run dev -- ./agents/coder/

В этом режиме:

  • agentHome = путь к директории
  • workDir = то же (если не переопределён через work_dir или env)
  • Скилы загружаются из agentHome/skills/
  • Сессии сохраняются в agentHome/sessions/

Скилы (Skills)

Агент поддерживает скилы — специализированные инструкции в формате SKILL.md.

Структура скила

skills/
  review/
    SKILL.md
  refactor/
    SKILL.md

Формат SKILL.md

---
name: review
description: "Code review — анализ кода на ошибки, стиль, производительность"
---

# Code Review

Инструкции для агента...

Как работает

Используется progressive loading (как в Claude Code):

  1. В системный промпт попадают только XML-сводки скилов (имя + описание + путь)
  2. Агент читает полный SKILL.md через инструмент Read только когда скил нужен
  3. Контекст не засоряется лишним текстом

Скилы загружаются из двух мест:

  • agentHome/skills/ (или workDir/skills/) — скилы конкретного агента
  • ~/.picogent/skills/ — глобальные скилы

Ограничение доступа к файлам (allowed_paths)

По умолчанию агент может читать и писать файлы без ограничений. Для ограничения укажите список разрешённых директорий:

{
  "allowed_paths": [
    "/projects/my-app/src",
    "/projects/my-app/tests"
  ]
}

Что защищено:

  • Read — проверка пути перед чтением
  • Write — проверка перед записью и созданием директорий
  • Edit — проверка перед чтением и записью
  • Bash — проверка, что рабочая директория команды внутри allowed_paths

Что не защищено:

  • Grep/Find/Ls — read-only инструменты, не ограничиваются
  • Bash-команды — содержимое команд не парсится (агент может выполнить cat /etc/passwd). Для полной изоляции bash используйте контейнеры

.env файл

API ключи и секреты удобно хранить в .env файле в корне проекта:

ANTHROPIC_API_KEY=sk-ant-...
TRACKER_URL=http://localhost:8100
AGENT_TOKEN=tb-agent-abc123

Node 22 загружает .env автоматически через флаг --env-file=.env (прописан в package.json).

Архитектура

src/
  index.ts                  # Точка входа, dual-mode wiring
  config.ts                 # Загрузка конфигурации (JSON + env)
  agent.ts                  # Pi Agent Core — agentic loop, skills, sessions
  sandbox.ts                # Sandboxed tools с проверкой путей
  router.ts                 # Роутер событий трекера -> agent
  logger.ts                 # Pino logger
  transport/
    websocket.ts            # WebSocket-сервер (чат-режим)
    http.ts                 # HTTP-сервер (agent-режим, transport=http)
    ws-client.ts            # WebSocket-клиент к трекеру (agent-режим, transport=ws)
    types.ts                # Общие типы транспорта
  tracker/
    client.ts               # HTTP-клиент к Tracker API
    registration.ts         # Регистрация + heartbeat
    types.ts                # Типы Tracker API

Поток данных

WebSocket-режим:

Browser (client.html) -> WebSocket -> index.ts -> runAgent() -> Pi Agent Core -> WebSocket -> Browser

Agent-режим (transport=http):

Tracker -> HTTP POST /events -> HttpTransport -> EventRouter -> runAgent() -> Pi Agent Core -> TrackerClient -> Tracker

Agent-режим (transport=ws):

Agent -> WebSocket -> Tracker (auth + heartbeat + events) -> WsClientTransport -> EventRouter -> runAgent() -> TrackerClient -> Tracker

Ядро (agent.ts)

Использует Pi Agent Core (@mariozechner/pi-coding-agent) для in-process agentic loop:

  • Модели через ModelRegistry с models.json в ~/.picogent/
  • API ключи через AuthStorage с runtime injection (initAgent())
  • Инструменты: Read, Write, Edit, Bash, Grep, Find, Ls (через createSandboxedTools)
  • Сессии: JSONL-файлы через SessionManager
  • Скилы: loadSkills() + formatSkillsForPrompt() для progressive loading

Tracker интеграция

  • HTTP-транспорт (по умолчанию): POST /api/v1/agents/register с callback_url, POST /api/v1/agents/heartbeat, события через HTTP POST
  • WS-транспорт: агент подключается к /ws?client_type=agent, регистрация и heartbeat через WebSocket, события приходят через тот же канал
  • Задачи: трекер отправляет task.assigned event -> агент выполняет -> результат как комментарий + статус review
  • Чат: трекер отправляет chat.message -> агент отвечает -> комментарий к задаче
  • Устойчивость: HTTP — retry регистрации каждые 5с. WS — reconnect с exponential backoff (1с → 30с)

WebSocket-протокол

Клиент -> Сервер

{
  "id": "msg-1",
  "content": "Какие файлы есть в текущей директории?",
  "sessionId": "my-session",
  "workDir": "/projects/my-app",
  "systemPrompt": "Ты помощник-разработчик"
}
Поле Обязательно Описание
id да Уникальный ID сообщения
content да Текст промпта
sessionId нет Имя сессии (для сохранения контекста между сообщениями)
workDir нет Рабочая директория для этого запроса
systemPrompt нет Дополнительный системный промпт

Сервер -> Клиент (стрим)

{
  "id": "msg-1",
  "type": "text",
  "content": "В директории находятся...",
  "sessionId": "abc-123"
}

Типы сообщений:

  • text — фрагмент текстового ответа (стримится по мере генерации)
  • tool_use — агент вызвал инструмент (формат: ToolName: описание)
  • tool_result — результат инструмента с ошибкой
  • error — ошибка агента или API
  • done — запрос завершён

Команды

npm install          # Установка зависимостей
npm run build        # Компиляция TypeScript
npm run dev          # Dev-режим (tsx, .env)
npm start            # Запуск из dist/ (.env)
npm test             # Тесты (vitest)

Файлы данных

Путь Описание
~/.picogent/ Домашняя директория picogent
~/.picogent/models.json Конфигурация моделей (создаётся автоматически)
~/.picogent/auth.json Хранилище API ключей
~/.picogent/sessions/ Сессии по умолчанию
~/.picogent/skills/ Глобальные скилы

Происхождение

Проект извлечён из двух соседних проектов:

  • OpenClaw (openclaw/) — паттерн in-process agent loop через Pi Agent Core (createAgentSession, AuthStorage, ModelRegistry, codingTools, event subscription)
  • NanoClaw (nanoclaw/) — паттерн pino-логгера, структура "получи сообщение -> запусти агента -> отправь результат"

Сознательно выброшено: каналы, контейнеры, плагины, auth profiles, MCP, subagents и прочая сложность. Picogent — это голый agent loop + транспорт.