Files
agentik/standalone
subochev ac5d209fce
ci / JVM build + tests (push) Failing after 2m5s
refactor(standalone): extract modules, event-driven background, AppConfig
Standalone refactor — modularity + correctness improvements after
STANDALONE-REVIEW findings. Touches ~30 files. Build green, 178 tests pass.

(1) Module extractions — generic components out of :standalone:

  • :llm-tools (new KMP module, package pw.binom.agentik.llm.tools)
    - LlmReflector, SkillMiner, LlmMemoryReviewer, LiteLlmContextCompactor
    - Parsers: ReflectionParser, SkillMiningParser, ReviewDecisionParser
    - Prompts: ReflectionPrompts, SkillMiningPrompts, ReviewPrompts

  • :mcp-bridge (new JVM module, package pw.binom.agentik.mcp.bridge)
    - McpConfig, McpRegistry, McpLiteToolAdapter

  • NamedTool moved from :standalone to :agent-toolsets/commonMain
    - Generic (name + LiteTool) wrapper, used by both :mcp-bridge
      and :standalone's tool dispatcher

  :standalone loses ~1400 lines, depends on the two new modules.

(2) Background work → event-driven (no more interval-polling):

  • New :standalone/agent/BackgroundEvents.kt — internal event bus:
    - ToolCallEvent.Succeeded/Failed (emitted by ToolDispatcher after invoke)
    - CompactionEvent.Triggered (emitted by CompactionCoordinator pre-delete)
    - ConversationLifecycleEvent.Closing (emitted by ConversationLoop.close)

  • BackgroundScheduler rewritten as event subscriber:
    - On Closing: final reflection + skill mining (last-chance extraction)
    - On Compaction (turnsToDelete > 10): skill mining (debounced 60s)
    - On ToolFailure x2 in 60s window: reflection (debounced 5min)
    - Dropped: maybeScheduleReview/Reflection/SkillMining (interval-based)
    - Dropped config: memoryReviewInterval, reflectionInterval, skillMiningInterval

  • ToolDispatcher emits ToolCallEvent after each invoke.
  • CompactionCoordinator emits CompactionEvent before workingMemory.compact().
  • ConversationLoop.close() emits Closing BEFORE agentScope.cancel() so the
    subscription gets to run final reflection/mining.

  Net effect: typical 30-turn conversation runs ~38 LLM calls (was: 30 main +
  3 review + 3 reflection + 2 mining). With event-driven, review/mining only fire
  when their triggers actually make sense (compaction about to delete, or
  conversation closing).

(3) AppConfig single source of truth:

  • Replaces AgentikConfig + LlmConfig.fromEnv + McpConfig.fromEnv with one
    AppConfig.fromEnv() that reads all ~25 env vars in a single pass.
  • Sections: AgentSection, LlmSection, McpSection, MemorySection,
    EmbeddingSection, ReflectionSection, SkillMiningSection, DebugSection.
  • OPENAI_CONTEXT_WINDOW / AGENTIK_GOOGLE_CONTEXT_WINDOW no longer
    read twice (was a bug per STANDALONE-REVIEW E3).

(4) Other fixes inherited from earlier waves:

  • Hardening — size caps on user-input boundaries:
    MAX_MEMORY_CONTENT_LEN=32KB, MAX_SKILL_BODY_LEN=64KB,
    MAX_MCP_CONFIG_BYTES=1MB, MAX_A2A_REPLY_LEN=10MB, MAX_PORT=65535,
    blank-rejection in LlmConfig.requireEnv, URL/command validation.
  • Single scope — :standalone/agent/ConversationLoop has one
    agentScope (was: scope + backgroundScope).
  • liteConvRef race fix — capture-then-use pattern replaces !!-after-read;
    close() + runTurn.finally race on LiteConv JNI handled via
    AtomicReference.getAndSet.
  • SkillMiner.maxTurns / LlmReflector.maxTurns exposed as public (needed
    by BackgroundScheduler for prompt sizing).
  • Tests: MemoryWiringTest updated for new compaction-triggered review
    behavior; all parser/test imports updated for new packages.

Test results: 178/178 in :standalone, 36/36 in :agent-toolsets — all green.
2026-09-18 20:43:54 +03:00
..

:standalone — single-jar HTTP-сервер со всеми транспортами

Что это

