Skip to content

Preserve DeepSeek empty reasoning content#352

Merged
ModerRAS merged 4 commits into
masterfrom
codex/add-llm-trace-logging-and-fix-empty-encoded-value
May 13, 2026
Merged

Preserve DeepSeek empty reasoning content#352
ModerRAS merged 4 commits into
masterfrom
codex/add-llm-trace-logging-and-fix-empty-encoded-value

Conversation

@ModerRAS
Copy link
Copy Markdown
Owner

@ModerRAS ModerRAS commented May 13, 2026

Keep DeepSeek reasoning_content round-tripped even when it is an empty string, while avoiding empty reasoning patches for other providers that trigger OpenAI SDK serialization failures. Adds provider-aware gating, preserves empty reasoning in snapshot serialization, and covers the behavior with regression tests.

Summary by CodeRabbit

  • New Features

    • Added configurable logging level in Config.json supporting Verbose, Debug, Information, Warning, Error, and Fatal (default: Verbose)
    • Enhanced error reporting with structured error messages across LLM and tool execution services
  • Documentation

    • Updated build guide with simplified local debugging instructions
    • Added LogLevel configuration examples to README with supported values

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR implements comprehensive structured logging improvements with configurable log levels, exception handling utilities, reasoning-content support for thinking-mode models (DeepSeek), enhanced tool-execution diagnostics across LLM and agent services, and draft ID generation refinements. Core changes include a new ExceptionExtensions class, Env-level log-level configuration, widespread application of structured error logging, and support for preserving empty reasoning content in conversation snapshots.

Changes

Logging Infrastructure & Exception Handling

Layer / File(s) Summary
Logging Configuration & Exception Utilities Foundation
TelegramSearchBot.Common/Env.cs, TelegramSearchBot.Common/ExceptionExtensions.cs
Adds Config.LogLevel property (default "Verbose"), Env.SerilogMinimumLevel static field, ResolveSerilogMinimumLevel parser (validates string to LogEventLevel); introduces ExceptionExtensions with GetPrimaryException (unwraps nested TargetInvocationException/AggregateException) and GetLogSummary (formats type name + message).
Program Logger Configuration & Tests
TelegramSearchBot/Program.cs, TelegramSearchBot.Test/Common/EnvBotApiEndpointTests.cs
Updates Program.Main Serilog configuration to use Env.SerilogMinimumLevel for global and per-sink (console/file/OpenTelemetry) minimum levels; reworks OpenTelemetry sink to explicit fluent parameter setup. Adds parameterized test methods validating log-level parsing and Verbose fallback for invalid inputs.
Bootstrap Startup Error Logging
TelegramSearchBot/AppBootstrap/AppBootstrap.cs
Updates TryDispatchStartupByReflection and PrintUsageHint exception handlers to use Log.Error(exception, ...) with structured context instead of embedding exception messages, providing consistent diagnostics during startup.

Reasoning Content for Thinking-Mode Models (DeepSeek)

Layer / File(s) Summary
Reasoning Content Schema & Documentation
TelegramSearchBot.Common/Model/AI/LlmContinuationSnapshot.cs
Updates SerializedChatMessage.ReasoningContent documentation to clarify that reasoning content returned by the provider should be preserved when resuming conversation state for thinking-mode models.
OpenAI Reasoning Content & Argument Sanitization
TelegramSearchBot.LLM/Service/AI/LLM/OpenAIService.cs
Introduces SanitizeAndTruncateArguments helper (redacts sensitive JSON keys like api\_key/token/password, escapes newlines, truncates). Adds ShouldIncludeEmptyReasoningContent detection (returns true for DeepSeek gateway/models). Enhances GetAssistantReasoningContent with Patch-based $.reasoning_content extraction. Extends DeserializeProviderHistory to accept includeEmptyReasoningContent flag. Updates SetAssistantReasoningContent to conditionally preserve empty reasoning.
OpenAI Responses Service Tool Call & Function Normalization
TelegramSearchBot.LLM/Service/AI/LLM/OpenAIResponsesService.cs
Normalizes function-call metadata (id/name/arguments JSON) with debug logging during main and resume paths. Enriches tool-execution error logging with call id, arguments, and error summary. Adds lastResolvedCallId tracking in snapshot deserialization to fill missing output call ids. Parses both __FUNC_CALL__ and __FUNC_OUTPUT__ markers with normalized metadata during resume.
Reasoning Content Test Coverage
TelegramSearchBot.LLM.Test/Service/AI/LLM/OpenAIProviderHistorySerializationTests.cs
Replaces null-reasoning test with DeserializeProviderHistory_WithNullReasoningContent_Succeeds. Adds parameterized tests for ShouldIncludeEmptyReasoningContent (DeepSeek true, MiniMax false). Introduces async test for DeepSeek empty-reasoning serialization into OpenAI request. Adds CapturingHandler to validate request bodies.

Structured Logging Across LLM and Agent Services

