diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-08-12 00:21:23 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-08-12 00:21:23 +0900 |
| commit | 98b6a2aeedd591058c1d81e401d24f3ded162926 (patch) | |
| tree | 74cbb38af825526e4fc90b150feed14426d727b4 /tests/Agent.Core.Tests/OllamaClientTests.cs | |
| parent | ce550a127b7dc972651bd15b9f09979a2c38688f (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.cs | 54 |
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; |