Главный исполняемый модуль проекта — single-jar HTTP-сервер с:

  • AG-UI transport на POST /agui (SSE) + GET /health.
  • A2A transport на POST / (JSON-RPC) + GET /.well-known/agent-card.json.
  • :proto transport на POST /agentik/* (HTTP+JSON+SSE) — наш stateful.
  • Embedded LLM backend: GOOGLE (LiteRT) или OPENAI-совместимый (vLLM, LiteLLM, OpenAI API).
  • SQLite persistence через :storage-sqlite.
  • Memory backend: md (файловый) или vector (SQLite+JVector+ HTTP/SIGLIP-embeddings).
  • Skills из ~/.agentik/skills/*.md.
  • SOUL из ~/.agentik/SOUL.md.
  • Background подпроцессы: рефлексия, skill-mining, memory-reviewer.

Решает: даёт пользователю один JAR (10–250 МБ), который запускается через java -jar agentik-0.1.0-all.jar, и поднимает сразу все транспорты, которые другие системы могут хавать.

Как запустить

Требования

  • JVM 21+.
  • (Опционально) CUDA-устройство для :backend=google (LiteRT).
  • (Опционально) LM через OpenAI-совместимый endpoint (vLLM / Ollama / OpenAI) для :backend=openai.

Запуск из готового fatjar

java --enable-native-access=ALL-UNNAMED \
     -jar agentik-0.1.0-all.jar

С дефолтами — встроенный SQLite, OpenAI-compatible backend на http://localhost:8001/v1, порт 8080.

Запуск через Gradle (dev)

./gradlew :standalone:run

pull-model subcommand (для LiteRT)

# Сначала скачать модель под LiteRT-Gemma-4-E2B
AGENTIK_LLM_BACKEND=google \
AGENTIK_GOOGLE_MODEL_PATH=/root/gemma-4-E2B-it.litertlm \
  java --enable-native-access=ALL-UNNAMED \
       -jar agentik-0.1.0-all.jar pull-model

Скачивает https://static.binom.pw/models/gemma-4-E2B-it.litertlm (2.5 ГБ, с Range-resume). Поддерживает override через AGENTIK_GOOGLE_MODEL_URL и verify через AGENTIK_GOOGLE_MODEL_SHA256_URL.

Переменные среды

Полный список — общий для всего :standalone-процесса:

Env Default Что делает
AGENTIK_PORT 8080 Порт HTTP-сервера
AGENTIK_DB_PATH ./agentik.db Путь к SQLite
AGENTIK_AGENT_ID agentik ID агента (для multi-instance)
AGENTIK_LLM_BACKEND openai openai или google
AGENTIK_LLM_MODEL (выбирается по backend) Имя модели
AGENTIK_LLM_API_URL http://localhost:8001/v1 Endpoint для OpenAI-compatible
AGENTIK_LLM_API_KEY no-key-needed Auth header
AGENTIK_LLM_CONTEXT_TOKENS 115000 Сколько токенов остаётся модели
AGENTIK_GOOGLE_MODEL_PATH /root/gemma-4-E2B-it.litertlm Путь к .litertlm файлу
AGENTIK_GOOGLE_MODEL_URL https://static.binom.pw/models/gemma-4-E2B-it.litertlm Откуда скачивать
AGENTIK_GOOGLE_MODEL_SHA256_URL — Если задан — verify по SHA-256
AGENTIK_AUTO_DOWNLOAD_MODEL 0 1 = скачать модель если её нет
AGENTIK_MEMORY_BACKEND vector md, vector или off
AGENTIK_EMBEDDING_BACKEND http http или siglip (только для vector)
AGENTIK_EMBEDDING_API_URL http://localhost:8001/v1 Endpoint для эмбеддингов
AGENTIK_EMBEDDING_MODEL text-embedding-3-small Имя embedding-модели
AGENTIK_SOUL_PATH ~/.agentik/SOUL.md Путь к SOUL.md
AGENTIK_SKILLS_DIR ~/.agentik/skills/ Каталог SKILL.md
AGENTIK_MEMORY_DIR ~/.agentik/memory/ Каталог для md-памяти
AGENTIK_TOOLSETS_DEFAULT memory,skills,files,web Включённые тулы
AGENTIK_DEBUG 0 1 = verbose logging

Значения читаются через AgentikConfig.fromEnv() в :standalone/.../Main.kt.

Эндпоинты

Метод Путь Transport Описание
GET /health любой health-check ({"ok":true})
POST /agui AG-UI Стриминг run (SSE)
POST / A2A JSON-RPC message/send, tasks/get, tasks/cancel
GET /.well-known/agent-card.json A2A Discovery
POST /agentik/conversations :proto Создать диалог
GET /agentik/conversations :proto Список диалогов
GET /agentik/conversations/:id :proto Snapshot
GET /agentik/conversations/:id/messages :proto История
POST /agentik/conversations/:id/send :proto Send (SSE)
GET /agentik/conversations/:id/events :proto Live-events (SSE)
POST /agentik/conversations/:id/interrupt :proto Прервать
POST /agentik/conversations/:id/rename :proto Переименовать
DELETE /agentik/conversations/:id :proto Удалить

Тесты

./gradlew :standalone:jvmTest                       # unit-тесты
./gradlew :standalone:integrationTest               # integration (Testcontainers)
./gradlew :standalone:shadowJar                     # → build/libs/agentik-0.1.0-all.jar

Известные ограничения

  1. vLLM не поддерживает cancel-inference (interrupt() только закрывает client SSE-socket; бэкенд всё равно генерирует до конца).
  2. A2A JSON discriminator — "kind" (text/file/data), а не "type". См. A2aJson в :standalone.
  3. SSE в не-TTY ssh закрывается на default Ktor timeout.

Текущий статус

Production-ready. Все KMP-модули проекта интегрированы. Полный manual-test checklist смотрите в MANUAL-TESTS.md или MANUAL-TESTS.md в корне.

Где скачать

  • Source: git clone https://git.binom.pw/subochev/agentik
  • Fatjar: Gitea CI artifacts (через .gitea/workflows/release.yml на tag v*) или собирается через ./gradlew :standalone:shadowJar.

Версии

Все gradle/libs.versions.toml. Поднять версию → release через git tag v0.2.0 && git push --tags → CI собирает все KMP-таргеты публикует артефакты.