builtin_tool.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from core.model_runtime.entities.llm_entities import LLMResult
  2. from core.model_runtime.entities.message_entities import PromptMessage, SystemPromptMessage, UserPromptMessage
  3. from core.tools.entities.tool_entities import ToolProviderType
  4. from core.tools.tool.tool import Tool
  5. from core.tools.utils.model_invocation_utils import ModelInvocationUtils
  6. from core.tools.utils.web_reader_tool import get_url
  7. _SUMMARY_PROMPT = """You are a professional language researcher, you are interested in the language
  8. and you can quickly aimed at the main point of an webpage and reproduce it in your own words but
  9. retain the original meaning and keep the key points.
  10. however, the text you got is too long, what you got is possible a part of the text.
  11. Please summarize the text you got.
  12. """
  13. class BuiltinTool(Tool):
  14. """
  15. Builtin tool
  16. :param meta: the meta data of a tool call processing
  17. """
  18. def invoke_model(self, user_id: str, prompt_messages: list[PromptMessage], stop: list[str]) -> LLMResult:
  19. """
  20. invoke model
  21. :param model_config: the model config
  22. :param prompt_messages: the prompt messages
  23. :param stop: the stop words
  24. :return: the model result
  25. """
  26. # invoke model
  27. return ModelInvocationUtils.invoke(
  28. user_id=user_id,
  29. tenant_id=self.runtime.tenant_id,
  30. tool_type="builtin",
  31. tool_name=self.identity.name,
  32. prompt_messages=prompt_messages,
  33. )
  34. def tool_provider_type(self) -> ToolProviderType:
  35. return ToolProviderType.BUILT_IN
  36. def get_max_tokens(self) -> int:
  37. """
  38. get max tokens
  39. :param model_config: the model config
  40. :return: the max tokens
  41. """
  42. return ModelInvocationUtils.get_max_llm_context_tokens(
  43. tenant_id=self.runtime.tenant_id,
  44. )
  45. def get_prompt_tokens(self, prompt_messages: list[PromptMessage]) -> int:
  46. """
  47. get prompt tokens
  48. :param prompt_messages: the prompt messages
  49. :return: the tokens
  50. """
  51. return ModelInvocationUtils.calculate_tokens(tenant_id=self.runtime.tenant_id, prompt_messages=prompt_messages)
  52. def summary(self, user_id: str, content: str) -> str:
  53. max_tokens = self.get_max_tokens()
  54. if self.get_prompt_tokens(prompt_messages=[UserPromptMessage(content=content)]) < max_tokens * 0.6:
  55. return content
  56. def get_prompt_tokens(content: str) -> int:
  57. return self.get_prompt_tokens(
  58. prompt_messages=[SystemPromptMessage(content=_SUMMARY_PROMPT), UserPromptMessage(content=content)]
  59. )
  60. def summarize(content: str) -> str:
  61. summary = self.invoke_model(
  62. user_id=user_id,
  63. prompt_messages=[SystemPromptMessage(content=_SUMMARY_PROMPT), UserPromptMessage(content=content)],
  64. stop=[],
  65. )
  66. return summary.message.content
  67. lines = content.split("\n")
  68. new_lines = []
  69. # split long line into multiple lines
  70. for i in range(len(lines)):
  71. line = lines[i]
  72. if not line.strip():
  73. continue
  74. if len(line) < max_tokens * 0.5:
  75. new_lines.append(line)
  76. elif get_prompt_tokens(line) > max_tokens * 0.7:
  77. while get_prompt_tokens(line) > max_tokens * 0.7:
  78. new_lines.append(line[: int(max_tokens * 0.5)])
  79. line = line[int(max_tokens * 0.5) :]
  80. new_lines.append(line)
  81. else:
  82. new_lines.append(line)
  83. # merge lines into messages with max tokens
  84. messages: list[str] = []
  85. for i in new_lines:
  86. if len(messages) == 0:
  87. messages.append(i)
  88. else:
  89. if len(messages[-1]) + len(i) < max_tokens * 0.5:
  90. messages[-1] += i
  91. if get_prompt_tokens(messages[-1] + i) > max_tokens * 0.7:
  92. messages.append(i)
  93. else:
  94. messages[-1] += i
  95. summaries = []
  96. for i in range(len(messages)):
  97. message = messages[i]
  98. summary = summarize(message)
  99. summaries.append(summary)
  100. result = "\n".join(summaries)
  101. if self.get_prompt_tokens(prompt_messages=[UserPromptMessage(content=result)]) > max_tokens * 0.7:
  102. return self.summary(user_id=user_id, content=result)
  103. return result
  104. def get_url(self, url: str, user_agent: str = None) -> str:
  105. """
  106. get url
  107. """
  108. return get_url(url, user_agent=user_agent)