Add LLM-access library extracted from LiSSA - #1
Conversation
Framework-neutral library for chat LLM access, embeddings, and request caching, generalized from LiSSA (edu.kit.kastel.sdq.lissa.ratlr) so it can be shared across ArDoCo projects. Published as io.github.ardoco:llm-access. Features: - Chat models (OpenAI, Ollama, Blablador, DeepSeek, Open WebUI) via a typed LlmConfiguration + ChatModelProvider, with lazy initialization and cached single/n-fold requests (ChatModelUtils). - Embeddings (OpenAI, Ollama, ONNX, Open WebUI, mock) operating on plain strings, with transparent caching and jtokkit token-length handling. - Pluggable cache (local file, Redis, REST-Redis) with hierarchical layering and conflict-resolution strategies. On-disk and key formats are kept compatible with LiSSA's existing caches for a later drop-in migration.
|
@DanielDango I extracted the code from LiSSA; if possible, you can review the code :) |
There was a problem hiding this comment.
Pull request overview
Adds a new framework-neutral Java library (io.github.ardoco:llm-access) extracted/generalized from LiSSA to provide reusable chat-LLM access, embedding generation, and a pluggable request/embedding caching subsystem for ArDoCo projects.
Changes:
- Introduces typed chat model configuration/provider abstractions (platforms, lazy init, cached single/n-fold requests).
- Introduces embedding configuration/creator abstractions (multiple backends, caching, token-length fallback handling).
- Adds local/Redis/REST-Redis cache implementations with hierarchical layering + conflict strategies, plus tests, docs, and CI workflows.
Reviewed changes
Copilot reviewed 56 out of 57 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/resources/cache/test-local-cache-sample.json | Sample legacy-style local cache file for backward-compat tests. |
| src/test/resources/.env-test | Test-only environment configuration for cache/model tests. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/embedding/EmbeddingConfigurationTest.java | Tests embedding configuration defaults/platform parsing + mock/ONNX requirements. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatModelUtilsTest.java | Tests cached chat request behavior (miss/hit, n-fold, persistence). |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatConfigurationTest.java | Tests chat configuration defaults, parsing, provider metadata/caching parameters. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/cache/RestRedisTest.java | Testcontainers-based integration test for REST-Redis + hierarchical cache behavior. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/cache/HierarchicalCacheTest.java | Unit tests for hierarchical cache synchronization using mocks. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheTest.java | Unit tests for LocalCache persistence and legacy compatibility. |
| src/test/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheReplacementStrategyTest.java | Comprehensive tests for conflict resolution strategies. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/util/Pair.java | Small utility record used by the library. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/util/KeyGenerator.java | Deterministic key generation for caching (UUID from content). |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/util/Futures.java | Helper for resolving futures with logging and unchecked error propagation. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/util/Environment.java | .env + system env loading/overwriting utility used across providers/caches. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/OpenWebUiEmbeddingCreator.java | Open WebUI embedding backend integration. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/OpenAiEmbeddingCreator.java | OpenAI embedding backend integration. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/OnnxEmbeddingCreator.java | ONNX local embedding backend integration. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/OllamaEmbeddingCreator.java | Ollama embedding backend integration. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/MockEmbeddingCreator.java | Mock embedding backend for tests/offline usage. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/EmbeddingPlatform.java | Supported embedding platforms + defaults. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/EmbeddingCreator.java | Embedding creator API + factory dispatch by platform. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/EmbeddingConfiguration.java | Typed embedding configuration with defaults/builder/ONNX helper. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/CachedEmbeddingCreator.java | Core embedding caching + parallelization + token-length fallback logic. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/LlmConfiguration.java | Typed chat model configuration with defaults/builder. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/LazyChatModel.java | Thread-safe lazy initialization wrapper for chat models. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatModelUtils.java | Cached single/n-fold chat request helpers. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatModelProvider.java | Platform-specific chat model construction from config + env. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatModelPlatform.java | Supported chat platforms + defaults. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/UnifiedRedisClient.java | Minimal Redis client abstraction for cache implementations. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/RestRedisCache.java | REST-Redis cache backend (via adapter) with env-driven config. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/RestRedisAdapter.java | Adapter for the REST-Redis client to UnifiedRedisClient. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/RedisCache.java | Jedis-based Redis cache backend. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/RedisAdapter.java | Adapter for Jedis to UnifiedRedisClient. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/LocalCache.java | File-backed JSON cache backend with auto-flush behavior. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/LargeLanguageModelCacheMode.java | Enum distinguishing cache modes (chat vs embeddings). |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/HierarchicalCache.java | Multi-layer cache composition with conflict resolution. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/embedding/EmbeddingCacheParameter.java | Cache parameterization for embedding caches. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/embedding/EmbeddingCacheKey.java | Typed cache key for embedding entries (legacy-compatible structure). |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/chat/ChatCacheParameter.java | Cache parameterization for chat caches (incl. temperature handling). |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/chat/ChatCacheKey.java | Typed cache key for chat entries. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheType.java | Supported cache backend types. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheReplacementStrategy.java | Conflict/backfill strategies for layered caches. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheParameter.java | Cache parameter interface for key creation + cache identity. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheManager.java | Cache hierarchy construction/management + env-based configuration. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/CacheKey.java | Cache key contract + JSON key serialization helper. |
| src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/Cache.java | Cache interface + JSON conversion + backend factory method. |
| spotless.importorder | Spotless import order configuration. |
| sample.env | End-user configuration template for supported backends. |
| README.md | Library documentation, setup, usage examples, and configuration guide. |
| pom.xml | Maven module definition + dependency management + publishing settings. |
| license-header | License header template for formatting tooling. |
| formatter.xml | Eclipse formatter configuration used by formatting workflow. |
| .gitignore | Ignores build output, caches, .env, and IDE files. |
| .github/workflows/verify.yml | CI workflow to run Maven verify on PRs/branch pushes. |
| .github/workflows/format.yml | PR workflow to apply Spotless formatting and auto-commit changes. |
| .github/workflows/deploy.yml | Release workflow to deploy/publish artifacts. |
| .github/dependabot.yml | Dependabot configuration for Actions and Maven updates. |
| .github/CODEOWNERS | Defines default code owners for the repository. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 58 out of 59 changed files in this pull request and generated no new comments.
Suppressed comments (4)
src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/CachedEmbeddingCreator.java:216
tryToFixWithLength's binary search currently computes the first prefix length whose token count is >=MAX_TOKEN_LENGTH, and then embedssubstring(0, left). That can still be at/over the token limit and can re-trigger the same failure. The search should instead return the largest prefix that stays below the limit.
src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/CachedEmbeddingCreator.java:118- In the parallel path, if
awaitTerminationtimes out you only log and then proceed toFuture#get(viaFutures.getLogged), which can block indefinitely anyway. Consider failing fast on timeout (and on interruption) by cancelling/shutting down the executor and throwing.
src/main/java/edu/kit/kastel/mcse/ardoco/llm/cache/RedisCache.java:79 REDIS_URLis treated as set even when it is blank, which would makeRedisClient.create(redisUrl)fail with a confusing error. Treat blank as "unset" (similar toRestRedisCache).
private static RedisAdapter createRedisConnection() {
String redisUrl = "redis://localhost:6379";
if (Environment.getenv("REDIS_URL") != null) {
redisUrl = Environment.getenv("REDIS_URL");
}
src/test/java/edu/kit/kastel/mcse/ardoco/llm/chat/CachingChatModelTest.java:79
- This test claims to verify persistence across a "fresh" cache reload, but it never recreates the
CacheManager(socache()can just return the already-in-memory cache). Re-initialize the manager (pointing at the same temp dir) before the second call so the assertion actually exercises disk reload.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 67 out of 68 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/main/java/edu/kit/kastel/mcse/ardoco/llm/embedding/CachedEmbeddingCreator.java:216
- The binary search that determines
fixedContentfinds the first prefix whose token count is >= MAX_TOKEN_LENGTH, then uses that prefix. That meansfixedContentcan still be at/over the limit and can trigger the same embedding failure again (off-by-one / wrong boundary).
src/main/java/edu/kit/kastel/mcse/ardoco/llm/chat/ChatModelUtils.java:60 - This debug log prints the full LLM responses, which can leak sensitive/user data into application logs when debug is enabled. It's safer to log only metadata (e.g., count / lengths) and avoid dumping the content.
src/main/java/edu/kit/kastel/mcse/ardoco/llm/util/Environment.java:132 - When the .env file does not exist,
overwritekeeps the previous configuration (per the Javadoc) but the log message says it's "using system environment variables", which is misleading. This makes debugging configuration issues harder.
Framework-neutral library for chat LLM access, embeddings, and request caching, generalized from LiSSA (edu.kit.kastel.sdq.lissa.ratlr) so it can be shared across ArDoCo projects. Published as io.github.ardoco:llm-access.
Features: