- Domain: add ModelState, ModelStateEvent, ModelNotReady, ManageModelLifecycle
(in-port), ModelLoader and ModelStateEventBus (out-ports)
- Application: InMemoryModelStateEventBus; ModelLifecycleService — state
machine (ReentrantLock), lazy load on first request, idle-timeout auto-unload
(configurable via trueref.embedding.idle-timeout-seconds, default 300 s),
job-guard (skips unload while ingestion running), platform-thread CUDA executor
- Adapters: OnnxModelLoader wires embedder + reranker start/stop; remove
@PostConstruct/@PreDestroy from OnnxEmbeddingService and OnnxRerankerService;
requireStarted() now throws ModelNotReady instead of IllegalStateException
- REST: GET /api/model/status, POST /api/model/unload (409 when jobs running,
force=true to override), GET /api/model/status/stream (SSE)
- GlobalExceptionHandler: ModelNotReady -> 503 + Retry-After header
- HybridSearchService: calls lifecycle.ensureReady() before every search so
both REST and MCP paths get ModelNotReady (-> 503 / MCP error) when unloaded
- TrueRefMcpTools: catches ModelNotReady, returns retry hint in MCP error text
- Tests: InMemoryModelStateEventBusTest, ModelLifecycleServiceTest (10 cases),
OnnxModelLoaderTest, GlobalExceptionHandlerTest — all 41 tests green
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- align all io.modelcontextprotocol.sdk artifacts to 0.18.1 via
dependencyManagement so Spring AI transitives no longer pull mcp 0.10.0
- exclude Spring AI's legacy MCP server/webmvc auto-config, which is binary-
incompatible with the 0.18.1 streamable transport APIs
- build McpSyncServer directly against WebMvcStreamableServerTransportProvider
and adapt Spring AI ToolCallbacks to MCP SyncToolSpecifications manually
- keep /mcp as the sole Streamable HTTP endpoint for both initialize/tool calls
and optional SSE event streams
- update MCP transport documentation to match the new runtime
Validated locally with:
- POST /mcp initialize -> HTTP 200 + Mcp-Session-Id
- POST /mcp tools/list -> returns resolve-library-id + get-library-docs
- Upgrade mcp-spring-webmvc from 0.10.0 to 0.18.1 (adds
WebMvcStreamableServerTransportProvider alongside the legacy SSE provider)
- Add mcp-json-jackson2 0.18.1 for JacksonMcpJsonMapper adapter
- Exclude McpWebMvcServerAutoConfiguration (SSE transport) via
spring.autoconfigure.exclude; register WebMvcStreamableServerTransportProvider
and its RouterFunction manually in McpConfig so Spring AI's
McpServerAutoConfiguration picks up the correct transport bean
- Remove sse-message-endpoint / sse-endpoint from application.yml;
all MCP traffic now flows through POST+GET /mcp
- Remove McpSseMethodNotAllowed workaround from WebConfig and drop
'sse' from SPA fallback exclusions (no longer needed)
Clients should connect with type: http at https://trueref.sal.giize.com/mcp