Skip to content

fix: resolve empty response display and streaming errors#136

Open
jalen0x wants to merge 2 commits intoRichardAtCT:mainfrom
jalen0x:fix/no-content-display
Open

fix: resolve empty response display and streaming errors#136
jalen0x wants to merge 2 commits intoRichardAtCT:mainfrom
jalen0x:fix/no-content-display

Conversation

@jalen0x
Copy link

@jalen0x jalen0x commented Mar 7, 2026

Summary

Fixes three related bugs that cause (No content to display) in Telegram responses when Claude performs tool-heavy operations.

Changes

1. Add helper methods to StreamUpdate dataclass (sdk_integration.py)

The message handler calls get_tool_names(), is_error(), get_error_message(), and get_progress_percentage() on StreamUpdate objects, but these methods did not exist. Added all four methods plus a progress attribute.

2. Fix ConversationEnhancer call signatures (message.py)

The caller was passing wrong arguments to update_context(), should_show_suggestions(), and generate_follow_up_suggestions(). Aligned all calls to match the actual method signatures in conversation_mode.py.

3. Generate tool summary for empty responses (sdk_integration.py)

When Claude's response is purely tool operations (file edits, bash commands) with no conversational text, content was empty. Now generates a fallback: ✅ Task completed. Tools used: Edit, Bash, ...

Testing

  • python -m compileall -q src passes
  • Only 2 files modified, 121 additions, 15 deletions

Fixes #135

- Add helper methods to StreamUpdate dataclass for progress display
- Fix ConversationEnhancer.update_context() call signature
- Generate tool summary when response content is empty

Fixes RichardAtCT#135
@FridayOpenClawBot
Copy link

This fixes the three root causes from #135 correctly — the missing StreamUpdate methods, wrong ConversationEnhancer call signatures, and empty content when Claude only uses tools. The approach is sound.

Issues to address before merging:

StreamUpdate is a dataclass with instance methods — this works but is unusual for a data-transfer object. If StreamUpdate is used across multiple call sites or serialised/deserialised, the methods travel with it fine, but consider whether conversation_mode.py should own the logic for interpreting ClaudeResponse rather than StreamUpdate owning logic about itself. Not a blocker, just worth flagging.

is_error() false-positive risk — this check:

if self.metadata.get("error") or self.metadata.get("error_message"):
    return True

will return True if either key exists with any truthy value, including a dict {} or int 0-adjacent truthy values. If the SDK ever includes an "error": null or "error": {} in normal metadata, this won't trigger (falsy), but "error": "none" would. Low risk in practice but worth a type guard: isinstance(self.metadata.get("error"), str).

Tool summary fallback is user-facing with no i18n hook"✅ Task completed. Tools used: {tools_summary}" is hardcoded English. Fine for now, but if localisation is ever added, this will be a find-and-replace problem. A constant would be cleaner.

get_or_create_context(user_id) return type — the diff shows conversation_context is now assigned from get_or_create_context() rather than the return value of update_context(). Verify that get_or_create_context() returns the same context type that generate_follow_up_suggestions() expects — if the type changed, mypy strict mode should catch it, but worth a manual check if CI isn't running mypy on this path.

Positive: The _to_int helper in get_progress_percentage() is well-written — handles int, float, and str gracefully with proper clamping. The deduplication via dict.fromkeys() is clean throughout. The str(result_content).strip() fix is minimal and correct.

Overall this is a legitimate bug fix. Address the is_error() type guard and verify the context type alignment, then it's good to go.

Friday, AI assistant to @RichardAtCT

- is_error(): use isinstance() type guards to prevent false positives
  from non-string truthy values like {} or 0
- Extract hardcoded task-completed string as TASK_COMPLETED_MSG constant
  for future i18n
- Verified get_or_create_context/generate_follow_up_suggestions type
  compatibility (ConversationContext matches, no change needed)
@FridayOpenClawBot
Copy link

PR Review
Reviewed head: de1550b236eec8d57bffcfa3d37a6618a056e8cf

Summary

  • Added isinstance(str) type guards to is_error() for both error and error_message metadata fields
  • Extracted hardcoded fallback string as TASK_COMPLETED_MSG module-level constant

What looks good

  • Type guards correctly fix the false-positive risk — {}, 0, [] etc. no longer trigger is_error(). The two-variable split is clear and readable.
  • TASK_COMPLETED_MSG placement at module level with a descriptive comment is clean. Using .format() at the call site keeps the constant itself a simple template string.
  • Commit message explicitly calls out the type compatibility verification for get_or_create_context / generate_follow_up_suggestions — good discipline even if no code change was needed.

Issues / questions
None. Both pieces of feedback addressed correctly.

Verdict

  • ✅ Ready to merge

Friday, AI assistant to @RichardAtCT

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.

Bug: "No content to display" after Claude completes tasks (SDK compatibility issues in v1.5.0)

2 participants