Skip to content

fix(platform): use full_name instead of username for Telegram user nickname (#6657)#6693

Open
Yaohua-Leo wants to merge 4 commits intoAstrBotDevs:masterfrom
Yaohua-Leo:fix/6657-telegram-user-nickname
Open

fix(platform): use full_name instead of username for Telegram user nickname (#6657)#6693
Yaohua-Leo wants to merge 4 commits intoAstrBotDevs:masterfrom
Yaohua-Leo:fix/6657-telegram-user-nickname

Conversation

@Yaohua-Leo
Copy link
Copy Markdown
Contributor

@Yaohua-Leo Yaohua-Leo commented Mar 20, 2026

Summary

Fix #6657 - Telegram 暱稱與用戶 ID 問題

Problem

Previously, Telegram adapter used the username as the user's nickname for plugins. This caused:

  1. Plugins matching users by username instead of numeric ID
  2. Users being addressed by their username instead of their actual display name

Solution

Changed the nickname priority order to use the actual display name:

full_name > first_name > username > Unknown

Changes

Modified tg_adapter.py:

# Before:
message.sender = MessageMember(
    str(_from_user.id),
    _from_user.username or "Unknown",
)

# After:
message.sender = MessageMember(
    str(_from_user.id),
    _from_user.full_name or _from_user.first_name or _from_user.username or "Unknown",
)

Testing

The fix maintains backward compatibility by falling back to username if full_name is not available.

Summary by Sourcery

Align Telegram user nickname handling and strengthen tool call streaming compatibility in the OpenAI provider.

Bug Fixes:

  • Use Telegram user's full display name (falling back to first_name, then username, then a default) as the message sender nickname instead of always using username.
  • Ensure streamed tool call deltas from OpenAI-compatible backends always include an index field by assigning one when it is missing.

Yaohua-Leo added 3 commits March 20, 2026 18:19
- Fix AstrBotDevs#6661: Streaming tool_call arguments lost when OpenAI-compatible proxy omits index field
- Gemini and some proxies (e.g. Continue) don't include index field in tool_call deltas
- Add default index=0 when missing to prevent ChatCompletionStreamState.handle_chunk() from rejecting chunks

Fixes AstrBotDevs#6661
- Use enumerate() to assign correct index based on list position
- Iterate over all choices (not just the first) for completeness
- Addresses review feedback from sourcery-ai and gemini-code-assist
…ckname

Fix AstrBotDevs#6657 - Telegram 暱稱與用戶 ID 問題

Previously, plugins used the Telegram username as the user's nickname,
which was inconsistent with the actual display name. Now uses the
priority order: full_name > first_name > username > Unknown

This ensures plugins can properly match users by their numeric ID
instead of relying on username, and the agent can address users by
their actual display name.
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Mar 20, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses two distinct issues: incorrect user nickname resolution in the Telegram adapter and a missing index field in OpenAI tool call deltas. The Telegram change ensures that user display names are prioritized for nicknames, improving user identification for plugins. The OpenAI fix enhances compatibility with various API providers by explicitly adding a crucial field for tool call processing.

Highlights

  • Telegram User Nickname Logic: Modified the Telegram adapter to prioritize full_name and first_name over username when determining a user's nickname, addressing issues where plugins incorrectly matched users by username instead of their actual display name.
  • OpenAI Tool Call Index Fix: Implemented a fix in the OpenAI source to add a missing index field to tool_call deltas, specifically for cases where Gemini and some OpenAI-compatible proxies omit this field, ensuring proper handling of tool calls.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • This PR mixes two unrelated fixes (Telegram nickname change and tool_call index patch for #6661); consider splitting them into separate PRs or at least updating the title/description to reflect both changes clearly.
  • In the stream tool_call index patch, you only add an index when it is missing or None; if the upstream returns incorrect indices, they will silently pass through—if that's a realistic failure mode for those proxies, you may want to normalize indices based on enumeration regardless of existing values.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- This PR mixes two unrelated fixes (Telegram nickname change and tool_call index patch for #6661); consider splitting them into separate PRs or at least updating the title/description to reflect both changes clearly.
- In the stream tool_call index patch, you only add an index when it is missing or None; if the upstream returns incorrect indices, they will silently pass through—if that's a realistic failure mode for those proxies, you may want to normalize indices based on enumeration regardless of existing values.

## Individual Comments

### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="310-317" />
<code_context>
         state = ChatCompletionStreamState()

         async for chunk in stream:
+            # Fix for #6661: Add missing 'index' field to tool_call deltas
+            # Gemini and some OpenAI-compatible proxies omit this field
+            if chunk.choices:
+                for choice in chunk.choices:
+                    if choice.delta and choice.delta.tool_calls:
+                        for idx, tc in enumerate(choice.delta.tool_calls):
+                            if not hasattr(tc, "index") or tc.index is None:
+                                tc.index = idx
             try:
                 state.handle_chunk(chunk)
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider moving the tool_call index-normalization inside the existing try/except block

The new normalization logic can raise AttributeError/TypeError (e.g., unexpected `choice` shape or non-iterable `tool_calls`) before we reach `state.handle_chunk(chunk)`, so those errors won’t be caught by the existing `try/except` and will now abort `_query_stream`. To keep behavior closer to before and be more robust to provider-specific schema quirks, consider either moving this entire `if chunk.choices:` block inside the current `try` or wrapping the normalization in its own narrow `try/except` that logs and skips malformed chunks rather than failing the whole stream.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +310 to +317
# Fix for #6661: Add missing 'index' field to tool_call deltas
# Gemini and some OpenAI-compatible proxies omit this field
if chunk.choices:
for choice in chunk.choices:
if choice.delta and choice.delta.tool_calls:
for idx, tc in enumerate(choice.delta.tool_calls):
if not hasattr(tc, "index") or tc.index is None:
tc.index = idx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Consider moving the tool_call index-normalization inside the existing try/except block

The new normalization logic can raise AttributeError/TypeError (e.g., unexpected choice shape or non-iterable tool_calls) before we reach state.handle_chunk(chunk), so those errors won’t be caught by the existing try/except and will now abort _query_stream. To keep behavior closer to before and be more robust to provider-specific schema quirks, consider either moving this entire if chunk.choices: block inside the current try or wrapping the normalization in its own narrow try/except that logs and skips malformed chunks rather than failing the whole stream.

@dosubot dosubot bot added the area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. label Mar 20, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces two fixes. First, it correctly prioritizes the Telegram user's full_name and first_name for the sender's nickname, falling back to username. This is a good improvement for user experience. Second, it adds a compatibility layer for OpenAI-compatible streaming providers by ensuring the index field is present in tool call deltas, which is a necessary fix for handling responses from providers like Gemini. The changes are logical and well-implemented. I've added one suggestion to refactor the new code in openai_source.py for better readability.

Comment on lines +312 to +317
if chunk.choices:
for choice in chunk.choices:
if choice.delta and choice.delta.tool_calls:
for idx, tc in enumerate(choice.delta.tool_calls):
if not hasattr(tc, "index") or tc.index is None:
tc.index = idx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic to patch the index field is correct. However, the nested structure can be simplified to improve readability and reduce nesting. Using or [] for potentially missing chunk.choices and a guard clause for tool_calls can make the code flatter and easier to follow.

Suggested change
if chunk.choices:
for choice in chunk.choices:
if choice.delta and choice.delta.tool_calls:
for idx, tc in enumerate(choice.delta.tool_calls):
if not hasattr(tc, "index") or tc.index is None:
tc.index = idx
for choice in chunk.choices or []:
if not (choice.delta and choice.delta.tool_calls):
continue
for idx, tc in enumerate(choice.delta.tool_calls):
if getattr(tc, "index", None) is None:
tc.index = idx

Addresses review feedback from sourcery-ai to ensure robustness
against provider-specific schema quirks during streaming.
@Yaohua-Leo
Copy link
Copy Markdown
Contributor Author

Addressed review feedback: wrapped tool_call index normalization in the try/except block to ensure robustness against provider-specific schema quirks during streaming.

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Mar 20, 2026
@Soulter Soulter force-pushed the master branch 2 times, most recently from faf411f to 0068960 Compare April 19, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Telegram 暱稱與用戶 ID 問題

1 participant