| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | from core.model_runtime.entities.llm_entities import LLMResult | 
					
						
							| 
									
										
										
										
											2024-02-01 18:11:57 +08:00
										 |  |  | from core.model_runtime.entities.message_entities import PromptMessage, SystemPromptMessage, UserPromptMessage | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from core.tools.__base.tool import Tool | 
					
						
							|  |  |  | from core.tools.__base.tool_runtime import ToolRuntime | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | from core.tools.entities.tool_entities import ToolProviderType | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | from core.tools.utils.model_invocation_utils import ModelInvocationUtils | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | _SUMMARY_PROMPT = """You are a professional language researcher, you are interested in the language
 | 
					
						
							| 
									
										
										
										
											2025-04-29 18:04:33 +08:00
										 |  |  | and you can quickly aimed at the main point of an webpage and reproduce it in your own words but | 
					
						
							|  |  |  | retain the original meaning and keep the key points. | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | however, the text you got is too long, what you got is possible a part of the text. | 
					
						
							|  |  |  | Please summarize the text you got. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BuiltinTool(Tool): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     Builtin tool | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     :param meta: the meta data of a tool call processing | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     provider: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, provider: str, **kwargs): | 
					
						
							|  |  |  |         super().__init__(**kwargs) | 
					
						
							|  |  |  |         self.provider = provider | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fork_tool_runtime(self, runtime: ToolRuntime) -> "BuiltinTool": | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-03-31 13:19:15 +08:00
										 |  |  |         fork a new tool with metadata | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         :return: the new tool | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         return self.__class__( | 
					
						
							|  |  |  |             entity=self.entity.model_copy(), | 
					
						
							|  |  |  |             runtime=runtime, | 
					
						
							|  |  |  |             provider=self.provider, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     def invoke_model(self, user_id: str, prompt_messages: list[PromptMessage], stop: list[str]) -> LLMResult: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         invoke model | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-31 13:19:15 +08:00
										 |  |  |         :param user_id: the user id | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param prompt_messages: the prompt messages | 
					
						
							|  |  |  |         :param stop: the stop words | 
					
						
							|  |  |  |         :return: the model result | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         # invoke model | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         return ModelInvocationUtils.invoke( | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             user_id=user_id, | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |             tenant_id=self.runtime.tenant_id or "", | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             tool_type="builtin", | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             tool_name=self.entity.identity.name, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             prompt_messages=prompt_messages, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     def tool_provider_type(self) -> ToolProviderType: | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         return ToolProviderType.BUILT_IN | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |     def get_max_tokens(self) -> int: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get max tokens | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the max tokens | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         if self.runtime is None: | 
					
						
							|  |  |  |             raise ValueError("runtime is required") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         return ModelInvocationUtils.get_max_llm_context_tokens( | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |             tenant_id=self.runtime.tenant_id or "", | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 15:21:33 +08:00
										 |  |  |     def get_prompt_tokens(self, prompt_messages: list[PromptMessage]) -> int: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get prompt tokens | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param prompt_messages: the prompt messages | 
					
						
							|  |  |  |         :return: the tokens | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         if self.runtime is None: | 
					
						
							|  |  |  |             raise ValueError("runtime is required") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ModelInvocationUtils.calculate_tokens( | 
					
						
							|  |  |  |             tenant_id=self.runtime.tenant_id or "", prompt_messages=prompt_messages | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-17 10:04:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |     def summary(self, user_id: str, content: str) -> str: | 
					
						
							|  |  |  |         max_tokens = self.get_max_tokens() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         if self.get_prompt_tokens(prompt_messages=[UserPromptMessage(content=content)]) < max_tokens * 0.6: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             return content | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         def get_prompt_tokens(content: str) -> int: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             return self.get_prompt_tokens( | 
					
						
							|  |  |  |                 prompt_messages=[SystemPromptMessage(content=_SUMMARY_PROMPT), UserPromptMessage(content=content)] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         def summarize(content: str) -> str: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             summary = self.invoke_model( | 
					
						
							|  |  |  |                 user_id=user_id, | 
					
						
							|  |  |  |                 prompt_messages=[SystemPromptMessage(content=_SUMMARY_PROMPT), UserPromptMessage(content=content)], | 
					
						
							|  |  |  |                 stop=[], | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             assert isinstance(summary.message.content, str) | 
					
						
							|  |  |  |             return summary.message.content | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         lines = content.split("\n") | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         new_lines = [] | 
					
						
							|  |  |  |         # split long line into multiple lines | 
					
						
							|  |  |  |         for i in range(len(lines)): | 
					
						
							|  |  |  |             line = lines[i] | 
					
						
							|  |  |  |             if not line.strip(): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if len(line) < max_tokens * 0.5: | 
					
						
							|  |  |  |                 new_lines.append(line) | 
					
						
							|  |  |  |             elif get_prompt_tokens(line) > max_tokens * 0.7: | 
					
						
							|  |  |  |                 while get_prompt_tokens(line) > max_tokens * 0.7: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                     new_lines.append(line[: int(max_tokens * 0.5)]) | 
					
						
							|  |  |  |                     line = line[int(max_tokens * 0.5) :] | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |                 new_lines.append(line) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 new_lines.append(line) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # merge lines into messages with max tokens | 
					
						
							| 
									
										
										
										
											2024-02-09 15:21:33 +08:00
										 |  |  |         messages: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         for j in new_lines: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             if len(messages) == 0: | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                 messages.append(j) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                 if len(messages[-1]) + len(j) < max_tokens * 0.5: | 
					
						
							|  |  |  |                     messages[-1] += j | 
					
						
							|  |  |  |                 if get_prompt_tokens(messages[-1] + j) > max_tokens * 0.7: | 
					
						
							|  |  |  |                     messages.append(j) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                     messages[-1] += j | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         summaries = [] | 
					
						
							|  |  |  |         for i in range(len(messages)): | 
					
						
							|  |  |  |             message = messages[i] | 
					
						
							|  |  |  |             summary = summarize(message) | 
					
						
							|  |  |  |             summaries.append(summary) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         result = "\n".join(summaries) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         if self.get_prompt_tokens(prompt_messages=[UserPromptMessage(content=result)]) > max_tokens * 0.7: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             return self.summary(user_id=user_id, content=result) | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         return result |