-
Notifications
You must be signed in to change notification settings - Fork 227
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
Conversation
- 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
WalkthroughThis 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
Possibly related issues
Recent Review DetailsConfiguration used: CodeRabbit UI Files ignored due to path filters (1)
Files selected for processing (25)
Files skipped from review as they are similar to previous changes (7)
Additional comments not posted (30)
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Additionally, you can add CodeRabbit Configration File (
|
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.
There was a problem hiding this 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]") |
There was a problem hiding this comment.
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.
SystemMessage(content=f"statu:[After {time_feel} leave, user is back]") | |
SystemMessage(content=f"status:[After {time_feel} leave, user is back]") |
@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 |
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
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.
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, |
There was a problem hiding this comment.
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.
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, |
There was a problem hiding this comment.
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.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores
Refactor