Scan the shared MFA repositories
MfaEnrollmentService is a @Service in kamo-shared-library, so the wildcard @ComponentScan("com.kamo") in this application constructs it whether or not this serv...
Harden the kubectl download against flaky egress [skip ci]
dl.k8s.io over the runner's egress intermittently drops mid-transfer: curl: (56) OpenSSL SSL_read: decryption failed or bad record mac which fails the deploy ...
Classify vision failures so the retry loop and circuit breaker actually work
Two bugs in visionComplete, both of which defeated machinery built to handle them. A blank-content response was returned as SUCCESS and ended the retry loop. E...
Never route vision to an adapter that cannot send an image
AiProvider.supportsVision is a hand-editable database flag, and routing trusted it alone. The HuggingFace and Cohere adapters never read imageUrls at all, and t...
Anthropic dropped every system message but the last
buildRequestBody assigned rather than accumulated the system field, so with more than one system message only the final one reached the model. In practice that ...
Locked rules survive a section or whole-document override
An author taking over a rule section by hand replaced the entire section body, which silently discarded the locked pack rules inside it - so 'never quote a rate...
Streamed replies were dropped, persisting blank assistant messages
Every successful chat completion came back as an EMPTY assistant bubble. The assistant rows were being saved with content_len=0 and is_error=false, so there was...
Try the next model when a vision model rejects the image
Probing production again after the modality fix, routing moved from a text-to-speech model to o3-mini — an o-series reasoning model that also takes no image inp...
Stop routing vision to text-to-speech models
Found by probing production: org 1188756624575266822's vision calls resolved to gpt-4o-mini-tts-2025-03-20 — a TEXT-TO-SPEECH model — so every vision call retur...
Load history images via query, not lazy getImages() (WS path)
**************** runs on the WebSocket path (called from AiChatWebSocketHandler), which is NOT an HTTP request, so open-session-in-view does not apply. Iteratin...
Allow SWITCH_MODEL to reset a session to Auto
handleSwitchModel always UUID-parsed modelId and errored on null, so a session could never be reverted to automatic model selection mid-chat. Parse modelId as a...
Robust vision provider/model selection across vendors
Two-pass selectVisionProvider: prefer any org provider that has an active vision-capable model adapter already emits image_url content and reports supportsVisio...
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Lower RAG min-score threshold from 0.5 to 0.25 to stop filtering relevant KB results
The 0.5 threshold was silently discarding valid results from the embedding model, especially for domain-specific content with smaller 384-dim vectors.
Add response body and request logging to RagClient for debugging
Log the RAG search request URL, orgId, query, and response body on error to diagnose 500 responses from RAGService.
Use non-streaming chat completion for REST endpoint
Streaming over REST with blockLast() was producing empty responses because WebClient's SSE parsing doesn't work reliably with bodyToFlux(String.class). Added ha...
Add detailed error logging to HuggingFaceAdapter for debugging 400 errors
Captures and logs the actual HF error response body instead of just status code.
Switch HuggingFace to router.huggingface.co (api-inference is deprecated)
HF returns 410 on api-inference.huggingface.co with message to use router.huggingface.co instead.
Use HuggingFace OpenAI-compatible endpoint with model in request body
HF's /v1/chat/completions endpoint takes the model ID in the JSON body, not in the URL path. Switched from per-model URL routing to standard
Add model count to provider list, switch HF to router endpoint
- Include modelCount in provider list GET response - Switch Hugging Face default base URL to router.huggingface.co - Support both api-inference and router URL f...
Return full decrypted API key in provider responses
Users need to see and edit the full key, not a masked version.
Normalize base URL to prevent /v1/v1 duplication
Strips trailing /v1 from base URL before appending /v1/chat/completions, so users can enter base URLs with or without the /v1 suffix.
Restructure test connection to discover models first, handle rate limits gracefully
- Model discovery (lightweight GET) runs before chat test (POST) - Rate limit (429) errors show user-friendly warning instead of failing - Auth errors (401/403)...
Use provider-specific test model instead of hardcoded gpt-4o-mini
Each provider type now uses an appropriate model for connection testing
Serialize entity IDs as strings to prevent JavaScript precision loss
CockroachDB unique_rowid() generates INT8 values that exceed JavaScript's Number.MAX_SAFE_INTEGER, causing ID corruption in the frontend.
Add OTK authentication support matching SecurityService pattern
- Add OTKPreAuthFilter to validate X-OTK header and resolve to *** session - Update SessionHelper to read from request attributes set by filter - Update all con...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
