From 5c9f5c7d0bf77abf8b38e6e39e59abcf6a6a1437 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 18 Mar 2026 23:07:43 -0400 Subject: [PATCH] feat: add model-availability validation to agentic insight generation (T009-T011) - Verify custom model exists on at least one configured server before starting agentic loop; returns HTTP 400 with descriptive error if not found - has_tool_calling field auto-serialised in GET /insights/models via existing ModelCapabilities Serialize derive - model_version stored from OllamaClient.primary_model (already correct in T006 implementation) Co-Authored-By: Claude Sonnet 4.6 --- README.md | 5 +++++ src/ai/insight_generator.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10d2d6e..c8f1c69 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,11 @@ The following environment variables configure AI-powered photo insights and dail - Used to fetch conversation data for context in insights - `SMS_API_TOKEN` - Authentication token for SMS API (optional) +#### Agentic Insight Generation +- `AGENTIC_MAX_ITERATIONS` - Maximum tool-call iterations per agentic insight request [default: `10`] + - Controls how many times the model can invoke tools before being forced to produce a final answer + - Increase for more thorough context gathering; decrease to limit response time + #### Fallback Behavior - Primary server is tried first with 5-second connection timeout - On failure, automatically falls back to secondary server (if configured) diff --git a/src/ai/insight_generator.rs b/src/ai/insight_generator.rs index 6434314..2027fd2 100644 --- a/src/ai/insight_generator.rs +++ b/src/ai/insight_generator.rs @@ -1803,7 +1803,32 @@ Return ONLY the summary, nothing else."#, let insight_cx = current_cx.with_span(span); - // 2. Check tool calling capability + // 2a. Verify the model exists on at least one server before checking capabilities + if let Some(ref model_name) = custom_model { + let available_on_primary = OllamaClient::is_model_available( + &ollama_client.primary_url, + model_name, + ) + .await + .unwrap_or(false); + + let available_on_fallback = if let Some(ref fallback_url) = ollama_client.fallback_url { + OllamaClient::is_model_available(fallback_url, model_name) + .await + .unwrap_or(false) + } else { + false + }; + + if !available_on_primary && !available_on_fallback { + anyhow::bail!( + "model not available: '{}' not found on any configured server", + model_name + ); + } + } + + // 2b. Check tool calling capability let capabilities = OllamaClient::check_model_capabilities( &ollama_client.primary_url, &ollama_client.primary_model,