Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hook #381

Merged
merged 15 commits into from
Apr 17, 2024
Merged

Hook #381

merged 15 commits into from
Apr 17, 2024

Conversation

sudoskys
Copy link
Member

@sudoskys sudoskys commented Apr 17, 2024

Summary by CodeRabbit

  • New Features

    • Added new login modes in the program, changing symbols for URL-based and non-URL logins.
    • Introduced simulation of realistic conversations in development notes.
    • Implemented a hook for rendering media data in messages.
    • Enhanced multimedia processing capabilities in the OpenAPI.
  • Bug Fixes

    • Refined command and trigger handling in Discord sender functions.
    • Improved task creation logic in Kook sender functions.
    • Adjusted control flow in Telegram sender functions based on commented code blocks.
  • Documentation

    • Added documentation for new chat simulation and media rendering hooks.
  • Chores

    • Updated license information and keywords in project configuration.
    • Excluded specific database file from version control.
  • Refactor

    • Enhanced readability and parameter handling in various sender functions across different platforms (Discord, Kook, Slack, Telegram).

- Add SystemMessage to messages list
- Fix indentation in check_stop function
- Update indentation in extract function
- Add SystemMessage to messages list
- Fix indentation in check_stop function
- Update indentation in extract function
- Add SystemMessage to messages list
- Fix indentation in check_stop function
- Update indentation in extract function
@sudoskys sudoskys added the New Features New feature or request label Apr 17, 2024
@sudoskys sudoskys linked an issue Apr 17, 2024 that may be closed by this pull request
@sudoskys sudoskys self-assigned this Apr 17, 2024
@sudoskys sudoskys marked this pull request as draft April 17, 2024 09:14
Copy link
Contributor

coderabbitai bot commented Apr 17, 2024

Walkthrough

This update encompasses a broad range of changes aimed at enhancing functionality, improving code structure, and expanding support for plugins and media handling. Key highlights include adjusting login symbols, refining command processing in messaging platforms like Discord, improving task creation logic in Kook, and introducing new documentation for realistic chat simulations and media processing hooks.

Changes

File Path Change Summary
.gitignore Added exclusion for /.tutorial.db.
README.md Updated login symbols from # to $.
app/sender/.../__init__.py (Discord, Kook, Slack, Telegram) Enhanced logic, added imports, and improved parameter handling across messaging platforms.
app/middleware/llm_task.py Updated method names, added new methods, and integrated TimeFeelManager for time-related message handling.
app/receiver/... (app.py, Discord, Kook, receiver_client, Slack, Telegram) Refactored message processing logic for bulk handling, hook integration, and improved error handling.
app/sender/... (schema.py, util_func.py) Revised method implementations for improved functionality and error handling.
docs/dev_note/... (chat_start.md, hook.md, time.md) Introduced new documentation files for chat simulation, plugin hooks, and time management concepts.
llmkira/extra/voice/__init__.py Added functions for voice synthesis using different APIs.
llmkira/extra/voice_hook.py Introduced functionality for text processing and voice response generation based on detected language.
llmkira/kv_manager/... (env.py, file.py, time.py) Renamed variables, added methods, and introduced time-related functionality.
llmkira/memory/redis_storage/__init__.py Updated clear method to be asynchronous for improved performance.
llmkira/openapi/... (hook/init.py, trigger/init.py) Added functionality for multimedia processing and updated trigger handling.
playground/hooks.py Introduced functionality for defining and running hooks using a custom system.
pyproject.toml License update to Apache-2.0, added dependency "fast-langdetect," and adjusted project metadata.

Possibly related issues

  • Plugin Hook #380: The changes in docs/dev_note/hook.md and llmkira/openapi/hook/__init__.py align with the objectives of implementing a new plugin hook system, as these modifications introduce a framework for extending application functionality via hooks.

Recent Review Details

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 32bfe8c and cd7a09d.
Files ignored due to path filters (1)
  • pdm.lock is excluded by !**/*.lock
Files selected for processing (25)
  • README.md (3 hunks)
  • app/middleware/llm_task.py (5 hunks)
  • app/receiver/app.py (1 hunks)
  • app/receiver/discord/init.py (2 hunks)
  • app/receiver/kook/init.py (1 hunks)
  • app/receiver/receiver_client.py (4 hunks)
  • app/receiver/slack/init.py (1 hunks)
  • app/receiver/telegram/init.py (2 hunks)
  • app/sender/discord/init.py (3 hunks)
  • app/sender/kook/init.py (3 hunks)
  • app/sender/schema.py (1 hunks)
  • app/sender/slack/init.py (5 hunks)
  • app/sender/telegram/init.py (7 hunks)
  • app/sender/util_func.py (1 hunks)
  • docs/dev_note/hook.md (1 hunks)
  • docs/dev_note/time.md (1 hunks)
  • llmkira/extra/voice/init.py (1 hunks)
  • llmkira/extra/voice_hook.py (1 hunks)
  • llmkira/kv_manager/env.py (4 hunks)
  • llmkira/kv_manager/file.py (1 hunks)
  • llmkira/kv_manager/time.py (1 hunks)
  • llmkira/memory/redis_storage/init.py (1 hunks)
  • llmkira/openapi/hook/init.py (1 hunks)
  • playground/hooks.py (1 hunks)
  • pyproject.toml (2 hunks)
Files skipped from review as they are similar to previous changes (7)
  • app/sender/discord/init.py
  • app/sender/kook/init.py
  • app/sender/slack/init.py
  • app/sender/telegram/init.py
  • docs/dev_note/hook.md
  • llmkira/openapi/hook/init.py
  • pyproject.toml
Additional comments not posted (30)
docs/dev_note/time.md (6)

7-9: Consider providing more detailed examples or pseudocode for how historical messages are discarded after a certain time period. This would help in understanding the practical implementation of the concept.


10-10: Clarify how the relevance between current and historical chats is determined. This is a critical aspect of the solution and merits a detailed explanation or reference to existing methodologies.


16-17: Ensure that the method for topic extraction is well-defined or referenced to external resources. This is crucial for understanding how similarity sorting is achieved.


21-21: Specify which tool or library is used by Toolcall for keyword matching. This will help in understanding the dependencies and the setup required for this solution.


25-25: The term "LLM结构化导出" (LLM structured export) is vague. Please provide a more detailed description or an example of how LLM is used to structure and retrieve themes.


29-29: Highlight the performance implications more prominently and consider suggesting optimizations or alternatives that could mitigate the performance overhead in real-time systems.

playground/hooks.py (4)

4-14: Ensure that the decorator @resign_hook() is correctly implemented and tested. It's not clear from the context what this decorator does, so additional documentation or comments would be beneficial.


8-10: The method trigger_hook in TestHook class should handle exceptions or errors that might occur during execution. Consider adding error handling to improve robustness.


12-14: In hook_run, ensure that the return type matches the expected output in all scenarios. Currently, it returns a tuple, but error cases are not handled.


31-39: The function run_test uses asynchronous calls but does not handle exceptions that might occur during run_hook. Add try-except blocks to handle potential errors gracefully.

app/sender/schema.py (1)

15-31: The hook method correctly uses asynchronous calls and awaits the results. However, consider adding error handling for the run_hook call to manage exceptions that might arise from external service failures or data issues.

app/receiver/app.py (1)

54-54: Verify that the newly imported module llmkira.extra.voice_hook is utilized within the file or its dependencies. If it's not used, consider removing the import to clean up the code.

llmkira/extra/voice_hook.py (1)

14-34: Ensure proper handling of edge cases in check_string.

Consider adding more detailed error messages or logging to help debug issues with text parsing and validation.

llmkira/extra/voice/__init__.py (2)

7-29: Improve error handling in request_cn_speech.

Add logging for different types of errors and consider retry mechanisms for transient network errors.


82-105: Enhance error handling and logging in request_en_speech.

Add detailed error messages and consider implementing a fallback mechanism for service failures.

llmkira/kv_manager/file.py (3)

49-55: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [52-87]

Refine error handling in upload_file method of File class.

Consider adding more specific error messages for different failure scenarios and implementing a retry mechanism for recoverable errors.


49-55: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [52-87]

Optimize upload_file method in FileHandler class for better performance.

Consider implementing asynchronous file reading and writing to improve performance and reduce the risk of blocking operations.


49-55: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [52-87]

Enhance download_file method in FileHandler class for reliability.

Add logging for download failures and consider implementing a cache validation mechanism to ensure data integrity.

app/receiver/slack/__init__.py (1)

94-117: Optimize forward method in SlackSender class for efficiency.

Consider batching file uploads and messages to reduce the number of API calls and improve performance.

app/receiver/kook/__init__.py (1)

121-139: Optimize forward method in KookSender class for efficiency.

Consider batching file uploads and messages to reduce the number of API calls and improve performance.

README.md (3)

78-80: Update documentation for clarity in login methods.

Consider adding examples or further explanations to clarify the new login command syntax for users.


177-187: Enhance documentation on hook support for better user understanding.

Add more detailed examples and use cases to help users understand how to implement and use hooks effectively.


51-62: Verify the accuracy of roadmap and feature descriptions in the documentation.

Ensure that all listed features and roadmap items are currently supported or planned, and update the documentation if any discrepancies are found.

app/receiver/telegram/__init__.py (1)

118-140: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [121-146]

Refactor file_forward method in TelegramSender class for better error handling.

Consider implementing more granular error handling for different types of Telegram API failures and adding retry mechanisms for recoverable errors.

app/middleware/llm_task.py (4)

126-134: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [129-150]

Renaming and modification of build_message to build_history_messages enhances clarity and functionality.


152-158: Consider removing redundant type annotations for message within the loop, as the type is clear from the context.


152-158: Addition of build_task_messages method improves modularity and separation of concerns.


198-221: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [183-214]

Integration of TimeFeelManager in request_openai method adds valuable time-related functionality.

app/receiver/receiver_client.py (2)

118-134: Modification of hook function signature and implementation aligns with PR objectives and improves functionality.


260-263: Updated error handling in _flash function provides clearer user feedback and error logging.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

and standalone support for Openai's new Schema.
and standalone support for Openai's new Schema.
- Added new hook system for triggering and running hooks
- Created TestHook and TestHook2 classes for testing
- Implemented run_hook function to execute hooks based on trigger
- Implement TimeFeelManager to calculate time differences and manage user feelings.
- Fix indentation in receiver/telegram/__init__.py file.
- Fix indentation in receiver/telegram/__init__.py file.
Hooks control the EventMessage in sender and receiver. For example, we have `voice_hook` in built-in hooks. you can enable it by setting `VOICE_REPLY_ME=true` in `.env`. /env VOICE_REPLY_ME=true /env REECHO_VOICE_KEY=<key in dev.reecho.ai> check the source code in `llmkira/extra/voice_hook.py`, learn to write your own hooks.
@sudoskys sudoskys marked this pull request as ready for review April 17, 2024 15:11
@sudoskys sudoskys merged commit c0b4510 into main Apr 17, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

time_feel = await TimeFeelManager(self.session_uid).get_leave()
if time_feel:
messages.append(
SystemMessage(content=f"statu:[After {time_feel} leave, user is back]")
Copy link
Contributor

Choose a reason for hiding this comment

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

Correct the typo in the SystemMessage content from "statu" to "status".

- statu:[After {time_feel} leave, user is back]
+ status:[After {time_feel} leave, user is back]

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
SystemMessage(content=f"statu:[After {time_feel} leave, user is back]")
SystemMessage(content=f"status:[After {time_feel} leave, user is back]")

Comment on lines +17 to +28
@resign_hook()
class TestHook2(Hook):
trigger: Trigger = Trigger.SENDER
priority: int = 1

async def trigger_hook(self, *args, **kwargs) -> bool:
print(f"Trigger {args} {kwargs}")
return True

async def hook_run(self, *args, **kwargs):
print(f"Running {args} {kwargs}")
return args, kwargs
Copy link
Contributor

Choose a reason for hiding this comment

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

The TestHook2 class is almost identical to TestHook. If the functionality is meant to be the same, consider refactoring to reduce code duplication by using inheritance or composition.

Comment on lines +41 to +50
async def trigger_hook(self, *args, **kwargs) -> bool:
platform_name: str = kwargs.get("platform") # noqa
messages: List[EventMessage] = kwargs.get("messages")
locate: Location = kwargs.get("locate")
for message in messages:
if not check_string(message.text):
return False
if await EnvManager(locate.uid).get_env("VOICE_REPLY_ME", None):
return True
return False
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor trigger_hook for clarity and efficiency.

Consider using a more efficient way to handle message processing, such as filtering messages before looping through them.

Comment on lines +52 to +87
async def hook_run(self, *args, **kwargs):
logger.debug(f"Voice Hook {args} {kwargs}")
platform_name: str = kwargs.get("platform") # noqa
messages: List[EventMessage] = kwargs.get("messages")
locate: Location = kwargs.get("locate")
for message in messages:
if not check_string(message.text):
return args, kwargs
parsed_text = parse_sentence(message.text)
if not parsed_text:
return args, kwargs
lang_kinds = []
for lang in parsed_text:
lang_kinds.append(lang.get("lang"))
reecho_api_key = await EnvManager(locate.uid).get_env(
"REECHO_VOICE_KEY", None
)
if (len(set(lang_kinds)) == 1) and (lang_kinds[0] in ["EN"]):
voice_data = await request_en_speech(message.text)
else:
voice_data = await request_reecho_speech(
message.text, reecho_api_key=reecho_api_key
)
if voice_data is not None:
ogg_data = Ffmpeg.convert(
input_c="mp3", output_c="ogg", stream_data=voice_data, quiet=True
)
file = await File.upload_file(
creator=locate.uid, file_name="speech.ogg", file_data=ogg_data
)
file.caption = message.text
message.text = ""
message.files.append(file)
else:
logger.error(f"Voice Generation Failed:{message.text}")
return args, kwargs
Copy link
Contributor

Choose a reason for hiding this comment

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

Optimize hook_run for better performance and error handling.

Consider implementing asynchronous processing of messages and adding more robust error handling for external service failures.

Comment on lines +50 to +79
async def request_reecho_speech(
text: str, reecho_api_key: str, voiceId="eb5d7f8c-eea1-483f-b718-1f28d6649339"
):
"""
Call the Reecho endpoint to generate synthesized voice.
:param text: The text to synthesize
:param voiceId: The voiceId to use
:param reecho_api_key: The Reecho API token
:return: The synthesized voice audio data, or None if the request failed
"""
if not reecho_api_key:
return await request_cn_speech(text)
url = "https://v1.reecho.ai/api/tts/simple-generate"
headers = {
"User-Agent": "Apifox/1.0.0 (https://apifox.com)",
"Content-Type": "application/json",
"Authorization": f"Bearer {reecho_api_key}", # Replace {token} with your Reecho API token
}
data = {"voiceId": voiceId, "text": text, "origin_audio": True}
async with aiohttp.ClientSession() as session:
async with session.post(
url, headers=headers, data=json.dumps(data)
) as response:
if response.status == 200:
response_json = await response.json()
audio_url = response_json["data"].get("audio", None)
audio_bytes = get_audio_bytes_from_data_url(audio_url)
if not audio_bytes:
return await request_cn_speech(text)
return audio_bytes
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor request_reecho_speech to simplify and enhance reliability.

Consider separating the concerns of fetching and processing audio data into different functions or classes to improve maintainability and testability.

Comment on lines +94 to +117
event_message = [
EventMessage.from_openai_message(message=item, locate=receiver)
for item in messages
]
# 转析器
_, event_message, receiver = await self.hook(
platform_name=__receiver__, messages=event_message, locate=receiver
)
event_message: list
for event in event_message:
await self.file_forward(receiver=receiver, file_list=event.files)
if not event.text:
continue
_message = (
ChatMessageCreator(
channel=receiver.chat_id, thread_ts=receiver.message_id
)
.update_content(message_text=event_message.text)
.get_message_payload(message_text=event_message.text)
.update_content(message_text=event.text)
.get_message_payload(message_text=event.text)
)
await self.bot.chat_postMessage(
channel=receiver.chat_id,
thread_ts=receiver.message_id,
text=event_message.text,
text=event.text,
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor file_forward method in SlackSender class for better error handling.

Consider implementing more granular error handling for different types of Slack API failures and adding retry mechanisms for recoverable errors.


Enhance reply method in SlackSender class for better modularity and testability.

Consider separating the message processing and sending functionalities into different methods or classes to improve modularity and make the code easier to test.

Comment on lines +121 to +139
event_message = [
EventMessage.from_openai_message(message=item, locate=receiver)
for item in messages
]
# 转析器
_, event_message, receiver = await self.hook(
platform_name=__receiver__, messages=event_message, locate=receiver
)
event_message: list
for event in event_message:
await self.file_forward(receiver=receiver, file_list=event.files)
if not event.text:
continue
await self.send_message(
channel_id=receiver.thread_id,
user_id=receiver.user_id,
dm=receiver.thread_id == receiver.chat_id,
message_type=MessageTypes.KMD,
content=event_message.text,
content=event.text,
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor file_forward method in KookSender class for better error handling.

Consider implementing more granular error handling for different types of Kook API failures and adding retry mechanisms for recoverable errors.


Enhance reply method in KookSender class for better modularity and testability.

Consider separating the message processing and sending functionalities into different methods or classes to improve modularity and make the code easier to test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Features New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Plugin Hook
1 participant