summaryrefslogtreecommitdiff
path: root/tests/Agent.Core.Tests/OllamaClientTests.cs
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-12 00:21:23 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-12 00:21:23 +0900
commit98b6a2aeedd591058c1d81e401d24f3ded162926 (patch)
tree74cbb38af825526e4fc90b150feed14426d727b4 /tests/Agent.Core.Tests/OllamaClientTests.cs
parentce550a127b7dc972651bd15b9f09979a2c38688f (diff)
fix: implement native Ollama thinking semantics
Model Ollama chat thinking separately from final content, preserve it only across assistant tool-call continuation, and keep private reasoning out of user results, session context, and logs. Accept native boolean and low/medium/high/max think values, normalize YAML booleans, and serialize explicit overrides using the native top-level chat field. Stop forcing think=false for structured planning, skill selection, and context summaries; corrected retries now retain the configured thinking mode. Update the specification, design, audit report, and requirement traceability for OLL-14. Add request/response, configuration, observability, retry, and tool-continuation coverage. Verified with 92 passing Agent.Core tests and a deepseek-v4-flash:cloud think:true MCP operational run.
Diffstat (limited to 'tests/Agent.Core.Tests/OllamaClientTests.cs')
-rw-r--r--tests/Agent.Core.Tests/OllamaClientTests.cs54
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/Agent.Core.Tests/OllamaClientTests.cs b/tests/Agent.Core.Tests/OllamaClientTests.cs
index 94ce8cd..87a3e20 100644
--- a/tests/Agent.Core.Tests/OllamaClientTests.cs
+++ b/tests/Agent.Core.Tests/OllamaClientTests.cs
@@ -38,6 +38,60 @@ public sealed class OllamaClientTests
}
[Fact]
+ public async Task Thinking_is_separated_from_final_content_and_not_discarded()
+ {
+ var handler = new StubHandler((_, _) => Task.FromResult(Json(HttpStatusCode.OK,
+ """{"message":{"role":"assistant","thinking":"private reasoning","content":"final answer"},"prompt_eval_count":3,"eval_count":5}""")));
+ var client = new OllamaClient(new HttpClient(handler),
+ new OllamaSettings(new Uri("http://127.0.0.1:11434"), "test-model", true, "0", new Dictionary<string, JsonElement>()));
+
+ OllamaResult result = await client.ChatAsync([new OllamaMessage("user", "hello")], null, TestContext.Current.CancellationToken);
+
+ Assert.Equal("final answer", result.Content);
+ Assert.Equal("private reasoning", result.Thinking);
+ }
+
+ [Fact]
+ public async Task Thinking_level_and_assistant_thinking_history_follow_native_chat_schema()
+ {
+ string? body = null;
+ var handler = new StubHandler(async (request, _) =>
+ {
+ body = await request.Content!.ReadAsStringAsync();
+ return Json(HttpStatusCode.OK, """{"message":{"role":"assistant","content":"done"}}""");
+ });
+ var client = new OllamaClient(new HttpClient(handler),
+ new OllamaSettings(new Uri("http://127.0.0.1:11434"), "test-model", "high", "0", new Dictionary<string, JsonElement>()));
+
+ await client.ChatAsync([new OllamaMessage("assistant", "", ToolCalls: [], Thinking: "prior reasoning")], null,
+ TestContext.Current.CancellationToken);
+
+ using JsonDocument document = JsonDocument.Parse(body!);
+ Assert.Equal("high", document.RootElement.GetProperty("think").GetString());
+ Assert.Equal("prior reasoning", document.RootElement.GetProperty("messages")[0].GetProperty("thinking").GetString());
+ }
+
+ [Fact]
+ public async Task Explicit_false_override_is_serialized_as_boolean_false()
+ {
+ string? body = null;
+ var handler = new StubHandler(async (request, _) =>
+ {
+ body = await request.Content!.ReadAsStringAsync();
+ return Json(HttpStatusCode.OK, """{"message":{"role":"assistant","content":"{}"}}""");
+ });
+ var client = new OllamaClient(new HttpClient(handler),
+ new OllamaSettings(new Uri("http://127.0.0.1:11434"), "test-model", "high", "0", new Dictionary<string, JsonElement>()));
+ using JsonDocument schema = JsonDocument.Parse("""{"type":"object"}""");
+
+ await client.ChatStructuredAsync([new OllamaMessage("user", "json")], null, schema.RootElement.Clone(), false,
+ TestContext.Current.CancellationToken);
+
+ using JsonDocument document = JsonDocument.Parse(body!);
+ Assert.False(document.RootElement.GetProperty("think").GetBoolean());
+ }
+
+ [Fact]
public async Task Transient_failure_retries_three_times_with_configured_backoff()
{
int attempts = 0;