Layer / File(s) Summary
LLM Service Tool Execution Error Logging
TelegramSearchBot.LLM/Service/AI/LLM/AnthropicService.cs, TelegramSearchBot.LLM/Service/AI/LLM/GeminiService.cs, TelegramSearchBot.LLM/Service/AI/LLM/OllamaService.cs, TelegramSearchBot.LLM/Service/AI/LLM/OpenAIService.cs
Updates AnthropicService native and XML tool-call error handling to log with tool identifiers and GetLogSummary, wrapping JSON deserialization in try/catch with empty-dict fallback. Updates GeminiService, OllamaService, and OpenAIService tool-execution catch blocks to log structured error context (tool name, arguments, error summary) and return error messages based on GetLogSummary.
LLM Controller Agent Failure Logging
TelegramSearchBot/Controller/AI/LLM/GeneralLLMController.cs, TelegramSearchBot/Controller/AI/LLM/LLMIterationCallbackController.cs
Adds structured error logging to GeneralLLMController.ExecuteAsync and LLMIterationCallbackController.HandleContinue when AI agent task completes with AgentChunkType.Error, recording ChatId, MessageId/SnapshotId, and ErrorMessage.
Polling Service & Remote Tool Execution Logging
TelegramSearchBot/Service/AI/LLM/ChunkPollingService.cs, TelegramSearchBot.LLMAgent/Service/ToolExecutor.cs
Adds optional ILogger<T> injection (defaulting to NullLogger) to ChunkPollingService and ToolExecutor. Wraps per-task polling in try/catch with RedisException vs general exception distinction. Enhances ToolExecutor.ExecuteRemoteToolAsync with logging at queueing, wait-error, timeout, failure, and completion phases.
Telegram Task Consumer Tool Execution Logging
TelegramSearchBot/Service/AI/LLM/TelegramTaskConsumer.cs
Adds structured logging for tool execution start (request/tool/chat/user/message ids, argument keys), tool result persistence (success/length/error context), and explicit completion logs for send_message and generic tool tasks (request ID, tool name, result length).
Agent Loop Retry & Failure Diagnostics
TelegramSearchBot.LLMAgent/Service/AgentLoopService.cs
Enriches transient-retry handling with computed retryReason and structured persistence of lastRetryReason/lastRetryDetails/lastRetryExceptionType. Updates terminal-failure path to compute errorSummary and persist errorType/errorDetails.
LLM Agent Program Tool Loading & Registration Logging
TelegramSearchBot.LLMAgent/LLMAgentProgram.cs
Adds debug logging for Redis tool-definition loading (payload bytes). Enhances proxy tool invocation routing with informational logging and wraps remote execution in try/catch for error logging with ErrorSummary. Logs import summary with truncated tool names. Sets logger minimum level to Trace in BuildServices.

MCP Tool Execution and Registration Logging

Layer / File(s) Summary
MCP Tool Execution with Timing and Argument Sanitization
TelegramSearchBot.LLM/Service/AI/LLM/McpToolHelper.cs
Updates ExecuteRegisteredToolAsync with Stopwatch timing. Adds enriched structured logging for tool routing (chat/user/message ids, argument keys, truncated payloads with max-length constants). Implements null-safe argument trimming and CDATA marker regex stripping. Maintains enhanced pre/post logging across proxy, external, and local tool paths.
External MCP & Proxy Tool Registration with Redis Refresh Logging
TelegramSearchBot.LLM/Service/AI/LLM/McpToolHelper.cs
Enhances ExecuteExternalToolAsync with metadata logging using argument formatting/truncation helpers. Adds logging when RegisterExternalMcpTools clears stale registry. Adds RefreshAgentToolDefsInRedisAsync logging with tool count and names. Updates RegisterProxyTools to track skipped-local count and emit detailed registration summary (up to 80 tool names).

Draft Message Helpers and Documentation Updates

Layer / File(s) Summary
Draft ID Generation & Content Preview Helpers
TelegramSearchBot/Service/BotAPI/SendMessageService.Streaming.cs
Replaces tick-based XOR draft-id expression with CreateDraftId helper (mixes chatId/replyTo/time/GUID with non-zero fallback). Adds GetContentPreview for normalized/truncated content summaries. Enriches SendDraftStream with structured start/debug/error logging including draft ID and content previews.
Documentation & Configuration Updates
Docs/Build_and_Test_Guide.md, README.md
Updates build guide to replace command-line log-level flag examples with Config.json LogLevel default documentation. Adds LogLevel property to README.md config example with supported Serilog levels and defaults.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • ModerRAS/TelegramSearchBot#351: Adds the same ExceptionExtensions with GetLogSummary() and applies it across LLM services and agent paths for diagnostics-focused enhancements.
  • ModerRAS/TelegramSearchBot#333: Both PRs advance reasoning-content handling for thinking-mode models, adding Patch-based extraction and DeserializeProviderHistory/SetAssistantReasoningContent logic for DeepSeek empty-reasoning preservation.
  • ModerRAS/TelegramSearchBot#343: Both PRs modify OpenAIResponsesService tool-call and snapshot handling, with the retrieved PR wiring the service initially and the main PR enhancing its error logging and function-call normalization.

Poem

🐰 Logs now flow with crystal clarity,
Exceptions unwrapped, no mystery!
DeepSeek's thoughts preserved with care,
Structured trails of debug everywhere. ✨📋

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Preserve DeepSeek empty reasoning content' accurately reflects the main objective: enabling DeepSeek provider reasoning_content values (especially empty strings) to be preserved during serialization round-trips.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/add-llm-trace-logging-and-fix-empty-encoded-value

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

PR Check Report

Summary

Test Results

Platform Status Details
Ubuntu Passed Tests passed, artifacts uploaded
Windows Passed Tests passed, artifacts uploaded

Code Quality

  • Code formatting check
  • Security vulnerability scan
  • Dependency analysis
  • Code coverage collection

Test Artifacts

  • Test results artifacts count: 2
  • Code coverage uploaded to Codecov

Links


This report is auto-generated by GitHub Actions

@ModerRAS ModerRAS merged commit 27617c0 into master May 13, 2026
4 of 5 checks passed
@ModerRAS ModerRAS deleted the codex/add-llm-trace-logging-and-fix-empty-encoded-value branch May 13, 2026 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant