Gromozeka is an experimental Kotlin Multiplatform + Compose Desktop AI assistant.
It is both a desktop agent UI and a dogfooding environment for building a more durable agent runtime: multi-tab conversations, tool execution, MCP integration, voice input, and typed long-term memory.
The project is currently a local research/development application, not a polished packaged product.
- Main dogfooding runtime:
OPEN_AI_SUBSCRIPTION. - Startup/composition root:
:presentation. - Business workflows:
:application. - Domain contracts and memory models:
:domain. - AI integrations and tool implementations:
:infrastructure-ai. - Persistence and search implementations:
:infrastructure-db. - Active long-term memory backend: MongoDB through
MemoryStore.
Legacy and auxiliary integrations still exist in the codebase, but the current default development path is the OpenAI subscription runtime plus Mongo-backed typed memory.
- Runs a native Compose Desktop chat UI with tabs and project-aware sessions.
- Calls LLM runtimes through domain-level
AiRuntimeabstractions. - Exposes internal tools for filesystem, shell, web search, code navigation, planning, and inter-agent workflows.
- Supports MCP configuration for external tools and servers.
- Provides voice-oriented UI pieces such as push-to-talk and TTS services.
- Writes and recalls structured project memory automatically during chat.
The active memory system is not a plain vector database. It stores typed, provenance-aware memory objects:
Source: immutable evidence, usually a chat turn or tool output.Entity: canonical project/user/product/concept anchor.Claim: atomic factual memory with predicate, scope, evidence, lifecycle, and temporal fields.Note: rationale, design note, or reusable reasoning chunk.Task: durable follow-up or commitment memory with lifecycle state.Profile: projection built from profile-sync claims.Episode: reusable experience or lesson pattern.MemoryRun: debug/audit trace for memory pipeline execution.
Runtime write path:
- Capture the current message as a source.
- Route the message with
LlmMemoryWriteRouter. - Retrieve relevant existing memory when needed.
- Canonicalize entities.
- Build/reconcile notes, claims, and tasks.
- Materialize changes into
MemoryStore. - Update projections such as profiles.
Runtime read path:
- Plan whether memory is needed with
LlmMemoryReadPlanner. - Verify no-memory decisions with a model-based verifier when needed.
- Search typed memory in MongoDB.
- Select/rerank final memory context.
- Inject the retrieved memory into the main LLM call as runtime-only context.
Maintenance flows are currently explicit/manual and synchronous: note consolidation, repair, entity maintenance, and retention.
Useful memory docs:
- MEMORY_IMPLEMENTATION.md
- MEMORY_CURRENT_STATE.md
- LLM_CASSETTE_NOTE.md
- agent_memory_handoff/README.md
- domain memory architecture
- macOS development machine.
- JDK 21.
- Docker, for local MongoDB.
- OpenAI subscription auth file in Gromozeka home for the current dogfooding runtime.
- Microphone permissions if you want to use voice input.
MongoDB is intentionally explicit. The app should fail fast if Mongo is not available.
Start MongoDB:
GROMOZEKA_HOME="$PWD/dev-data/client/.gromozeka" \
docker compose -f "$PWD/presentation/src/jvmMain/resources/docker-compose.yml" up -d mongodbRun the desktop app:
export GROMOZEKA_MODE=dev
export GROMOZEKA_HOME="$PWD/dev-data/client/.gromozeka"
./gradlew :presentation:run -qStop MongoDB:
docker compose -f "$PWD/presentation/src/jvmMain/resources/docker-compose.yml" stop mongodbCodex desktop run actions are configured in:
.codex/environments/environment.toml
The high-value actions are Start Mongo, Run, Stop Mongo, Build, App Context Test, Memory Unit Tests, and Memory Real E2E.
Build:
./gradlew :presentation:build -qApplication context smoke test:
./gradlew :presentation:build :presentation:jvmTest --tests ApplicationContextTest -qMemory maintenance unit tests:
./gradlew :application:jvmTest --tests 'com.gromozeka.application.service.memory.MemoryMaintenancePipelineTest' -qMemory real-model E2E in deterministic replay mode:
./gradlew :presentation:jvmTest \
--tests 'com.gromozeka.presentation.MemoryRealModelE2eTest' \
-Dgromozeka.memory.e2e=true \
-Dgromozeka.llm.cassette.mode=replay-only \
-qRecord missing LLM cassettes intentionally:
./gradlew :presentation:jvmTest \
--tests 'com.gromozeka.presentation.MemoryRealModelE2eTest' \
-Dgromozeka.memory.e2e=true \
-Dgromozeka.llm.cassette.mode=record-missing \
-qFor gromozeka.memory.e2e=true, cassette mode defaults to replay-only. This prevents accidental live LLM calls during normal verification.
domain/ Domain models, service contracts, tool contracts
application/ Use cases and orchestration pipelines
infrastructure-ai/ LLM runtimes, tools, MCP-related integrations
infrastructure-db/ Mongo persistence, search, repository implementations
presentation/ Compose Desktop UI, app bootstrap, runtime composition
shared/ Shared utilities
agent_memory_handoff/ Memory design handoff and reference architecture
docs/ Architecture notes, diagrams, research, guides
- Domain contracts should explain what the system must be able to do without forcing a storage or UI implementation.
- Memory debug quality is judged by traces and E2E artifacts, not only by compilation.
- The current E2E suite intentionally uses real LLM calls when recording cassettes and deterministic replay afterward.
- Logs are verbose by design while the memory MVP is still being hardened.
- MongoDB data lives under
GROMOZEKA_HOME/mongowhen started through the provided compose file.
Gromozeka is an attempt to move beyond "just chat" toward an assistant that can work with code, tools, projects, and its own accumulated context.
The goal is human-AI collaboration where the system remembers useful project knowledge, exposes its traces, and stays debuggable enough that a developer can understand why it did what it did.
Custom License - free for non-commercial use, commercial use requires permission. See LICENSE for details.
