From b1eaeec6fc66e41639648a4fb7c9a328bccafddc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:23:29 +0000 Subject: [PATCH 1/9] Initial plan From 24b690faac636d7bfd353f2f09934b3a3e37282e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:28:38 +0000 Subject: [PATCH 2/9] Add configurable timeout for Ollama HTTP client to fix LLM timeout issues Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 7 +++++++ LocalAgent.ServiceDefaults/AIConfig.cs | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index b2d74a2..7c93f2d 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -33,6 +33,13 @@ .AddChatClient() .UseFunctionInvocation() .UseOpenTelemetry(configure: t => t.EnableSensitiveData = true); + + // Configure increased timeout for local Ollama LLM requests + // Local LLMs can be slower, especially on low-performance machines + builder.Services.AddHttpClient("ollamaModel_httpClient", client => + { + client.Timeout = TimeSpan.FromSeconds(aiConfig.TimeoutSeconds); + }); } else { diff --git a/LocalAgent.ServiceDefaults/AIConfig.cs b/LocalAgent.ServiceDefaults/AIConfig.cs index 7405d76..6ef7f7f 100644 --- a/LocalAgent.ServiceDefaults/AIConfig.cs +++ b/LocalAgent.ServiceDefaults/AIConfig.cs @@ -12,6 +12,12 @@ public class AIConfig public string ModelId { get; set; } = string.Empty; + /// + /// Timeout in seconds for HTTP requests to the AI service. + /// Default is 300 seconds (5 minutes) for local providers to accommodate slower local LLMs. + /// + public int TimeoutSeconds { get; set; } = 300; + /// /// Determines if the Azure provider is configured /// From 0261687230570df1149e66695ccbb37cc4932ee5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:29:13 +0000 Subject: [PATCH 3/9] Document TimeoutSeconds configuration in appsettings.json Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.AppHost/appsettings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LocalAgent.AppHost/appsettings.json b/LocalAgent.AppHost/appsettings.json index 4c386d1..52107c6 100644 --- a/LocalAgent.AppHost/appsettings.json +++ b/LocalAgent.AppHost/appsettings.json @@ -11,6 +11,7 @@ }, "AIConfig": { "Provider": "Local", - "ModelId": "llama32" + "ModelId": "llama32", + "TimeoutSeconds": 300 } } From 7e87fe0760320549f40b4ca47306295a2b4e3817 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:30:41 +0000 Subject: [PATCH 4/9] Address code review feedback: add validation and use constant for connection name Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index 7c93f2d..c97e367 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -29,16 +29,22 @@ if (aiConfig.IsLocalProvider()) { - builder.AddOllamaApiClient("ollamaModel") + // The connection name used for Ollama + const string OllamaConnectionName = "ollamaModel"; + + builder.AddOllamaApiClient(OllamaConnectionName) .AddChatClient() .UseFunctionInvocation() .UseOpenTelemetry(configure: t => t.EnableSensitiveData = true); // Configure increased timeout for local Ollama LLM requests // Local LLMs can be slower, especially on low-performance machines - builder.Services.AddHttpClient("ollamaModel_httpClient", client => + // The HttpClient name follows the pattern: {connectionName}_httpClient + builder.Services.AddHttpClient($"{OllamaConnectionName}_httpClient", client => { - client.Timeout = TimeSpan.FromSeconds(aiConfig.TimeoutSeconds); + // Ensure timeout is at least 1 second to prevent invalid values + var timeoutSeconds = Math.Max(1, aiConfig.TimeoutSeconds); + client.Timeout = TimeSpan.FromSeconds(timeoutSeconds); }); } else From d7e24d090307d4e216a9be2b539cccfbb36e4a59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:31:35 +0000 Subject: [PATCH 5/9] Improve documentation and use named constant for minimum timeout Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 5 +++-- LocalAgent.ServiceDefaults/AIConfig.cs | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index c97e367..19686a9 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -40,10 +40,11 @@ // Configure increased timeout for local Ollama LLM requests // Local LLMs can be slower, especially on low-performance machines // The HttpClient name follows the pattern: {connectionName}_httpClient + const int MinimumTimeoutSeconds = 1; builder.Services.AddHttpClient($"{OllamaConnectionName}_httpClient", client => { - // Ensure timeout is at least 1 second to prevent invalid values - var timeoutSeconds = Math.Max(1, aiConfig.TimeoutSeconds); + // Ensure timeout is at least MinimumTimeoutSeconds to prevent invalid values + var timeoutSeconds = Math.Max(MinimumTimeoutSeconds, aiConfig.TimeoutSeconds); client.Timeout = TimeSpan.FromSeconds(timeoutSeconds); }); } diff --git a/LocalAgent.ServiceDefaults/AIConfig.cs b/LocalAgent.ServiceDefaults/AIConfig.cs index 6ef7f7f..0c561fc 100644 --- a/LocalAgent.ServiceDefaults/AIConfig.cs +++ b/LocalAgent.ServiceDefaults/AIConfig.cs @@ -15,6 +15,8 @@ public class AIConfig /// /// Timeout in seconds for HTTP requests to the AI service. /// Default is 300 seconds (5 minutes) for local providers to accommodate slower local LLMs. + /// Note: This timeout applies specifically to HTTP client requests. Some AI providers may have + /// their own internal timeout mechanisms that are independent of this setting. /// public int TimeoutSeconds { get; set; } = 300; From 6fe62cf75518a28a31bf552f09aceec9420643cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:47:19 +0000 Subject: [PATCH 6/9] Fix timeout by configuring resilience handler before Ollama client creation Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index 19686a9..770c66e 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -32,21 +32,29 @@ // The connection name used for Ollama const string OllamaConnectionName = "ollamaModel"; - builder.AddOllamaApiClient(OllamaConnectionName) - .AddChatClient() - .UseFunctionInvocation() - .UseOpenTelemetry(configure: t => t.EnableSensitiveData = true); - - // Configure increased timeout for local Ollama LLM requests + // Configure increased timeout for local Ollama LLM requests BEFORE creating the client // Local LLMs can be slower, especially on low-performance machines // The HttpClient name follows the pattern: {connectionName}_httpClient const int MinimumTimeoutSeconds = 1; + var timeoutSeconds = Math.Max(MinimumTimeoutSeconds, aiConfig.TimeoutSeconds); + builder.Services.AddHttpClient($"{OllamaConnectionName}_httpClient", client => { - // Ensure timeout is at least MinimumTimeoutSeconds to prevent invalid values - var timeoutSeconds = Math.Max(MinimumTimeoutSeconds, aiConfig.TimeoutSeconds); - client.Timeout = TimeSpan.FromSeconds(timeoutSeconds); + // Set HttpClient timeout to infinite so the resilience handler's timeout is used + client.Timeout = Timeout.InfiniteTimeSpan; + }) + .AddStandardResilienceHandler(options => + { + // Configure the resilience handler with the desired timeout + // This overrides the global 10-second default for this specific client + options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); + options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); }); + + builder.AddOllamaApiClient(OllamaConnectionName) + .AddChatClient() + .UseFunctionInvocation() + .UseOpenTelemetry(configure: t => t.EnableSensitiveData = true); } else { From 2858fa9243149fe3224b3f4b602707d86ed8af7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:48:38 +0000 Subject: [PATCH 7/9] Increase minimum timeout to 30 seconds for LLM operations Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index 770c66e..f0db075 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -35,7 +35,7 @@ // Configure increased timeout for local Ollama LLM requests BEFORE creating the client // Local LLMs can be slower, especially on low-performance machines // The HttpClient name follows the pattern: {connectionName}_httpClient - const int MinimumTimeoutSeconds = 1; + const int MinimumTimeoutSeconds = 30; // Minimum 30 seconds for LLM operations var timeoutSeconds = Math.Max(MinimumTimeoutSeconds, aiConfig.TimeoutSeconds); builder.Services.AddHttpClient($"{OllamaConnectionName}_httpClient", client => From 82609128f6855fd8382fdca7b4602dfc2ad805c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 07:18:47 +0000 Subject: [PATCH 8/9] Reduce default timeout to 90s and configure circuit breaker sampling duration Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 4 ++++ LocalAgent.AppHost/appsettings.json | 2 +- LocalAgent.ServiceDefaults/AIConfig.cs | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index f0db075..59daf45 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -49,6 +49,10 @@ // This overrides the global 10-second default for this specific client options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); + + // Circuit breaker's sampling duration must be at least double the attempt timeout + // to be effective according to validation rules + options.CircuitBreaker.SamplingDuration = TimeSpan.FromSeconds(timeoutSeconds * 2.5); }); builder.AddOllamaApiClient(OllamaConnectionName) diff --git a/LocalAgent.AppHost/appsettings.json b/LocalAgent.AppHost/appsettings.json index 52107c6..c2d6967 100644 --- a/LocalAgent.AppHost/appsettings.json +++ b/LocalAgent.AppHost/appsettings.json @@ -12,6 +12,6 @@ "AIConfig": { "Provider": "Local", "ModelId": "llama32", - "TimeoutSeconds": 300 + "TimeoutSeconds": 90 } } diff --git a/LocalAgent.ServiceDefaults/AIConfig.cs b/LocalAgent.ServiceDefaults/AIConfig.cs index 0c561fc..4863740 100644 --- a/LocalAgent.ServiceDefaults/AIConfig.cs +++ b/LocalAgent.ServiceDefaults/AIConfig.cs @@ -14,11 +14,11 @@ public class AIConfig /// /// Timeout in seconds for HTTP requests to the AI service. - /// Default is 300 seconds (5 minutes) for local providers to accommodate slower local LLMs. + /// Default is 90 seconds to accommodate slower local LLMs while maintaining reasonable responsiveness. /// Note: This timeout applies specifically to HTTP client requests. Some AI providers may have /// their own internal timeout mechanisms that are independent of this setting. /// - public int TimeoutSeconds { get; set; } = 300; + public int TimeoutSeconds { get; set; } = 90; /// /// Determines if the Azure provider is configured From 51bbb70c1920dad2cb4c74fd49efa0292d089503 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:32:31 +0000 Subject: [PATCH 9/9] Remove AddStandardResilienceHandler for Ollama client to fix timeout issues Co-authored-by: hammar <68027+hammar@users.noreply.github.com> --- LocalAgent.ApiService/Program.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/LocalAgent.ApiService/Program.cs b/LocalAgent.ApiService/Program.cs index 59daf45..b66808d 100644 --- a/LocalAgent.ApiService/Program.cs +++ b/LocalAgent.ApiService/Program.cs @@ -38,21 +38,21 @@ const int MinimumTimeoutSeconds = 30; // Minimum 30 seconds for LLM operations var timeoutSeconds = Math.Max(MinimumTimeoutSeconds, aiConfig.TimeoutSeconds); + // IMPORTANT: We do NOT use AddStandardResilienceHandler for this client because: + // 1. The global AddStandardResilienceHandler cannot be effectively overridden per-client + // 2. It would stack with the global handler causing whichever timeout is shorter to win + // 3. For streaming LLM responses, we need a much longer timeout than the default 10 seconds builder.Services.AddHttpClient($"{OllamaConnectionName}_httpClient", client => { - // Set HttpClient timeout to infinite so the resilience handler's timeout is used - client.Timeout = Timeout.InfiniteTimeSpan; + // Set a long timeout for LLM operations (streaming responses can take a while) + client.Timeout = TimeSpan.FromSeconds(timeoutSeconds); }) - .AddStandardResilienceHandler(options => + // Remove any additional handlers that were added by ConfigureHttpClientDefaults + .ConfigureAdditionalHttpMessageHandlers((handlers, _) => { - // Configure the resilience handler with the desired timeout - // This overrides the global 10-second default for this specific client - options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); - options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(timeoutSeconds); - - // Circuit breaker's sampling duration must be at least double the attempt timeout - // to be effective according to validation rules - options.CircuitBreaker.SamplingDuration = TimeSpan.FromSeconds(timeoutSeconds * 2.5); + // Clear the standard resilience handler that was added by defaults + // This allows us to have a custom timeout for Ollama without interference + handlers.Clear(); }); builder.AddOllamaApiClient(OllamaConnectionName)