ac5d209fce
ci / JVM build + tests (push) Failing after 2m5s
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.
81 lines
4.7 KiB
Kotlin
81 lines
4.7 KiB
Kotlin
val caffeineRepo = providers.gradleProperty("caffeineRepo").getOrElse("http://192.168.76.117/repository/caffeine")
|
||
|
||
pluginManagement {
|
||
repositories {
|
||
gradlePluginPortal()
|
||
mavenCentral()
|
||
google()
|
||
}
|
||
}
|
||
|
||
dependencyResolutionManagement {
|
||
repositories {
|
||
// Сначала mavenLocal — чтобы локально опубликованные версии
|
||
// (через publishToMavenLocal) перекрывали caffeine.
|
||
mavenLocal()
|
||
mavenCentral()
|
||
google()
|
||
// Локально опубликованные snapshot-ы text-embedding-kmp (см. `~/.m2`).
|
||
// Home Nexus, репо "caffeine": pw.binom.* (A2A, ...)
|
||
maven {
|
||
name = "caffeine"
|
||
url = uri(caffeineRepo)
|
||
setAllowInsecureProtocol(true)
|
||
}
|
||
}
|
||
}
|
||
|
||
rootProject.name = "agentik"
|
||
|
||
include(":standalone")
|
||
// Generic LLM-side tools: LlmReflector, SkillMiner, LlmMemoryReviewer,
|
||
// ContextCompactor + парсеры/промпты. Вынесены из :standalone (god class)
|
||
// — переиспользуемы в :agentik-cli / :agentik-tui и любых других клиентах.
|
||
include(":llm-tools")
|
||
// Generic MCP-bridge: McpConfig, McpRegistry, McpLiteToolAdapter. Вынесены
|
||
// из :standalone — MCP не специфичен для standalone'а, это generic мост
|
||
// между MCP-SDK и LiteTool. Содержит :agent-toolsets (NamedTool).
|
||
include(":mcp-bridge")
|
||
// Собственный протокол agentik. Пока в нём пилим, потом вынесем.
|
||
include(":proto")
|
||
// Парсер скилов (YAML-frontmatter + markdown body, opencode-style).
|
||
include(":skills")
|
||
// Ktor-сервер, экспонирующий Agent по HTTP (SSE + JSON).
|
||
include(":server")
|
||
// Ktor-клиент, превращающий HTTP-фасад в `Agent`/`Conversation`.
|
||
include(":client")
|
||
// CLI-клиент поверх :client — REPL со slash-командами и стримингом ответов.
|
||
// KMP со всеми целями (jvm + весь натив), jvm-таргет собирается как shadowJar.
|
||
include(":agentik-cli")
|
||
// TUI-клиент поверх :client — Compose-style UI (Mosaic от Jake Wharton),
|
||
// рендерится в ANSI-терминал. KMP со всеми desktop-целями (без ios).
|
||
// include(":agentik-tui") — отключено 2026-09-17: пользователь признал TUI-подход неудачным.
|
||
// Папка agentik-tui/ оставлена на диске для возможного возврата; из сборки исключена.
|
||
|
||
// Встраиваемая долговременная память агента. `:memory-api` — интерфейсы,
|
||
// `:memory-md` — реализация на базе §-файлов (Hermes-style).
|
||
include(":memory-api")
|
||
include(":memory-md")
|
||
// Vector-бэкенд долговременной памяти поверх JVector (ANN-индекс) + SQLite
|
||
// для метаданных. JVM-only (JVector не имеет KMP-таргетов). На Android ART
|
||
// работает через Java 11 base classes (scalar fallback).
|
||
include(":memory-vector")
|
||
// Интерфейсы хранилища и разговорной истории: MessageStore / WorkingMemoryStore /
|
||
// ConversationStore / ReflectionStore + StorageBundle агрегатор. Реализации —
|
||
// в :storage-inmemory / :storage-sqlite / :storage-android (последний deferred).
|
||
include(":storage-core")
|
||
// In-memory реализация всех 4 store'ов из :storage-core. KMP, без платформенных
|
||
// IO-зависимостей. Используется в тестах (быстрый setup, без JDBC) и будет
|
||
// использоваться в Android-сборке (JVector/SQLite не подходят для ART out-of-box).
|
||
include(":storage-inmemory")
|
||
// SQLDelight-реализация всех 4 store'ов из :storage-core. JVM-only (SQLDelight
|
||
// native драйверов для KMP вне JVM пока не публикует). Содержит 4 .sq-файла +
|
||
// 5 классов: SqliteStores, SqliteConversationStore, SqliteMessageStore,
|
||
// SqliteWorkingMemoryStore, SqliteReflectionStore. Бэкенд для прод-запуска
|
||
// :standalone (путь к .db файлу в AGENTIK_DB).
|
||
include(":storage-sqlite")
|
||
// Ядро механики toolsets: ToolsetRegistry + ToolsetDispatchPolicy + встроенные
|
||
// тулы enable_toolset/disable_toolset. KMP, не зависит от :standalone, может быть
|
||
// переиспользован в Android-сборке. Интеграция с ChatAgent — commit 5+.
|
||
include(":agent-toolsets")
|