Skip to content

feat: add --sender parameter to chat commands#562

Merged
qin-ctx merged 9 commits intomainfrom
feat/bot_add_sender
Mar 13, 2026
Merged

feat: add --sender parameter to chat commands#562
qin-ctx merged 9 commits intomainfrom
feat/bot_add_sender

Conversation

@chenjw
Copy link
Collaborator

@chenjw chenjw commented Mar 12, 2026

  • Add --sender option to Python CLI chat command
  • Add --sender option to Rust CLI chat command
  • Pass sender ID through to channels
  • Display sender in interactive mode header
  • Update langfuse integration for compatibility

Description

Related Issue

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Notes

- Add --sender option to Python CLI chat command
- Add --sender option to Rust CLI chat command
- Pass sender ID through to channels
- Display sender in interactive mode header
- Update langfuse integration for compatibility
@github-actions
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Type Mismatch Bug

The --sender option is annotated as str but has a default value of None, causing a type mismatch. This will result in type checking errors and potential runtime issues.

sender: str = typer.Option(
    None, "--sender", help="Sender ID, same usage as feishu channel sender"
)
Inconsistent Fallback

The fallback sender_id values are inconsistent between ChatChannel ("user") and SingleTurnChannel ("default"). Unifying these would improve consistency.

sender_id = self.sender or "user"
Code Duplication

The litellm_provider now directly calls langfuse client methods instead of using the existing langfuse.generation() context manager, leading to duplicated logic. Consider using the context manager for consistency.

# Langfuse integration
# Note: session_id is set via propagate_attributes in loop.py, not here
langfuse_observation = None
try:
    if self.langfuse.enabled and self.langfuse._client:
        metadata = {"has_tools": tools is not None}
        client = self.langfuse._client
        # Use start_observation with generation type
        if hasattr(client, "start_observation"):
            langfuse_observation = client.start_observation(
                name="llm-chat",
                as_type="generation",
                model=model,
                input=messages,
                metadata=metadata,
            )

    response = await acompletion(**kwargs)
    llm_response = self._parse_response(response)

    # Update and end Langfuse observation
    if langfuse_observation:
        output_text = llm_response.content or ""
        if llm_response.tool_calls:
            output_text = (
                output_text
                or f"[Tool calls: {[tc.name for tc in llm_response.tool_calls]}]"
            )

        # Update observation with output and usage
        update_kwargs: dict[str, Any] = {
            "output": output_text,
            "metadata": {"finish_reason": llm_response.finish_reason},
        }

        if llm_response.usage:
            # Add usage data using usage_details format
            usage_details: dict[str, Any] = {
                "input": llm_response.usage.get("prompt_tokens", 0),
                "output": llm_response.usage.get("completion_tokens", 0),
            }

            # Add cache read tokens if available
            cache_read_tokens = llm_response.usage.get(
                "cache_read_input_tokens"
            ) or llm_response.usage.get("prompt_tokens_details", {}).get("cached_tokens")
            if cache_read_tokens:
                usage_details["cache_read_input_tokens"] = cache_read_tokens

            update_kwargs["usage_details"] = usage_details

        # Update the observation
        if hasattr(langfuse_observation, "update"):
            try:
                langfuse_observation.update(**update_kwargs)
            except Exception as e:
                logger.debug(f"[LANGFUSE] Failed to update observation: {e}")

        # End the observation
        if hasattr(langfuse_observation, "end"):
            try:
                langfuse_observation.end()
            except Exception as e:
                logger.debug(f"[LANGFUSE] Failed to end observation: {e}")

        self.langfuse.flush()

    return llm_response
except Exception as e:
    # End Langfuse observation with error
    if langfuse_observation:
        try:
            if hasattr(langfuse_observation, "update"):
                langfuse_observation.update(
                    output=f"Error: {str(e)}",
                    metadata={"error": str(e)},
                )
            if hasattr(langfuse_observation, "end"):
                langfuse_observation.end()
            self.langfuse.flush()
        except Exception:
            pass

@github-actions
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Align default sender ID to "user"

The default sender ID in SingleTurnChannel is "default", which is inconsistent with
ChatChannel's default of "user". This could lead to inconsistent sender
identification across interactive and single-turn chat modes. Let's align the
default to "user" for consistency.

bot/vikingbot/channels/single_turn.py [64]

 async def start(self) -> None:
     """Start the single-turn channel - send message and wait for response."""
     self._running = True
 
     # Send the message
-    sender_id = self.sender or "default"
+    sender_id = self.sender or "user"
     msg = InboundMessage(
Suggestion importance[1-10]: 5

__

Why: Aligning the default sender ID between SingleTurnChannel and ChatChannel improves consistency across chat modes. This is a minor quality improvement with no critical impact.

Low

Align default sender ID in SingleTurnChannel from "default" to "user" to
match ChatChannel's default, ensuring consistent sender identification
across interactive and single-turn chat modes.
@chenjw chenjw requested review from MaojiaSheng and qin-ctx March 13, 2026 02:49
chenjw added 6 commits March 13, 2026 11:25
Change Rust CLI's default sender from "cli_user" to "user" to match
Python side (ChatChannel and SingleTurnChannel), ensuring consistent
default sender identification across both Rust and Python CLI tools.
When converting from old usage format (prompt_tokens/completion_tokens/total_tokens)
to usage_details format, also pass through total_tokens as 'total' field if
it's available in the usage dict.
Wrap self.langfuse.flush() calls in try/except blocks to prevent
flush failures from discarding successfully obtained LLM responses.

- In success path: flush() failure only logs debug message
- In error path: flush() failure silently ignored (already in error handling)
Temporarily disable langfuse propagate_attributes context manager to fix
RuntimeError: generator didn't stop after throw(). The context manager
had exception handling issues when exceptions were thrown inside the block.

This preserves the API while avoiding the runtime error.
…or error

Reimplement propagate_attributes with manual __enter__/__exit__ management to
avoid the 'generator didn't stop after throw()' error. Key changes:

- Use local variable to avoid name shadowing with the method
- Only catch exceptions when entering the context manager
- Let inner block exceptions propagate normally
- Always exit the context manager in finally block
- Restore session_id/user_id propagation to langfuse
@qin-ctx qin-ctx merged commit 4cf6888 into main Mar 13, 2026
11 of 12 checks passed
@qin-ctx qin-ctx deleted the feat/bot_add_sender branch March 13, 2026 06:02
@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenViking project Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants