diff --git a/en/.doctrees/agentscope.agents.doctree b/en/.doctrees/agentscope.agents.doctree index f99c7bccc..92d0d21e8 100644 Binary files a/en/.doctrees/agentscope.agents.doctree and b/en/.doctrees/agentscope.agents.doctree differ diff --git a/en/.doctrees/agentscope.agents.react_agent.doctree b/en/.doctrees/agentscope.agents.react_agent.doctree index 15238ee14..b76a3493c 100644 Binary files a/en/.doctrees/agentscope.agents.react_agent.doctree and b/en/.doctrees/agentscope.agents.react_agent.doctree differ diff --git a/en/.doctrees/agentscope.exception.doctree b/en/.doctrees/agentscope.exception.doctree new file mode 100644 index 000000000..aa55058b2 Binary files /dev/null and b/en/.doctrees/agentscope.exception.doctree differ diff --git a/en/.doctrees/agentscope.models.doctree b/en/.doctrees/agentscope.models.doctree index 7a00e2e83..47a5ea050 100644 Binary files a/en/.doctrees/agentscope.models.doctree and b/en/.doctrees/agentscope.models.doctree differ diff --git a/en/.doctrees/agentscope.models.response.doctree b/en/.doctrees/agentscope.models.response.doctree index c290f5062..f878b355c 100644 Binary files a/en/.doctrees/agentscope.models.response.doctree and b/en/.doctrees/agentscope.models.response.doctree differ diff --git a/en/.doctrees/agentscope.parsers.code_block_parser.doctree b/en/.doctrees/agentscope.parsers.code_block_parser.doctree new file mode 100644 index 000000000..c8da00c37 Binary files /dev/null and b/en/.doctrees/agentscope.parsers.code_block_parser.doctree differ diff --git a/en/.doctrees/agentscope.parsers.doctree b/en/.doctrees/agentscope.parsers.doctree new file mode 100644 index 000000000..68b853cf2 Binary files /dev/null and b/en/.doctrees/agentscope.parsers.doctree differ diff --git a/en/.doctrees/agentscope.parsers.json_object_parser.doctree b/en/.doctrees/agentscope.parsers.json_object_parser.doctree new file mode 100644 index 000000000..e515fab23 Binary files /dev/null and b/en/.doctrees/agentscope.parsers.json_object_parser.doctree differ diff --git a/en/.doctrees/agentscope.parsers.parser_base.doctree b/en/.doctrees/agentscope.parsers.parser_base.doctree new file mode 100644 index 000000000..06cb257fa Binary files /dev/null and b/en/.doctrees/agentscope.parsers.parser_base.doctree differ diff --git a/en/.doctrees/agentscope.parsers.tagged_content_parser.doctree b/en/.doctrees/agentscope.parsers.tagged_content_parser.doctree new file mode 100644 index 000000000..3104f40db Binary files /dev/null and b/en/.doctrees/agentscope.parsers.tagged_content_parser.doctree differ diff --git a/en/.doctrees/agentscope.service.doctree b/en/.doctrees/agentscope.service.doctree index a75eb0302..534fb66c8 100644 Binary files a/en/.doctrees/agentscope.service.doctree and b/en/.doctrees/agentscope.service.doctree differ diff --git a/en/.doctrees/agentscope.service.service_factory.doctree b/en/.doctrees/agentscope.service.service_factory.doctree deleted file mode 100644 index 81a7070d6..000000000 Binary files a/en/.doctrees/agentscope.service.service_factory.doctree and /dev/null differ diff --git a/en/.doctrees/agentscope.service.service_toolkit.doctree b/en/.doctrees/agentscope.service.service_toolkit.doctree new file mode 100644 index 000000000..3e2d32a9e Binary files /dev/null and b/en/.doctrees/agentscope.service.service_toolkit.doctree differ diff --git a/en/.doctrees/agentscope.utils.common.doctree b/en/.doctrees/agentscope.utils.common.doctree index 43581cdd5..f827c0334 100644 Binary files a/en/.doctrees/agentscope.utils.common.doctree and b/en/.doctrees/agentscope.utils.common.doctree differ diff --git a/en/.doctrees/environment.pickle b/en/.doctrees/environment.pickle index c478eb707..5d2e765f4 100644 Binary files a/en/.doctrees/environment.pickle and b/en/.doctrees/environment.pickle differ diff --git a/en/.doctrees/index.doctree b/en/.doctrees/index.doctree index 8279c5e64..4f5e14bab 100644 Binary files a/en/.doctrees/index.doctree and b/en/.doctrees/index.doctree differ diff --git a/en/.doctrees/tutorial/204-service.doctree b/en/.doctrees/tutorial/204-service.doctree index ef1772bf8..2578867c6 100644 Binary files a/en/.doctrees/tutorial/204-service.doctree and b/en/.doctrees/tutorial/204-service.doctree differ diff --git a/en/_modules/agentscope/_init.html b/en/_modules/agentscope/_init.html index e6dae9034..d09be533d 100644 --- a/en/_modules/agentscope/_init.html +++ b/en/_modules/agentscope/_init.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/agent.html b/en/_modules/agentscope/agents/agent.html index 75c89456c..4bc1ea324 100644 --- a/en/_modules/agentscope/agents/agent.html +++ b/en/_modules/agentscope/agents/agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/dialog_agent.html b/en/_modules/agentscope/agents/dialog_agent.html index d5e0ca853..c1b08ab12 100644 --- a/en/_modules/agentscope/agents/dialog_agent.html +++ b/en/_modules/agentscope/agents/dialog_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/dict_dialog_agent.html b/en/_modules/agentscope/agents/dict_dialog_agent.html index 346ae9e41..05c509384 100644 --- a/en/_modules/agentscope/agents/dict_dialog_agent.html +++ b/en/_modules/agentscope/agents/dict_dialog_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/operator.html b/en/_modules/agentscope/agents/operator.html index 578821705..b2912fd50 100644 --- a/en/_modules/agentscope/agents/operator.html +++ b/en/_modules/agentscope/agents/operator.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/react_agent.html b/en/_modules/agentscope/agents/react_agent.html index f4e6f655f..edaba7490 100644 --- a/en/_modules/agentscope/agents/react_agent.html +++ b/en/_modules/agentscope/agents/react_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -100,27 +102,18 @@

    Source code for agentscope.agents.react_agent

    and act iteratively to solve problems. More details can be found in the paper https://arxiv.org/abs/2210.03629. """ -import json -from typing import Tuple, List +from typing import Any +from loguru import logger + +from agentscope.exception import ResponseParsingError, FunctionCallError from agentscope.agents import AgentBase from agentscope.message import Msg -from agentscope.models import ResponseParser, ResponseParsingError -from agentscope.service import ServiceResponse, ServiceExecStatus - - -DEFAULT_TOOL_PROMPT = """The following tool functions are available in the format of -``` -{{index}}. {{function name}}: {{function description}} - {{argument1 name}} ({{argument type}}): {{argument description}} - {{argument2 name}} ({{argument type}}): {{argument description}} - ... -``` +from agentscope.parsers import MarkdownJsonDictParser +from agentscope.service import ServiceToolkit +from agentscope.service.service_toolkit import ServiceFunction -## Tool Functions: -{function_prompt} - -## What You Should Do: +INSTRUCTION_PROMPT = """## What You Should Do: 1. First, analyze the current situation, and determine your goal. 2. Then, check if your goal is already achieved. If so, try to generate a response. Otherwise, think about how to achieve it with the help of provided tool functions. 3. Respond in the required format. @@ -131,37 +124,8 @@

    Source code for agentscope.agents.react_agent

    3. Make sure the types and values of the arguments you provided to the tool functions are correct. 4. Don't take things for granted. For example, where you are, what's the time now, etc. You can try to use the tool functions to get information. 5. If the function execution fails, you should analyze the error and try to solve it. - """ # noqa -TOOL_HINT_PROMPT = """ -## Response Format: -You should respond with a JSON object in the following format, which can be loaded by `json.loads` in Python directly. If no tool function is used, the "function" field should be an empty list. -{ - "thought": "what you thought", - "speak": "what you said", - "function": [{"name": "{function name}", "arguments": {"{argument1 name}": xxx, "{argument2 name}": xxx}}] -}""" # noqa - -FUNCTION_RESULT_TITLE_PROMPT = """Execution Results: -""" - -FUNCTION_RESULT_PROMPT = """{index}. {function_name}: - [EXECUTE STATUS]: {status} - [EXECUTE RESULT]: {result} -""" - -ERROR_INFO_PROMPT = """Your response is not a JSON object, and cannot be parsed by `json.loads` in parse function: -## Your Response: -[YOUR RESPONSE BEGIN] -{response} -[YOUR RESPONSE END] - -## Error Information: -{error_info} - -Analyze the reason, and re-correct your response in the correct format.""" # pylint: disable=all # noqa -
    [docs] @@ -181,10 +145,11 @@

    Source code for agentscope.agents.react_agent

    self, name: str, model_config_name: str, - tools: List[Tuple], + service_toolkit: ServiceToolkit = None, sys_prompt: str = "You're a helpful assistant. Your name is {name}.", max_iters: int = 10, verbose: bool = True, + **kwargs: Any, ) -> None: """Initialize the ReAct agent with the given name, model config name and tools. @@ -197,13 +162,14 @@

    Source code for agentscope.agents.react_agent

    model_config_name (`str`): The name of the model config, which is used to load model from configuration. - tools (`List[Tuple]`): - A list of tuples, each containing the name of a tool and the - tool's description in JSON schema format. + service_toolkit (`ServiceToolkit`): + A `ServiceToolkit` object that contains the tool functions. max_iters (`int`, defaults to `10`): The maximum number of iterations of the reasoning-acting loops. verbose (`bool`, defaults to `True`): - Whether to print the output of the tools. + Whether to print the detailed information during reasoning and + acting steps. If `False`, only the content in speak field will + be print out. """ super().__init__( name=name, @@ -211,24 +177,69 @@

    Source code for agentscope.agents.react_agent

    model_config_name=model_config_name, ) - self.tools = tools - self.verbose = verbose - self.max_iters = max_iters + # TODO: To compatible with the old version, which will be deprecated + # soon + if "tools" in kwargs: + logger.warning( + "The argument `tools` will be deprecated soon. " + "Please use `service_toolkit` instead. Example refers to " + "https://github.com/modelscope/agentscope/blob/main/" + "examples/conversation_with_react_agent/code/" + "conversation_with_react_agent.py", + ) - func_prompt, self.func_name_mapping = self.prepare_funcs_prompt(tools) + service_funcs = {} + for func, json_schema in kwargs["tools"]: + name = json_schema["function"]["name"] + service_funcs[name] = ServiceFunction( + name=name, + original_func=func, + processed_func=func, + json_schema=json_schema, + ) - # Prepare system prompt - tools_prompt = DEFAULT_TOOL_PROMPT.format(function_prompt=func_prompt) + if service_toolkit is None: + service_toolkit = ServiceToolkit() + service_toolkit.service_funcs = service_funcs + else: + service_toolkit.service_funcs.update(service_funcs) - if sys_prompt.endswith("\n"): - self.sys_prompt = sys_prompt.format(name=self.name) + tools_prompt - else: - self.sys_prompt = ( - sys_prompt.format(name=self.name) + "\n" + tools_prompt + elif service_toolkit is None: + raise ValueError( + "The argument `service_toolkit` is required to initialize " + "the ReActAgent.", ) + self.service_toolkit = service_toolkit + self.verbose = verbose + self.max_iters = max_iters + + if not sys_prompt.endswith("\n"): + sys_prompt = sys_prompt + "\n" + + self.sys_prompt = "\n".join( + [ + # The brief intro of the role and target + sys_prompt.format(name=self.name), + # The instruction prompt for tools + self.service_toolkit.tools_instruction, + # The detailed instruction prompt for the agent + INSTRUCTION_PROMPT, + ], + ) + # Put sys prompt into memory - self.memory.add(Msg("system", self.sys_prompt, role="system"))
    + self.memory.add(Msg("system", self.sys_prompt, role="system")) + + # Initialize a parser object to formulate the response from the model + self.parser = MarkdownJsonDictParser( + content_hint={ + "thought": "what you thought", + "speak": "what you speak", + "function": service_toolkit.tools_calling_format, + }, + required_keys=["thought", "speak", "function"], + )
    @@ -237,41 +248,67 @@

    Source code for agentscope.agents.react_agent

    """The reply function that achieves the ReAct algorithm. The more details please refer to https://arxiv.org/abs/2210.03629""" - if self.memory: - self.memory.add(x) + self.memory.add(x) for _ in range(self.max_iters): # Step 1: Thought + if self.verbose: + self.speak(f" ITER {_+1}, STEP 1: REASONING ".center(70, "#")) + + # Prepare hint to remind model what the response format is + # Won't be recorded in memory to save tokens + hint_msg = Msg( + "system", + self.parser.format_instruction, + role="system", + ) + if self.verbose: + self.speak(hint_msg) - self.speak(f" ITER {_+1}, STEP 1: REASONING ".center(70, "#")) + # Prepare prompt for the model + prompt = self.model.format(self.memory.get_memory(), hint_msg) + # Generate and parse the response try: - hint_msg = Msg("system", TOOL_HINT_PROMPT, role="system") - self.memory.add(hint_msg) - - # Generate LLM response - prompt = self.model.format(self.memory.get_memory()) res = self.model( prompt, - parse_func=ResponseParser.to_dict, + parse_func=self.parser.parse, max_retries=1, - ).json + ) + + # Record the response in memory + msg_response = Msg(self.name, res.text, "assistant") + self.memory.add(msg_response) + # Print out the response + if self.verbose: + self.speak(msg_response) + else: + self.speak( + Msg(self.name, res.parsed["speak"], "assistant"), + ) + + # Skip the next steps if no need to call tools + # The parsed field is a dictionary + arg_function = res.parsed["function"] + if ( + isinstance(arg_function, str) + and arg_function in ["[]", ""] + or isinstance(arg_function, list) + and len(arg_function) == 0 + ): + # Only the speak field is exposed to users or other agents + return Msg(self.name, res.parsed["speak"], "assistant") + + # Only catch the response parsing error and expose runtime + # errors to developers for debugging except ResponseParsingError as e: - # Record the wrong response from the model - response_msg = Msg(self.name, e.response.text, "assistant") + # Print out raw response from models for developers to debug + response_msg = Msg(self.name, e.raw_response, "assistant") self.speak(response_msg) # Re-correct by model itself - error_msg = Msg( - "system", - ERROR_INFO_PROMPT.format( - parse_func=ResponseParser.to_dict, - error_info=e.error_info, - response=e.response.text, - ), - "system", - ) + error_msg = Msg("system", str(e), "system") self.speak(error_msg) self.memory.add([response_msg, error_msg]) @@ -279,160 +316,51 @@

    Source code for agentscope.agents.react_agent

    # Skip acting step to re-correct the response continue - # Record the response in memory - msg_thought = Msg(self.name, res, role="assistant") - - # To better display the response, we reformat it by json.dumps here - self.speak( - Msg(self.name, json.dumps(res, indent=4), role="assistant"), - ) - - if self.memory: - self.memory.add(msg_thought) - - # Skip the next steps if no need to call tools - if len(res.get("function", [])) == 0: - return msg_thought + # Step 2: Acting + if self.verbose: + self.speak(f" ITER {_+1}, STEP 2: ACTING ".center(70, "#")) - # Step 2: Action - - self.speak(f" ITER {_+1}, STEP 2: ACTION ".center(70, "#")) - - # Execute functions - # TODO: check the provided arguments and re-correct them if needed - execute_results = [] - for i, func in enumerate(res["function"]): - # Execute the function - func_res = self.execute_func(i, func) - execute_results.append(func_res) - - # Prepare prompt for execution results - execute_results_prompt = "\n".join( - [ - FUNCTION_RESULT_PROMPT.format_map(res) - for res in execute_results - ], - ) - # Add title - execute_results_prompt = ( - FUNCTION_RESULT_TITLE_PROMPT + execute_results_prompt - ) + # Parse, check and execute the tool functions in service toolkit + try: + execute_results = self.service_toolkit.parse_and_call_func( + res.parsed["function"], + ) - # Note: Observing the execution results and generate response are - # finished in the next loop. We just put the execution results - # into memory, and wait for the next loop to generate response. + # Note: Observing the execution results and generate response + # are finished in the next reasoning step. We just put the + # execution results into memory, and wait for the next loop + # to generate response. - # Record execution results into memory as a message from the system - msg_res = Msg( - name="system", - content=execute_results_prompt, - role="system", - ) - self.speak(msg_res) - if self.memory: + # Record execution results into memory as system message + msg_res = Msg("system", execute_results, "system") + self.speak(msg_res) self.memory.add(msg_res) - return Msg( + except FunctionCallError as e: + # Catch the function calling error that can be handled by + # the model + error_msg = Msg("system", str(e), "system") + self.speak(error_msg) + self.memory.add(error_msg) + + # Exceed the maximum iterations + hint_msg = Msg( "system", - "The agent has reached the maximum iterations.", + "You have failed to generate a response in the maximum " + "iterations. Now generate a reply by summarizing the current " + "situation.", role="system", - )
    - - -
    -[docs] - def execute_func(self, index: int, func_call: dict) -> dict: - """Execute the tool function and return the result. - - Args: - index (`int`): - The index of the tool function. - func_call (`dict`): - The function call dictionary with keys 'name' and 'arguments'. - - Returns: - `ServiceResponse`: The execution results. - """ - # Extract the function name and arguments - func_name = func_call["name"] - func_args = func_call["arguments"] - - self.speak(f">>> Executing function {func_name} ...") - - try: - func_res = self.func_name_mapping[func_name](**func_args) - except Exception as e: - func_res = ServiceResponse( - status=ServiceExecStatus.ERROR, - content=str(e), - ) - - self.speak(">>> END ") - - status = ( - "SUCCESS" - if func_res.status == ServiceExecStatus.SUCCESS - else "FAILED" ) + if self.verbose: + self.speak(hint_msg) - # return the result of the function - return { - "index": index + 1, - "function_name": func_name, - "status": status, - "result": func_res.content, - }
    - - -
    -[docs] - def prepare_funcs_prompt(self, tools: List[Tuple]) -> Tuple[str, dict]: - """Convert function descriptions from json schema format to - string prompt format. - - Args: - tools (`List[Tuple]`): - The list of tool functions and their descriptions in JSON - schema format. - - Returns: - `Tuple[str, dict]`: - The string prompt for the tool functions and a function name - mapping dict. - - .. code-block:: python - - {index}. {function name}: {function description} - {argument name} ({argument type}): {argument description} - ... - - """ - tools_prompt = [] - func_name_mapping = {} - for i, (func, desc) in enumerate(tools): - func_name = desc["function"]["name"] - func_name_mapping[func_name] = func - - func_desc = desc["function"]["description"] - args_desc = desc["function"]["parameters"]["properties"] - - args_list = [f"{i + 1}. {func_name}: {func_desc}"] - for args_name, args_info in args_desc.items(): - if "type" in args_info: - args_line = ( - f'\t{args_name} ({args_info["type"]}): ' - f'{args_info.get("description", "")}' - ) - else: - args_line = ( - f'\t{args_name}: {args_info.get("description", "")}' - ) - args_list.append(args_line) - - func_prompt = "\n".join(args_list) - tools_prompt.append(func_prompt) + # Generate a reply by summarizing the current situation + prompt = self.model.format(self.memory.get_memory(), hint_msg) + res = self.model(prompt) + res_msg = Msg(self.name, res.text, "assistant") + self.speak(res_msg) - return "\n".join(tools_prompt), func_name_mapping
    + return res_msg
    diff --git a/en/_modules/agentscope/agents/rpc_agent.html b/en/_modules/agentscope/agents/rpc_agent.html index c1d80a69f..2f1d7830f 100644 --- a/en/_modules/agentscope/agents/rpc_agent.html +++ b/en/_modules/agentscope/agents/rpc_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/text_to_image_agent.html b/en/_modules/agentscope/agents/text_to_image_agent.html index b64514501..f7bd6429b 100644 --- a/en/_modules/agentscope/agents/text_to_image_agent.html +++ b/en/_modules/agentscope/agents/text_to_image_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/agents/user_agent.html b/en/_modules/agentscope/agents/user_agent.html index e12fa8eb6..634f8cced 100644 --- a/en/_modules/agentscope/agents/user_agent.html +++ b/en/_modules/agentscope/agents/user_agent.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/constants.html b/en/_modules/agentscope/constants.html index a25c4d4d2..81391e4b7 100644 --- a/en/_modules/agentscope/constants.html +++ b/en/_modules/agentscope/constants.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/exception.html b/en/_modules/agentscope/exception.html new file mode 100644 index 000000000..4ff63e050 --- /dev/null +++ b/en/_modules/agentscope/exception.html @@ -0,0 +1,262 @@ + + + + + + + agentscope.exception — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for agentscope.exception

    +# -*- coding: utf-8 -*-
    +"""AgentScope exception classes."""
    +
    +# - Model Response Parsing Exceptions
    +
    +
    +
    +[docs] +class ResponseParsingError(Exception): + """The exception class for response parsing error with uncertain + reasons.""" + + raw_response: str + """Record the raw response.""" + +
    +[docs] + def __init__(self, message: str, raw_response: str = None) -> None: + """Initialize the exception with the message.""" + self.message = message + self.raw_response = raw_response
    + + + def __str__(self) -> str: + return f"{self.__class__.__name__}: {self.message}"
    + + + +
    +[docs] +class JsonParsingError(ResponseParsingError): + """The exception class for JSON parsing error."""
    + + + +
    +[docs] +class JsonTypeError(ResponseParsingError): + """The exception class for JSON type error."""
    + + + +
    +[docs] +class RequiredFieldNotFoundError(ResponseParsingError): + """The exception class for missing required field in model response, when + the response is required to be a JSON dict object with required fields."""
    + + + +
    +[docs] +class TagNotFoundError(ResponseParsingError): + """The exception class for missing tagged content in model response.""" + + missing_begin_tag: bool + """If the response misses the begin tag.""" + + missing_end_tag: bool + """If the response misses the end tag.""" + +
    +[docs] + def __init__( + self, + message: str, + raw_response: str = None, + missing_begin_tag: bool = True, + missing_end_tag: bool = True, + ): + """Initialize the exception with the message. + + Args: + raw_response (`str`): + Record the raw response from the model. + missing_begin_tag (`bool`, defaults to `True`): + If the response misses the beginning tag, default to `True`. + missing_end_tag (`bool`, defaults to `True`): + If the response misses the end tag, default to `True`. + """ + super().__init__(message, raw_response) + + self.missing_begin_tag = missing_begin_tag + self.missing_end_tag = missing_end_tag
    +
    + + + +# - Function Calling Exceptions + + +
    +[docs] +class FunctionCallError(Exception): + """The base class for exception raising during calling functions.""" + +
    +[docs] + def __init__(self, message: str) -> None: + self.message = message
    + + + def __str__(self) -> str: + return f"{self.__class__.__name__}: {self.message}"
    + + + +
    +[docs] +class FunctionCallFormatError(FunctionCallError): + """The exception class for function calling format error."""
    + + + +
    +[docs] +class FunctionNotFoundError(FunctionCallError): + """The exception class for function not found error."""
    + + + +
    +[docs] +class ArgumentNotFoundError(FunctionCallError): + """The exception class for missing argument error."""
    + + + +
    +[docs] +class ArgumentTypeError(FunctionCallError): + """The exception class for argument type error."""
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/memory/memory.html b/en/_modules/agentscope/memory/memory.html index 61dbb549a..53f11f691 100644 --- a/en/_modules/agentscope/memory/memory.html +++ b/en/_modules/agentscope/memory/memory.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/memory/temporary_memory.html b/en/_modules/agentscope/memory/temporary_memory.html index 313884ab5..24c303263 100644 --- a/en/_modules/agentscope/memory/temporary_memory.html +++ b/en/_modules/agentscope/memory/temporary_memory.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/message.html b/en/_modules/agentscope/message.html index 33312a401..9a4718072 100644 --- a/en/_modules/agentscope/message.html +++ b/en/_modules/agentscope/message.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models.html b/en/_modules/agentscope/models.html index 8693d2af7..f3407d3ce 100644 --- a/en/_modules/agentscope/models.html +++ b/en/_modules/agentscope/models.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -104,11 +106,7 @@

    Source code for agentscope.models

     
     from .config import _ModelConfig
     from .model import ModelWrapperBase
    -from .response import (
    -    ModelResponse,
    -    ResponseParsingError,
    -    ResponseParser,
    -)
    +from .response import ModelResponse
     from .post_model import (
         PostAPIModelWrapperBase,
         PostAPIChatWrapper,
    @@ -139,8 +137,6 @@ 

    Source code for agentscope.models

     __all__ = [
         "ModelWrapperBase",
         "ModelResponse",
    -    "ResponseParser",
    -    "ResponseParsingError",
         "PostAPIModelWrapperBase",
         "PostAPIChatWrapper",
         "OpenAIWrapperBase",
    @@ -243,6 +239,8 @@ 

    Source code for agentscope.models

         if clear_existing:
             clear_model_configs()
     
    +    cfgs = None
    +
         if isinstance(configs, str):
             with open(configs, "r", encoding="utf-8") as f:
                 cfgs = json.load(f)
    @@ -257,6 +255,13 @@ 

    Source code for agentscope.models

                 )
             cfgs = configs
     
    +    if cfgs is None:
    +        raise TypeError(
    +            f"Invalid type of model_configs, it could be a dict, a list of "
    +            f"dicts, or a path to a json file (containing a dict or a list "
    +            f"of dicts), but got {type(configs)}",
    +        )
    +
         format_configs = _ModelConfig.format_configs(configs=cfgs)
     
         # check if name is unique
    diff --git a/en/_modules/agentscope/models/dashscope_model.html b/en/_modules/agentscope/models/dashscope_model.html
    index 8449bc4a4..96b8f8ec1 100644
    --- a/en/_modules/agentscope/models/dashscope_model.html
    +++ b/en/_modules/agentscope/models/dashscope_model.html
    @@ -62,6 +62,8 @@
     
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models/gemini_model.html b/en/_modules/agentscope/models/gemini_model.html index 815887a79..51a53c432 100644 --- a/en/_modules/agentscope/models/gemini_model.html +++ b/en/_modules/agentscope/models/gemini_model.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models/model.html b/en/_modules/agentscope/models/model.html index a1b494139..059ed7161 100644 --- a/en/_modules/agentscope/models/model.html +++ b/en/_modules/agentscope/models/model.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -161,7 +163,8 @@

    Source code for agentscope.models.model

     from loguru import logger
     
     from agentscope.utils import QuotaExceededError
    -from .response import ResponseParsingError, ModelResponse
    +from .response import ModelResponse
    +from ..exception import ResponseParsingError
     
     from ..file_manager import file_manager
     from ..message import MessageBase
    @@ -221,7 +224,7 @@ 

    Source code for agentscope.models.model

                 # Parse the response if needed
                 try:
                     return parse_func(response)
    -            except Exception as e:
    +            except ResponseParsingError as e:
                     if itr < max_retries:
                         logger.warning(
                             f"Fail to parse response ({itr}/{max_retries}):\n"
    @@ -233,12 +236,7 @@ 

    Source code for agentscope.models.model

                         if fault_handler is not None and callable(fault_handler):
                             return fault_handler(response)
                         else:
    -                        error_info = f"{e.__class__.__name__}: {e}"
    -                        raise ResponseParsingError(
    -                            parse_func=parse_func,
    -                            error_info=error_info,
    -                            response=response,
    -                        ) from None
    +                        raise
             return {}
     
         return checking_wrapper
    @@ -304,7 +302,7 @@ 

    Source code for agentscope.models.model

             self.monitor = MonitorFactory.get_monitor()
     
             self.config_name = config_name
    -        logger.info(f"Initialize model [{config_name}]")
    + logger.info(f"Initialize model by configuration [{config_name}]")
    diff --git a/en/_modules/agentscope/models/ollama_model.html b/en/_modules/agentscope/models/ollama_model.html index b31452268..be26c75e5 100644 --- a/en/_modules/agentscope/models/ollama_model.html +++ b/en/_modules/agentscope/models/ollama_model.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models/openai_model.html b/en/_modules/agentscope/models/openai_model.html index 572d2f03e..a4447e4f2 100644 --- a/en/_modules/agentscope/models/openai_model.html +++ b/en/_modules/agentscope/models/openai_model.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models/post_model.html b/en/_modules/agentscope/models/post_model.html index 1c4627763..51f3e3093 100644 --- a/en/_modules/agentscope/models/post_model.html +++ b/en/_modules/agentscope/models/post_model.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/models/response.html b/en/_modules/agentscope/models/response.html index e1281e523..66af3c2af 100644 --- a/en/_modules/agentscope/models/response.html +++ b/en/_modules/agentscope/models/response.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -98,9 +100,8 @@

    Source code for agentscope.models.response

     # -*- coding: utf-8 -*-
     """Parser for model response."""
    -import inspect
     import json
    -from typing import Optional, Sequence, Any, Callable
    +from typing import Optional, Sequence, Any
     
     from loguru import logger
     
    @@ -120,7 +121,7 @@ 

    Source code for agentscope.models.response

         embedding: Optional[Sequence] = None
         raw: Optional[Any] = None
         image_urls: Optional[Sequence[str]] = None
    -    json: Optional[Any] = None
    +    parsed: Optional[Any] = None
     
     
    [docs] @@ -130,6 +131,7 @@

    Source code for agentscope.models.response

             embedding: Sequence = None,
             image_urls: Sequence[str] = None,
             raw: Any = None,
    +        parsed: Any = None,
         ) -> None:
             """Initialize the model response.
     
    @@ -142,13 +144,36 @@ 

    Source code for agentscope.models.response

                     The image URLs returned by the model.
                 raw (`Any`, optional):
                     The raw data returned by the model.
    +            parsed (`Any`, optional):
    +                The parsed data returned by the model.
             """
             self.text = text
             self.embedding = embedding
             self.image_urls = image_urls
    -        self.raw = raw
    + self.raw = raw + self.parsed = parsed
    + def __getattribute__(self, item: str) -> Any: + """Warning for the deprecated json attribute.""" + if item == "json": + logger.warning( + "The json attribute in ModelResponse class is deprecated. Use" + " parsed attribute instead.", + ) + + return super().__getattribute__(item) + + def __setattr__(self, key: str, value: Any) -> Optional[Any]: + """Warning for the deprecated json attribute.""" + if key == "json": + logger.warning( + "The json attribute in ModelResponse class is deprecated. Use" + " parsed attribute instead.", + ) + + return super().__setattr__(key, value) + def __str__(self) -> str: if _is_json_serializable(self.raw): raw = self.raw @@ -159,126 +184,11 @@

    Source code for agentscope.models.response

                 "text": self.text,
                 "embedding": self.embedding,
                 "image_urls": self.image_urls,
    -            "json": self.json,
    +            "parsed": self.parsed,
                 "raw": raw,
             }
             return json.dumps(serialized_fields, indent=4, ensure_ascii=False)
    - - -
    -[docs] -class ResponseParser: - """A class that contains several static methods to parse the response.""" - -
    -[docs] - @classmethod - def to_dict(cls, response: ModelResponse) -> ModelResponse: - """Parse the response text to a dict, and feed it into the `json` - field.""" - text = response.text - if text is not None: - logger.debug("Text before parsing", text) - - # extract from the first '{' to the last '}' - index_start = max(text.find("{"), 0) - index_end = min(text.rfind("}") + 1, len(text)) - - text = text[index_start:index_end] - logger.debug("Text after parsing", text) - - response.text = text - response.json = json.loads(text) - return response - else: - raise ValueError( - f"The text field of the model response is None: {response}", - )
    - - -
    -[docs] - @classmethod - def to_list(cls, response: ModelResponse) -> ModelResponse: - """Parse the response text to a list, and feed it into the `json` - field.""" - text = response.text - if text is not None: - logger.debug("Text before parsing", text) - - # extract from the first '{' to the last '}' - index_start = max(text.find("["), 0) - index_end = min(text.rfind("]") + 1, len(text)) - - text = text[index_start:index_end] - logger.debug("Text after parsing", text) - - response.text = text - response.json = json.loads(text) - return response - else: - raise ValueError( - f"The text field of the model response is None: {response}", - )
    -
    - - - -
    -[docs] -class ResponseParsingError(Exception): - """Exception raised when parsing the response fails.""" - - parse_func: str - """The source code of the parsing function.""" - - error_info: str - """The detail information of the error.""" - - response: ModelResponse - """The response that fails to be parsed.""" - -
    -[docs] - def __init__( - self, - *args: Any, - parse_func: Callable, - error_info: str, - response: ModelResponse, - **kwargs: Any, - ) -> None: - """Initialize the exception. - - Args: - parse_func (`str`): - The source code of the parsing function. - error_info (`str`): - The detail information of the error. - response (`ModelResponse`): - The response that fails to be parsed. - """ - super().__init__(*args, **kwargs) - - self.parse_func_code = inspect.getsource(parse_func) - self.error_info = error_info - self.response = response
    - - - def __str__(self) -> str: - return ( - f"Fail to parse response with the following parsing function:\n" - f"## PARSE FUNCTION: \n" - f"```python\n" - f"{self.parse_func_code}" - f"```\n\n" - f"## ERROR INFO: \n" - f"{self.error_info}\n\n" - f"## INPUT RESPONSE: \n" - f"{self.response}" - )
    -
    diff --git a/en/_modules/agentscope/msghub.html b/en/_modules/agentscope/msghub.html index 9eb1627bc..047e982a3 100644 --- a/en/_modules/agentscope/msghub.html +++ b/en/_modules/agentscope/msghub.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/parsers/code_block_parser.html b/en/_modules/agentscope/parsers/code_block_parser.html new file mode 100644 index 000000000..b2aabc727 --- /dev/null +++ b/en/_modules/agentscope/parsers/code_block_parser.html @@ -0,0 +1,185 @@ + + + + + + + agentscope.parsers.code_block_parser — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
      +
    • + + +
    • +
    • +
    +
    +
    +
    +
    + +

    Source code for agentscope.parsers.code_block_parser

    +# -*- coding: utf-8 -*-
    +"""Model response parser class for Markdown code block."""
    +from agentscope.models import ModelResponse
    +from agentscope.parsers import ParserBase
    +
    +
    +
    +[docs] +class MarkdownCodeBlockParser(ParserBase): + """The base class for parsing the response text by fenced block.""" + + name: str = "{language_name} block" + """The name of the parser.""" + + tag_begin: str = "```{language_name}" + """The beginning tag.""" + + content_hint: str = "${your_{language_name}_CODE}" + """The hint of the content.""" + + tag_end: str = "```" + """The ending tag.""" + + format_instruction: str = ( + "You should generate {language_name} code in a {language_name} fenced " + "code block as follows: \n```{language_name}\n" + "${your_{language_name}_CODE}\n```" + ) + """The instruction for the format of the code block.""" + +
    +[docs] + def __init__(self, language_name: str) -> None: + self.name = self.name.format(language_name=language_name) + self.tag_begin = self.tag_begin.format(language_name=language_name) + self.format_instruction = self.format_instruction.format( + language_name=language_name, + ).strip()
    + + +
    +[docs] + def parse(self, response: ModelResponse) -> ModelResponse: + """Extract the content between the tag_begin and tag_end in the + response and store it in the parsed field of the response object. + """ + + extract_text = self._extract_first_content_by_tag( + response, + self.tag_begin, + self.tag_end, + ) + response.parsed = extract_text + return response
    +
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/parsers/json_object_parser.html b/en/_modules/agentscope/parsers/json_object_parser.html new file mode 100644 index 000000000..14758356a --- /dev/null +++ b/en/_modules/agentscope/parsers/json_object_parser.html @@ -0,0 +1,351 @@ + + + + + + + agentscope.parsers.json_object_parser — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
      +
    • + + +
    • +
    • +
    +
    +
    +
    +
    + +

    Source code for agentscope.parsers.json_object_parser

    +# -*- coding: utf-8 -*-
    +"""The parser for JSON object in the model response."""
    +import json
    +from copy import deepcopy
    +from typing import Optional, Any, List
    +
    +from loguru import logger
    +
    +from agentscope.exception import (
    +    TagNotFoundError,
    +    JsonParsingError,
    +    JsonTypeError,
    +    RequiredFieldNotFoundError,
    +)
    +from agentscope.models import ModelResponse
    +from agentscope.parsers import ParserBase
    +from agentscope.utils.tools import _join_str_with_comma_and
    +
    +
    +
    +[docs] +class MarkdownJsonObjectParser(ParserBase): + """A parser to parse the response text to a json object.""" + + name: str = "json block" + """The name of the parser.""" + + tag_begin: str = "```json" + """Opening tag for a code block.""" + + content_hint: str = "{your_json_object}" + """The hint of the content.""" + + tag_end: str = "```" + """Closing end for a code block.""" + + _format_instruction = ( + "You should respond a json object in a json fenced code block as " + "follows:\n```json\n{content_hint}\n```" + ) + """The instruction for the format of the json object.""" + +
    +[docs] + def __init__(self, content_hint: Optional[Any] = None) -> None: + """Initialize the parser with the content hint. + + Args: + content_hint (`Optional[Any]`, defaults to `None`): + The hint used to remind LLM what should be fill between the + tags. If it is a string, it will be used as the content hint + directly. If it is a dict, it will be converted to a json + string and used as the content hint. + """ + if content_hint is not None: + if isinstance(content_hint, str): + self.content_hint = content_hint + else: + self.content_hint = json.dumps( + content_hint, + ensure_ascii=False, + )
    + + +
    +[docs] + def parse(self, response: ModelResponse) -> ModelResponse: + """Parse the response text to a json object, and fill it in the parsed + field in the response object.""" + + # extract the content and try to fix the missing tags by hand + try: + extract_text = self._extract_first_content_by_tag( + response, + self.tag_begin, + self.tag_end, + ) + except TagNotFoundError as e: + # Try to fix the missing tag error by adding the tag + try: + response_copy = deepcopy(response) + + # Fix the missing tags + if e.missing_begin_tag: + response_copy.text = ( + self.tag_begin + "\n" + response_copy.text + ) + if e.missing_end_tag: + response_copy.text = response_copy.text + self.tag_end + + # Try again to extract the content + extract_text = self._extract_first_content_by_tag( + response_copy, + self.tag_begin, + self.tag_end, + ) + + # replace the response with the fixed one + response.text = response_copy.text + + logger.debug("Fix the missing tags by adding them manually.") + + except TagNotFoundError: + # Raise the original error if the missing tags cannot be fixed + raise e from None + + # Parse the content into JSON object + try: + parsed_json = json.loads(extract_text) + response.parsed = parsed_json + return response + except json.decoder.JSONDecodeError as e: + raw_response = f"{self.tag_begin}{extract_text}{self.tag_end}" + raise JsonParsingError( + f"The content between {self.tag_begin} and {self.tag_end} " + f"MUST be a JSON object." + f'When parsing "{raw_response}", an error occurred: {e}', + raw_response=raw_response, + ) from None
    + + + @property + def format_instruction(self) -> str: + """Get the format instruction for the json object, if the + format_example is provided, it will be used as the example. + """ + return self._format_instruction.format( + content_hint=self.content_hint, + )
    + + + +
    +[docs] +class MarkdownJsonDictParser(MarkdownJsonObjectParser): + """A class used to parse a JSON dictionary object in a markdown fenced + code""" + + name: str = "json block" + """The name of the parser.""" + + tag_begin: str = "```json" + """Opening tag for a code block.""" + + content_hint: str = "{your_json_dictionary}" + """The hint of the content.""" + + tag_end: str = "```" + """Closing end for a code block.""" + + _format_instruction = ( + "You should respond a json object in a json fenced code block as " + "follows:\n```json\n{content_hint}\n```" + ) + """The instruction for the format of the json object.""" + + required_keys: List[str] + """A list of required keys in the JSON dictionary object. If the response + misses any of the required keys, it will raise a + RequiredFieldNotFoundError.""" + +
    +[docs] + def __init__( + self, + content_hint: Optional[Any] = None, + required_keys: List[str] = None, + ) -> None: + """Initialize the parser with the content hint. + + Args: + content_hint (`Optional[Any]`, defaults to `None`): + The hint used to remind LLM what should be fill between the + tags. If it is a string, it will be used as the content hint + directly. If it is a dict, it will be converted to a json + string and used as the content hint. + required_keys (`List[str]`, defaults to `[]`): + A list of required keys in the JSON dictionary object. If the + response misses any of the required keys, it will raise a + RequiredFieldNotFoundError. + """ + super().__init__(content_hint) + + self.required_keys = required_keys or []
    + + +
    +[docs] + def parse(self, response: ModelResponse) -> ModelResponse: + """Parse the text field of the response to a JSON dictionary object, + store it in the parsed field of the response object, and check if the + required keys exists. + """ + # Parse the JSON object + response = super().parse(response) + + if not isinstance(response.parsed, dict): + # If not a dictionary, raise an error + raise JsonTypeError( + "A JSON dictionary object is wanted, " + f"but got {type(response.parsed)} instead.", + response.text, + ) + + # Check if the required keys exist + keys_missing = [] + for key in self.required_keys: + if key not in response.parsed: + keys_missing.append(key) + + if len(keys_missing) != 0: + raise RequiredFieldNotFoundError( + f"Missing required " + f"field{'' if len(keys_missing)==1 else 's'} " + f"{_join_str_with_comma_and(keys_missing)} in the JSON " + f"dictionary object.", + response.text, + ) + + return response
    +
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/parsers/parser_base.html b/en/_modules/agentscope/parsers/parser_base.html new file mode 100644 index 000000000..04adf10a5 --- /dev/null +++ b/en/_modules/agentscope/parsers/parser_base.html @@ -0,0 +1,202 @@ + + + + + + + agentscope.parsers.parser_base — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
      +
    • + + +
    • +
    • +
    +
    +
    +
    +
    + +

    Source code for agentscope.parsers.parser_base

    +# -*- coding: utf-8 -*-
    +"""The base class for model response parser."""
    +from abc import ABC, abstractmethod
    +
    +from agentscope.exception import TagNotFoundError
    +from agentscope.models import ModelResponse
    +
    +
    +
    +[docs] +class ParserBase(ABC): + """The base class for model response parser.""" + +
    +[docs] + @abstractmethod + def parse(self, response: ModelResponse) -> ModelResponse: + """Parse the response text to a specific object, and stored in the + parsed field of the response object."""
    + + + def _extract_first_content_by_tag( + self, + response: ModelResponse, + tag_start: str, + tag_end: str, + ) -> str: + """Extract the first text content between the tag_start and tag_end + in the response text. Note this function does not support nested. + + Args: + response (`ModelResponse`): + The response object. + tag_start (`str`): + The start tag. + tag_end (`str`): + The end tag. + + Returns: + `str`: The extracted text content. + """ + text = response.text + + index_start = text.find(tag_start) + + # Avoid the case that tag_begin contains tag_end, e.g. ```json and ``` + if index_start == -1: + index_end = text.find(tag_end, 0) + else: + index_end = text.find(tag_end, index_start + len(tag_start)) + + if index_start == -1 or index_end == -1: + missing_tags = [] + if index_start == -1: + missing_tags.append(tag_start) + if index_end == -1: + missing_tags.append(tag_end) + + raise TagNotFoundError( + f"Missing " + f"tag{'' if len(missing_tags)==1 else 's'} " + f"{' and '.join(missing_tags)} in response.", + raw_response=text, + missing_begin_tag=index_start == -1, + missing_end_tag=index_end == -1, + ) + + extract_text = text[ + index_start + len(tag_start) : index_end # noqa: E203 + ] + + return extract_text
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/parsers/tagged_content_parser.html b/en/_modules/agentscope/parsers/tagged_content_parser.html new file mode 100644 index 000000000..fc3262d58 --- /dev/null +++ b/en/_modules/agentscope/parsers/tagged_content_parser.html @@ -0,0 +1,292 @@ + + + + + + + agentscope.parsers.tagged_content_parser — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
      +
    • + + +
    • +
    • +
    +
    +
    +
    +
    + +

    Source code for agentscope.parsers.tagged_content_parser

    +# -*- coding: utf-8 -*-
    +"""The parser for tagged content in the model response."""
    +import json
    +
    +from agentscope.exception import JsonParsingError
    +from agentscope.models import ModelResponse
    +from agentscope.parsers import ParserBase
    +
    +
    +
    +[docs] +class TaggedContent: + """A tagged content object to store the tag name, tag begin, content hint + and tag end.""" + + name: str + """The name of the tagged content.""" + + tag_begin: str + """The beginning tag.""" + + content_hint: str + """The hint of the content.""" + + tag_end: str + """The ending tag.""" + + parse_json: bool + """Whether to parse the content as a json object.""" + +
    +[docs] + def __init__( + self, + name: str, + tag_begin: str, + content_hint: str, + tag_end: str, + parse_json: bool = False, + ) -> None: + """Initialize the tagged content object. + + Args: + name (`str`): + The name of the tagged content. + tag_begin (`str`): + The beginning tag. + content_hint (`str`): + The hint of the content. + tag_end (`str`): + The ending tag. + parse_json (`bool`, defaults to `False`): + Whether to parse the content as a json object. + """ + + self.name = name + self.tag_begin = tag_begin + self.content_hint = content_hint + self.tag_end = tag_end + self.parse_json = parse_json
    + + + def __str__(self) -> str: + """Return the tagged content as a string.""" + return f"{self.tag_begin}{self.content_hint}{self.tag_end}"
    + + + +
    +[docs] +class MultiTaggedContentParser(ParserBase): + """Parse response text by multiple tags, and return a dict of their + content. Asking llm to generate JSON dictionary object directly maybe not a + good idea due to involving escape characters and other issues. So we can + ask llm to generate text with tags, and then parse the text to get the + final JSON dictionary object. + """ + + format_instruction = ( + "Respond with specific tags as outlined below{json_required_hint}\n" + "{tag_lines_format}" + ) + """The instruction for the format of the tagged content.""" + + json_required_hint = ", and the content between {} MUST be a JSON object:" + """If a tagged content is required to be a JSON object by `parse_json` + equals to `True`, this instruction will be used to remind the model to + generate JSON object.""" + +
    +[docs] + def __init__(self, *tagged_contents: TaggedContent) -> None: + """Initialize the parser with tags. + + Args: + tags (`dict[str, Tuple[str, str]]`): + A dictionary of tags, the key is the tag name, and the value is + a tuple of starting tag and end tag. + """ + self.tagged_contents = list(tagged_contents) + + # Prepare the format instruction according to the tagged contents + tag_lines = "\n".join([str(_) for _ in tagged_contents]) + + # Prepare hint for the tagged contents that requires a JSON object. + json_required_tags = ", ".join( + [ + f"{_.tag_begin} and {_.tag_end}" + for _ in tagged_contents + if _.parse_json + ], + ) + if json_required_tags != "": + json_required_hint = self.json_required_hint.format( + json_required_tags, + ) + else: + json_required_hint = ": " + + self.format_instruction = self.format_instruction.format( + json_required_hint=json_required_hint, + tag_lines_format=tag_lines, + )
    + + +
    +[docs] + def parse(self, response: ModelResponse) -> ModelResponse: + """Parse the response text by tags, and return a dict of their content + in the parsed field of the model response object. If the tagged content + requires to parse as a JSON object by `parse_json` equals to `True`, it + will be parsed as a JSON object by `json.loads`.""" + + tag_to_content = {} + for tagged_content in self.tagged_contents: + tag_begin = tagged_content.tag_begin + tag_end = tagged_content.tag_end + + extract_content = self._extract_first_content_by_tag( + response, + tag_begin, + tag_end, + ) + + if tagged_content.parse_json: + try: + extract_content = json.loads(extract_content) + except json.decoder.JSONDecodeError as e: + raw_response = f"{tag_begin}{extract_content}{tag_end}" + raise JsonParsingError( + f"The content between {tagged_content.tag_begin} and " + f"{tagged_content.tag_end} should be a JSON object." + f'When parsing "{raw_response}", an error occurred: ' + f"{e}", + raw_response=raw_response, + ) from None + + tag_to_content[tagged_content.name] = extract_content + + response.parsed = tag_to_content + return response
    +
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/pipelines/functional.html b/en/_modules/agentscope/pipelines/functional.html index d57b9204c..e6e82d069 100644 --- a/en/_modules/agentscope/pipelines/functional.html +++ b/en/_modules/agentscope/pipelines/functional.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/pipelines/pipeline.html b/en/_modules/agentscope/pipelines/pipeline.html index 04d873af3..7f1e5b4f2 100644 --- a/en/_modules/agentscope/pipelines/pipeline.html +++ b/en/_modules/agentscope/pipelines/pipeline.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/prompt.html b/en/_modules/agentscope/prompt.html index 2139ca599..5e5b9f695 100644 --- a/en/_modules/agentscope/prompt.html +++ b/en/_modules/agentscope/prompt.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/rpc/rpc_agent_client.html b/en/_modules/agentscope/rpc/rpc_agent_client.html index 85a4d334c..eedf5165b 100644 --- a/en/_modules/agentscope/rpc/rpc_agent_client.html +++ b/en/_modules/agentscope/rpc/rpc_agent_client.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/rpc/rpc_agent_pb2_grpc.html b/en/_modules/agentscope/rpc/rpc_agent_pb2_grpc.html index 69dc77ab3..055084c6b 100644 --- a/en/_modules/agentscope/rpc/rpc_agent_pb2_grpc.html +++ b/en/_modules/agentscope/rpc/rpc_agent_pb2_grpc.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service.html b/en/_modules/agentscope/service.html index c56845aba..35ac77a35 100644 --- a/en/_modules/agentscope/service.html +++ b/en/_modules/agentscope/service.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -119,7 +121,8 @@

    Source code for agentscope.service

     from .web.search import bing_search, google_search
     from .web.arxiv import arxiv_search
     from .service_response import ServiceResponse
    -from .service_factory import ServiceFactory
    +from .service_toolkit import ServiceToolkit
    +from .service_toolkit import ServiceFactory
     from .retrieval.similarity import cos_sim
     from .text_processing.summarization import summarization
     from .retrieval.retrieval_from_list import retrieve_from_list
    @@ -140,7 +143,7 @@ 

    Source code for agentscope.service

     __all__ = [
         "ServiceResponse",
         "ServiceExecStatus",
    -    "ServiceFactory",
    +    "ServiceToolkit",
         "get_help",
         "execute_python_code",
         "execute_shell_command",
    @@ -169,6 +172,8 @@ 

    Source code for agentscope.service

         "load_web",
         "parse_html_to_text",
         "download_from_url",
    +    # to be deprecated
    +    "ServiceFactory",
     ]
     
    diff --git a/en/_modules/agentscope/service/execute_code/exec_python.html b/en/_modules/agentscope/service/execute_code/exec_python.html index 38fa5b8cf..040e2c885 100644 --- a/en/_modules/agentscope/service/execute_code/exec_python.html +++ b/en/_modules/agentscope/service/execute_code/exec_python.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/execute_code/exec_shell.html b/en/_modules/agentscope/service/execute_code/exec_shell.html index 42b73878f..af520df45 100644 --- a/en/_modules/agentscope/service/execute_code/exec_shell.html +++ b/en/_modules/agentscope/service/execute_code/exec_shell.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/file/common.html b/en/_modules/agentscope/service/file/common.html index 212d15596..6bc210f45 100644 --- a/en/_modules/agentscope/service/file/common.html +++ b/en/_modules/agentscope/service/file/common.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/file/json.html b/en/_modules/agentscope/service/file/json.html index d2b782c38..e196bdfab 100644 --- a/en/_modules/agentscope/service/file/json.html +++ b/en/_modules/agentscope/service/file/json.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/file/text.html b/en/_modules/agentscope/service/file/text.html index 9a6afe69c..e489dadc2 100644 --- a/en/_modules/agentscope/service/file/text.html +++ b/en/_modules/agentscope/service/file/text.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/retrieval/retrieval_from_list.html b/en/_modules/agentscope/service/retrieval/retrieval_from_list.html index 4be750dd9..58fbd825f 100644 --- a/en/_modules/agentscope/service/retrieval/retrieval_from_list.html +++ b/en/_modules/agentscope/service/retrieval/retrieval_from_list.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/retrieval/similarity.html b/en/_modules/agentscope/service/retrieval/similarity.html index 4d5549aa2..be9a02832 100644 --- a/en/_modules/agentscope/service/retrieval/similarity.html +++ b/en/_modules/agentscope/service/retrieval/similarity.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/service_factory.html b/en/_modules/agentscope/service/service_factory.html deleted file mode 100644 index 3c541c0e0..000000000 --- a/en/_modules/agentscope/service/service_factory.html +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - agentscope.service.service_factory — AgentScope documentation - - - - - - - - - - - - - - - - - - - - -
    - - -
    - -
    -
    -
    - -
    -
    -
    -
    - -

    Source code for agentscope.service.service_factory

    -# -*- coding: utf-8 -*-
    -"""Service factory for model prompt."""
    -import collections.abc
    -from functools import partial
    -import inspect
    -from typing import (
    -    Callable,
    -    Any,
    -    Tuple,
    -    Union,
    -    Optional,
    -    Literal,
    -    get_args,
    -    get_origin,
    -)
    -
    -try:
    -    from docstring_parser import parse
    -except ImportError:
    -    parse = None
    -from loguru import logger
    -
    -
    -def _get_type_str(cls: Any) -> Optional[Union[str, list]]:
    -    """Get the type string."""
    -    type_str = None
    -    if hasattr(cls, "__origin__"):
    -        # Typing class
    -        if cls.__origin__ is Union:
    -            type_str = [_get_type_str(_) for _ in get_args(cls)]
    -        elif cls.__origin__ is collections.abc.Sequence:
    -            type_str = "array"
    -        else:
    -            type_str = str(cls.__origin__)
    -    else:
    -        # Normal class
    -        if cls is str:
    -            type_str = "string"
    -        elif cls in [float, int, complex]:
    -            type_str = "number"
    -        elif cls is bool:
    -            type_str = "boolean"
    -        elif cls is collections.abc.Sequence:
    -            type_str = "array"
    -        elif cls is None.__class__:
    -            type_str = "null"
    -        else:
    -            type_str = cls.__name__
    -
    -    return type_str  # type: ignore[return-value]
    -
    -
    -
    -[docs] -class ServiceFactory: - """A service factory class that turns service function into string - prompt format.""" - -
    -[docs] - @classmethod - def get( - cls, - service_func: Callable[..., Any], - **kwargs: Any, - ) -> Tuple[Callable[..., Any], dict]: - """Covnert a service function into a tool function that agent can - use, and generate a dictionary in JSON Schema format that can be - used in OpenAI API directly. While for open-source model, developers - should handle the conversation from json dictionary to prompt. - - Args: - service_func (`Callable[..., Any]`): - The service function to be called. - kwargs (`Any`): - The arguments to be passed to the service function. - - Returns: - `Tuple(Callable[..., Any], dict)`: A tuple of tool function and - a dict in JSON Schema format to describe the function. - - Note: - The description of the function and arguments are extracted from - its docstring automatically, which should be well-formatted in - **Google style**. Otherwise, their descriptions in the returned - dictionary will be empty. - - Suggestions: - 1. The name of the service function should be self-explanatory, - so that the agent can understand the function and use it properly. - 2. The typing of the arguments should be provided when defining - the function (e.g. `def func(a: int, b: str, c: bool)`), so that - the agent can specify the arguments properly. - - Example: - - """ - # Get the function for agent to use - tool_func = partial(service_func, **kwargs) - - # Obtain all arguments of the service function - argsspec = inspect.getfullargspec(service_func) - - # Construct the mapping from arguments to their typings - if parse is None: - raise ImportError( - "Missing required package `docstring_parser`" - "Please install it by " - "`pip install docstring_parser`.", - ) - - docstring = parse(service_func.__doc__) - - # Function description - func_description = ( - docstring.short_description or docstring.long_description - ) - - # The arguments that requires the agent to specify - args_agent = set(argsspec.args) - set(kwargs.keys()) - - # Check if the arguments from agent have descriptions in docstring - args_description = { - _.arg_name: _.description for _ in docstring.params - } - - # Prepare default values - if argsspec.defaults is None: - args_defaults = {} - else: - args_defaults = dict( - zip( - reversed(argsspec.args), - reversed(argsspec.defaults), # type: ignore - ), - ) - - args_required = sorted( - list(set(args_agent) - set(args_defaults.keys())), - ) - - # Prepare types of the arguments, remove the return type - args_types = { - k: v for k, v in argsspec.annotations.items() if k != "return" - } - - # Prepare argument dictionary - properties_field = {} - for key in args_agent: - arg_property = {} - # type - if key in args_types: - try: - required_type = _get_type_str(args_types[key]) - arg_property["type"] = required_type - except Exception: - logger.warning( - f"Fail and skip to get the type of the " - f"argument `{key}`.", - ) - - # For Literal type, add enum field - if get_origin(args_types[key]) is Literal: - arg_property["enum"] = list(args_types[key].__args__) - - # description - if key in args_description: - arg_property["description"] = args_description[key] - - # default - if key in args_defaults and args_defaults[key] is not None: - arg_property["default"] = args_defaults[key] - - properties_field[key] = arg_property - - # Construct the JSON Schema for the service function - func_dict = { - "type": "function", - "function": { - "name": service_func.__name__, - "description": func_description, - "parameters": { - "type": "object", - "properties": properties_field, - "required": args_required, - }, - }, - } - - return tool_func, func_dict
    -
    - -
    - -
    -
    -
    - -
    - -
    -

    © Copyright 2024, Alibaba Tongyi Lab.

    -
    - - Built with Sphinx using a - theme - provided by Read the Docs. - - -
    -
    -
    -
    -
    - - - - \ No newline at end of file diff --git a/en/_modules/agentscope/service/service_response.html b/en/_modules/agentscope/service/service_response.html index 0d7482897..e7142da4e 100644 --- a/en/_modules/agentscope/service/service_response.html +++ b/en/_modules/agentscope/service/service_response.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/service_status.html b/en/_modules/agentscope/service/service_status.html index a33f434a6..e9aac81ca 100644 --- a/en/_modules/agentscope/service/service_status.html +++ b/en/_modules/agentscope/service/service_status.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/service_toolkit.html b/en/_modules/agentscope/service/service_toolkit.html new file mode 100644 index 000000000..bca6158a8 --- /dev/null +++ b/en/_modules/agentscope/service/service_toolkit.html @@ -0,0 +1,879 @@ + + + + + + + agentscope.service.service_toolkit — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for agentscope.service.service_toolkit

    +# -*- coding: utf-8 -*-
    +"""Service Toolkit for service function usage."""
    +import collections.abc
    +import json
    +from functools import partial
    +import inspect
    +from typing import (
    +    Callable,
    +    Any,
    +    Tuple,
    +    Union,
    +    Optional,
    +    Literal,
    +    get_args,
    +    get_origin,
    +    List,
    +)
    +from loguru import logger
    +
    +from ..exception import (
    +    JsonParsingError,
    +    FunctionNotFoundError,
    +    FunctionCallFormatError,
    +)
    +from .service_response import ServiceResponse
    +from .service_response import ServiceExecStatus
    +
    +try:
    +    from docstring_parser import parse
    +except ImportError:
    +    parse = None
    +
    +
    +def _get_type_str(cls: Any) -> Optional[Union[str, list]]:
    +    """Get the type string."""
    +    type_str = None
    +    if hasattr(cls, "__origin__"):
    +        # Typing class
    +        if cls.__origin__ is Union:
    +            type_str = [_get_type_str(_) for _ in get_args(cls)]
    +        elif cls.__origin__ is collections.abc.Sequence:
    +            type_str = "array"
    +        else:
    +            type_str = str(cls.__origin__)
    +    else:
    +        # Normal class
    +        if cls is str:
    +            type_str = "string"
    +        elif cls in [float, int, complex]:
    +            type_str = "number"
    +        elif cls is bool:
    +            type_str = "boolean"
    +        elif cls is collections.abc.Sequence:
    +            type_str = "array"
    +        elif cls is None.__class__:
    +            type_str = "null"
    +        else:
    +            type_str = cls.__name__
    +
    +    return type_str  # type: ignore[return-value]
    +
    +
    +
    +[docs] +class ServiceFunction: + """The service function class.""" + + name: str + """The name of the service function.""" + + original_func: Callable + """The original function before processing.""" + + processed_func: Callable + """The processed function that can be called by the model directly.""" + + json_schema: dict + """The JSON schema description of the service function.""" + + require_args: bool + """Whether calling the service function requests arguments. Some arguments + may have default values, so it is not necessary to provide all arguments. + """ + +
    +[docs] + def __init__( + self, + name: str, + original_func: Callable, + processed_func: Callable, + json_schema: dict, + ) -> None: + """Initialize the service function object.""" + + self.name = name + self.original_func = original_func + self.processed_func = processed_func + self.json_schema = json_schema + + self.require_args = ( + len( + json_schema["function"] + .get("parameters", {}) + .get("required", []), + ) + != 0 + )
    +
    + + + +
    +[docs] +class ServiceToolkit: + """A service toolkit class that turns service function into string + prompt format.""" + + service_funcs: dict[str, ServiceFunction] + """The registered functions in the service toolkit.""" + + _tools_instruction_format: str = ( + "## Tool Functions:\n" + "The following tool functions are available in the format of\n" + "```\n" + "{{index}}. {{function name}}: {{function description}}\n" + "{{argument1 name}} ({{argument type}}): {{argument description}}\n" + "{{argument2 name}} ({{argument type}}): {{argument description}}\n" + "...\n" + "```\n\n" + "{function_prompt}\n" + ) + """The instruction template for the tool functions.""" + + _tools_calling_format: str = ( + '[{"name": "{function name}", "arguments": {"{argument1 name}": xxx,' + ' "{argument2 name}": xxx}}]' + ) + """The format of the tool function call.""" + + _tools_execution_format: str = ( + "{index}. Execute function {function_name}\n" + " [ARGUMENTS]:\n" + " {arguments}\n" + " [STATUS]: {status}\n" + " [RESULT]: {result}\n" + ) + """The prompt template for the execution results.""" + +
    +[docs] + def __init__(self) -> None: + """Initialize the service toolkit with a list of service functions.""" + self.service_funcs = {}
    + + +
    +[docs] + def add(self, service_func: Callable[..., Any], **kwargs: Any) -> None: + """Add a service function to the toolkit, which will be processed into + a tool function that can be called by the model directly, and + registered in processed_funcs. + + Args: + service_func (`Callable[..., Any]`): + The service function to be called. + kwargs (`Any`): + The arguments to be passed to the service function. + + Returns: + `Tuple(Callable[..., Any], dict)`: A tuple of tool function and + a dict in JSON Schema format to describe the function. + + Note: + The description of the function and arguments are extracted from + its docstring automatically, which should be well-formatted in + **Google style**. Otherwise, their descriptions in the returned + dictionary will be empty. + + Suggestions: + 1. The name of the service function should be self-explanatory, + so that the agent can understand the function and use it properly. + 2. The typing of the arguments should be provided when defining + the function (e.g. `def func(a: int, b: str, c: bool)`), so that + the agent can specify the arguments properly. + 3. The execution results should be a `ServiceResponse` object. + + Example: + + .. code-block:: python + + def bing_search(query: str, api_key: str, num_results=10): + \"""Search the query in Bing search engine. + + Args: + query: (`str`): + The string query to search. + api_key: (`str`): + The API key for Bing search. + num_results: (`int`, optional): + The number of results to return, default to 10. + \""" + + # ... Your implementation here ... + return ServiceResponse(status, output) + + """ + + processed_func, json_schema = ServiceToolkit.get( + service_func, + **kwargs, + ) + + # register the service function + name = service_func.__name__ + if name in self.service_funcs: + logger.warning( + f"Service function `{name}` already exists, " + f"skip adding it.", + ) + else: + self.service_funcs[name] = ServiceFunction( + name=name, + original_func=service_func, + processed_func=processed_func, + json_schema=json_schema, + )
    + + + @property + def json_schemas(self) -> dict: + """The json schema descriptions of the processed service funcs.""" + return {k: v.json_schema for k, v in self.service_funcs.items()} + + @property + def tools_calling_format(self) -> str: + """The calling format of the tool functions.""" + return self._tools_calling_format + + @property + def tools_instruction(self) -> str: + """The instruction of the tool functions.""" + tools_prompt = [] + for i, (func_name, desc) in enumerate(self.json_schemas.items()): + func_desc = desc["function"]["description"] + args_desc = desc["function"]["parameters"]["properties"] + + args_list = [f"{i + 1}. {func_name}: {func_desc}"] + for args_name, args_info in args_desc.items(): + if "type" in args_info: + args_line = ( + f'\t{args_name} ({args_info["type"]}): ' + f'{args_info.get("description", "")}' + ) + else: + args_line = ( + f'\t{args_name}: {args_info.get("description", "")}' + ) + args_list.append(args_line) + + func_prompt = "\n".join(args_list) + tools_prompt.append(func_prompt) + + tools_description = "\n".join(tools_prompt) + + if tools_description == "": + # No tools are provided + return "" + else: + return self._tools_instruction_format.format_map( + {"function_prompt": tools_description}, + ) + + def _parse_and_check_text(self, cmd: Union[list[dict], str]) -> List[dict]: + """Parsing and check the format of the function calling text.""" + + # Record the error + error_info = [] + + if isinstance(cmd, str): + # --- Syntax check: if the input can be loaded by JSON + try: + processed_text = cmd.strip() + + # complete "[" and "]" if they are missing + index_start = processed_text.find("[") + index_end = processed_text.rfind("]") + + if index_start == -1: + index_start = 0 + error_info.append('Missing "[" at the beginning.') + + if index_end == -1: + index_end = len(processed_text) + error_info.append('Missing "]" at the end.') + + # remove the unnecessary prefix before "[" and suffix after "]" + processed_text = processed_text[ + index_start : index_end + 1 # noqa: E203 + ] + + cmds = json.loads(processed_text) + except json.JSONDecodeError: + # Since we have processed the text, here we can only report + # the JSON parsing error + raise JsonParsingError( + f"Except a list of dictionaries in JSON format, " + f"like: {self.tools_calling_format}", + ) from None + else: + cmds = cmd + + # --- Semantic Check: if the input is a list of dicts with + # required fields + + # Handle the case when the input is a single dictionary + if isinstance(cmds, dict): + # The error info is already recorded in error_info + cmds = [cmds] + + if not isinstance(cmds, list): + # Not list, raise parsing error + raise JsonParsingError( + f"Except a list of dictionaries in JSON format " + f"like: {self.tools_calling_format}", + ) + + # --- Check the format of the command --- + for sub_cmd in cmds: + if not isinstance(sub_cmd, dict): + raise JsonParsingError( + f"Except a JSON list of dictionaries, but got" + f" {type(sub_cmd)} instead.", + ) + + if "name" not in sub_cmd: + raise FunctionCallFormatError( + "The field 'name' is required in the dictionary.", + ) + + # Obtain the service function + func_name = sub_cmd["name"] + + # Cannot find the service function + if func_name not in self.service_funcs: + raise FunctionNotFoundError( + f"Cannot find a tool function named `{func_name}`.", + ) + + # Type error for the arguments + if not isinstance(sub_cmd["arguments"], dict): + raise FunctionCallFormatError( + "Except a dictionary for the arguments, but got " + f"{type(sub_cmd['arguments'])} instead.", + ) + + # Leaving the type checking and required checking to the runtime + # error reporting during execution + return cmds + + def _execute_func(self, cmds: List[dict]) -> str: + """Execute the function with the arguments. + + Args: + cmds (`List[dict]`): + A list of dictionaries, where each dictionary contains the + name of the function and its arguments, e.g. {"name": "func1", + "arguments": {"arg1": 1, "arg2": 2}}. + + Returns: + `str`: The prompt of the execution results. + """ + + execute_results = [] + for i, cmd in enumerate(cmds): + func_name = cmd["name"] + service_func = self.service_funcs[cmd["name"]] + kwargs = cmd.get("arguments", {}) + + print(f">>> Executing function {func_name} with arguments:") + for key, value in kwargs.items(): + value = ( + value if len(str(value)) < 50 else str(value)[:50] + "..." + ) + print(f">>> \t{key}: {value}") + + # Execute the function + try: + func_res = service_func.processed_func(**kwargs) + except Exception as e: + func_res = ServiceResponse( + status=ServiceExecStatus.ERROR, + content=str(e), + ) + + print(">>> END ") + + status = ( + "SUCCESS" + if func_res.status == ServiceExecStatus.SUCCESS + else "FAILED" + ) + + arguments = [f"{k}: {v}" for k, v in kwargs.items()] + + execute_res = self._tools_execution_format.format_map( + { + "index": i + 1, + "function_name": cmd["name"], + "arguments": "\n\t\t".join(arguments), + "status": status, + "result": func_res.content, + }, + ) + + execute_results.append(execute_res) + + execute_results_prompt = "\n".join(execute_results) + + return execute_results_prompt + +
    +[docs] + def parse_and_call_func(self, text_cmd: Union[list[dict], str]) -> str: + """Parse, check the text and call the function.""" + + # --- Step 1: Parse the text according to the tools_call_format + cmds = self._parse_and_check_text(text_cmd) + + # --- Step 2: Call the service function --- + + execute_results_prompt = self._execute_func(cmds) + + return execute_results_prompt
    + + +
    +[docs] + @classmethod + def get( + cls, + service_func: Callable[..., Any], + **kwargs: Any, + ) -> Tuple[Callable[..., Any], dict]: + """Convert a service function into a tool function that agent can + use, and generate a dictionary in JSON Schema format that can be + used in OpenAI API directly. While for open-source model, developers + should handle the conversation from json dictionary to prompt. + + Args: + service_func (`Callable[..., Any]`): + The service function to be called. + kwargs (`Any`): + The arguments to be passed to the service function. + + Returns: + `Tuple(Callable[..., Any], dict)`: A tuple of tool function and + a dict in JSON Schema format to describe the function. + + Note: + The description of the function and arguments are extracted from + its docstring automatically, which should be well-formatted in + **Google style**. Otherwise, their descriptions in the returned + dictionary will be empty. + + Suggestions: + 1. The name of the service function should be self-explanatory, + so that the agent can understand the function and use it properly. + 2. The typing of the arguments should be provided when defining + the function (e.g. `def func(a: int, b: str, c: bool)`), so that + the agent can specify the arguments properly. + + Example: + + .. code-block:: python + + def bing_search(query: str, api_key: str, num_results: int=10): + '''Search the query in Bing search engine. + + Args: + query (str): + The string query to search. + api_key (str): + The API key for Bing search. + num_results (int): + The number of results to return, default to 10. + ''' + pass + + + """ + # Get the function for agent to use + tool_func = partial(service_func, **kwargs) + + # Obtain all arguments of the service function + argsspec = inspect.getfullargspec(service_func) + + # Construct the mapping from arguments to their typings + if parse is None: + raise ImportError( + "Missing required package `docstring_parser`" + "Please install it by " + "`pip install docstring_parser`.", + ) + + docstring = parse(service_func.__doc__) + + # Function description + func_description = ( + docstring.short_description or docstring.long_description + ) + + # The arguments that requires the agent to specify + args_agent = set(argsspec.args) - set(kwargs.keys()) + + # Check if the arguments from agent have descriptions in docstring + args_description = { + _.arg_name: _.description for _ in docstring.params + } + + # Prepare default values + if argsspec.defaults is None: + args_defaults = {} + else: + args_defaults = dict( + zip( + reversed(argsspec.args), + reversed(argsspec.defaults), # type: ignore + ), + ) + + args_required = sorted( + list(set(args_agent) - set(args_defaults.keys())), + ) + + # Prepare types of the arguments, remove the return type + args_types = { + k: v for k, v in argsspec.annotations.items() if k != "return" + } + + # Prepare argument dictionary + properties_field = {} + for key in args_agent: + arg_property = {} + # type + if key in args_types: + try: + required_type = _get_type_str(args_types[key]) + arg_property["type"] = required_type + except Exception: + logger.warning( + f"Fail and skip to get the type of the " + f"argument `{key}`.", + ) + + # For Literal type, add enum field + if get_origin(args_types[key]) is Literal: + arg_property["enum"] = list(args_types[key].__args__) + + # description + if key in args_description: + arg_property["description"] = args_description[key] + + # default + if key in args_defaults and args_defaults[key] is not None: + arg_property["default"] = args_defaults[key] + + properties_field[key] = arg_property + + # Construct the JSON Schema for the service function + func_dict = { + "type": "function", + "function": { + "name": service_func.__name__, + "description": func_description, + "parameters": { + "type": "object", + "properties": properties_field, + "required": args_required, + }, + }, + } + + return tool_func, func_dict
    +
    + + + +
    +[docs] +class ServiceFactory: + """A service factory class that turns service function into string + prompt format.""" + +
    +[docs] + @classmethod + def get( + cls, + service_func: Callable[..., Any], + **kwargs: Any, + ) -> Tuple[Callable[..., Any], dict]: + """Convert a service function into a tool function that agent can + use, and generate a dictionary in JSON Schema format that can be + used in OpenAI API directly. While for open-source model, developers + should handle the conversation from json dictionary to prompt. + + Args: + service_func (`Callable[..., Any]`): + The service function to be called. + kwargs (`Any`): + The arguments to be passed to the service function. + + Returns: + `Tuple(Callable[..., Any], dict)`: A tuple of tool function and + a dict in JSON Schema format to describe the function. + + Note: + The description of the function and arguments are extracted from + its docstring automatically, which should be well-formatted in + **Google style**. Otherwise, their descriptions in the returned + dictionary will be empty. + + Suggestions: + 1. The name of the service function should be self-explanatory, + so that the agent can understand the function and use it properly. + 2. The typing of the arguments should be provided when defining + the function (e.g. `def func(a: int, b: str, c: bool)`), so that + the agent can specify the arguments properly. + + Example: + + .. code-block:: python + + def bing_search(query: str, api_key: str, num_results: int=10): + '''Search the query in Bing search engine. + + Args: + query (str): + The string query to search. + api_key (str): + The API key for Bing search. + num_results (int): + The number of results to return, default to 10. + ''' + pass + + + """ + logger.warning( + "The service factory will be deprecated in the future." + " Try to use the `ServiceToolkit` class instead.", + ) + + # Get the function for agent to use + tool_func = partial(service_func, **kwargs) + + # Obtain all arguments of the service function + argsspec = inspect.getfullargspec(service_func) + + # Construct the mapping from arguments to their typings + if parse is None: + raise ImportError( + "Missing required package `docstring_parser`" + "Please install it by " + "`pip install docstring_parser`.", + ) + + docstring = parse(service_func.__doc__) + + # Function description + func_description = ( + docstring.short_description or docstring.long_description + ) + + # The arguments that requires the agent to specify + args_agent = set(argsspec.args) - set(kwargs.keys()) + + # Check if the arguments from agent have descriptions in docstring + args_description = { + _.arg_name: _.description for _ in docstring.params + } + + # Prepare default values + if argsspec.defaults is None: + args_defaults = {} + else: + args_defaults = dict( + zip( + reversed(argsspec.args), + reversed(argsspec.defaults), # type: ignore + ), + ) + + args_required = sorted( + list(set(args_agent) - set(args_defaults.keys())), + ) + + # Prepare types of the arguments, remove the return type + args_types = { + k: v for k, v in argsspec.annotations.items() if k != "return" + } + + # Prepare argument dictionary + properties_field = {} + for key in args_agent: + arg_property = {} + # type + if key in args_types: + try: + required_type = _get_type_str(args_types[key]) + arg_property["type"] = required_type + except Exception: + logger.warning( + f"Fail and skip to get the type of the " + f"argument `{key}`.", + ) + + # For Literal type, add enum field + if get_origin(args_types[key]) is Literal: + arg_property["enum"] = list(args_types[key].__args__) + + # description + if key in args_description: + arg_property["description"] = args_description[key] + + # default + if key in args_defaults and args_defaults[key] is not None: + arg_property["default"] = args_defaults[key] + + properties_field[key] = arg_property + + # Construct the JSON Schema for the service function + func_dict = { + "type": "function", + "function": { + "name": service_func.__name__, + "description": func_description, + "parameters": { + "type": "object", + "properties": properties_field, + "required": args_required, + }, + }, + } + + return tool_func, func_dict
    +
    + +
    + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/_modules/agentscope/service/sql_query/mongodb.html b/en/_modules/agentscope/service/sql_query/mongodb.html index 9bc8e3a32..39b220c5a 100644 --- a/en/_modules/agentscope/service/sql_query/mongodb.html +++ b/en/_modules/agentscope/service/sql_query/mongodb.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/sql_query/mysql.html b/en/_modules/agentscope/service/sql_query/mysql.html index 6118df6ac..5653a7eb7 100644 --- a/en/_modules/agentscope/service/sql_query/mysql.html +++ b/en/_modules/agentscope/service/sql_query/mysql.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -102,7 +104,7 @@

    Source code for agentscope.service.sql_query.mysql

    from typing import Any from ..service_response import ServiceResponse -from ...utils.common import if_change_database +from ...utils.common import _if_change_database from ...service.service_status import ServiceExecStatus try: @@ -153,7 +155,7 @@

    Source code for agentscope.service.sql_query.mysql

    """ # Check if the query is safe - if not allow_change_data and not if_change_database(query): + if not allow_change_data and not _if_change_database(query): raise ValueError( "Unsafe SQL query detected. Only SELECT statements are allowed. " "If you want to allow changing data in the database, " @@ -180,7 +182,7 @@

    Source code for agentscope.service.sql_query.mysql

    cursor = conn.cursor() cursor.execute(query) - if if_change_database(query): + if _if_change_database(query): conn.commit() cursor.close() diff --git a/en/_modules/agentscope/service/sql_query/sqlite.html b/en/_modules/agentscope/service/sql_query/sqlite.html index 96c7e8044..4da53a538 100644 --- a/en/_modules/agentscope/service/sql_query/sqlite.html +++ b/en/_modules/agentscope/service/sql_query/sqlite.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -102,7 +104,7 @@

    Source code for agentscope.service.sql_query.sqlite

    from typing import Any from ...service.service_response import ServiceResponse -from ...utils.common import if_change_database +from ...utils.common import _if_change_database from ...service.service_status import ServiceExecStatus try: @@ -139,7 +141,7 @@

    Source code for agentscope.service.sql_query.sqlite

    """ # Check if the query is safe - if not allow_change_data and not if_change_database(query): + if not allow_change_data and not _if_change_database(query): raise ValueError( "Unsafe SQL query detected. Only SELECT statements are allowed. " "If you want to allow changing data in the database, " @@ -158,7 +160,7 @@

    Source code for agentscope.service.sql_query.sqlite

    results = cursor.fetchall() # commit the change if needed - if if_change_database(query): + if _if_change_database(query): conn.commit() cursor.close() diff --git a/en/_modules/agentscope/service/text_processing/summarization.html b/en/_modules/agentscope/service/text_processing/summarization.html index b712f96a0..6a4b9b8eb 100644 --- a/en/_modules/agentscope/service/text_processing/summarization.html +++ b/en/_modules/agentscope/service/text_processing/summarization.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/web/arxiv.html b/en/_modules/agentscope/service/web/arxiv.html index 5984d67fa..87fa6c797 100644 --- a/en/_modules/agentscope/service/web/arxiv.html +++ b/en/_modules/agentscope/service/web/arxiv.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/web/download.html b/en/_modules/agentscope/service/web/download.html index 91641af70..ebf3b8972 100644 --- a/en/_modules/agentscope/service/web/download.html +++ b/en/_modules/agentscope/service/web/download.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/web/search.html b/en/_modules/agentscope/service/web/search.html index 008ae15a1..eef157de0 100644 --- a/en/_modules/agentscope/service/web/search.html +++ b/en/_modules/agentscope/service/web/search.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/service/web/web_digest.html b/en/_modules/agentscope/service/web/web_digest.html index 5f510bfee..9aae158ba 100644 --- a/en/_modules/agentscope/service/web/web_digest.html +++ b/en/_modules/agentscope/service/web/web_digest.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/utils/common.html b/en/_modules/agentscope/utils/common.html index d81dab63b..07fc5f1af 100644 --- a/en/_modules/agentscope/utils/common.html +++ b/en/_modules/agentscope/utils/common.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -106,7 +108,6 @@

    Source code for agentscope.utils.common

     import tempfile
     import threading
     from typing import Any, Generator, Optional, Union
    -from loguru import logger
     import requests
     
     from agentscope.service.service_response import ServiceResponse
    @@ -268,7 +269,6 @@ 

    Source code for agentscope.utils.common

             # This will raise an exception for HTTP error codes
             response.raise_for_status()
         except requests.RequestException as e:
    -        logger.error(e)
             return str(e)
         # Parse the JSON response
         search_results = response.json()
    @@ -276,9 +276,7 @@ 

    Source code for agentscope.utils.common

     
     
     
    -
    -[docs] -def if_change_database(sql_query: str) -> bool: +def _if_change_database(sql_query: str) -> bool: """Check whether SQL query only contains SELECT query""" # Compile the regex pattern outside the function for better performance pattern_unsafe_sql = re.compile( @@ -293,8 +291,7 @@

    Source code for agentscope.utils.common

         # Matching non-SELECT statements with regular expressions
         if pattern_unsafe_sql.search(sql_query):
             return False
    -    return True
    - + return True
    diff --git a/en/_modules/agentscope/utils/logging_utils.html b/en/_modules/agentscope/utils/logging_utils.html index 3e25e8097..4a0d99f61 100644 --- a/en/_modules/agentscope/utils/logging_utils.html +++ b/en/_modules/agentscope/utils/logging_utils.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/utils/monitor.html b/en/_modules/agentscope/utils/monitor.html index 63e816a9c..0964020f5 100644 --- a/en/_modules/agentscope/utils/monitor.html +++ b/en/_modules/agentscope/utils/monitor.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/utils/token_utils.html b/en/_modules/agentscope/utils/token_utils.html index e0f0e1fef..ff982e777 100644 --- a/en/_modules/agentscope/utils/token_utils.html +++ b/en/_modules/agentscope/utils/token_utils.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/utils/tools.html b/en/_modules/agentscope/utils/tools.html index 74a57dd70..c6ea39d96 100644 --- a/en/_modules/agentscope/utils/tools.html +++ b/en/_modules/agentscope/utils/tools.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -102,7 +104,7 @@

    Source code for agentscope.utils.tools

     import json
     import secrets
     import string
    -from typing import Any, Literal
    +from typing import Any, Literal, List
     
     from urllib.parse import urlparse
     
    @@ -347,6 +349,20 @@ 

    Source code for agentscope.utils.tools

             return json.dumps(content, ensure_ascii=False)
         else:
             return str(content)
    +
    +
    +def _join_str_with_comma_and(elements: List[str]) -> str:
    +    """Return the JSON string with comma, and use " and " between the last two
    +    elements."""
    +
    +    if len(elements) == 0:
    +        return ""
    +    elif len(elements) == 1:
    +        return elements[0]
    +    elif len(elements) == 2:
    +        return " and ".join(elements)
    +    else:
    +        return ", ".join(elements[:-1]) + f", and {elements[-1]}"
     
    diff --git a/en/_modules/agentscope/web/_app.html b/en/_modules/agentscope/web/_app.html index 7a1a445b6..0fee740b3 100644 --- a/en/_modules/agentscope/web/_app.html +++ b/en/_modules/agentscope/web/_app.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/studio/studio.html b/en/_modules/agentscope/web/studio/studio.html index bb52ad5af..192e8d72c 100644 --- a/en/_modules/agentscope/web/studio/studio.html +++ b/en/_modules/agentscope/web/studio/studio.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/studio/utils.html b/en/_modules/agentscope/web/studio/utils.html index 5e5aa034e..04037987b 100644 --- a/en/_modules/agentscope/web/studio/utils.html +++ b/en/_modules/agentscope/web/studio/utils.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/workstation/workflow.html b/en/_modules/agentscope/web/workstation/workflow.html index ad6ce0f2a..5f25948e8 100644 --- a/en/_modules/agentscope/web/workstation/workflow.html +++ b/en/_modules/agentscope/web/workstation/workflow.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/workstation/workflow_dag.html b/en/_modules/agentscope/web/workstation/workflow_dag.html index 0f23a7545..eeee92f63 100644 --- a/en/_modules/agentscope/web/workstation/workflow_dag.html +++ b/en/_modules/agentscope/web/workstation/workflow_dag.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/workstation/workflow_node.html b/en/_modules/agentscope/web/workstation/workflow_node.html index 21660ac1a..9f5bdb76f 100644 --- a/en/_modules/agentscope/web/workstation/workflow_node.html +++ b/en/_modules/agentscope/web/workstation/workflow_node.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/agentscope/web/workstation/workflow_utils.html b/en/_modules/agentscope/web/workstation/workflow_utils.html index 649819da2..a901a719d 100644 --- a/en/_modules/agentscope/web/workstation/workflow_utils.html +++ b/en/_modules/agentscope/web/workstation/workflow_utils.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/_modules/index.html b/en/_modules/index.html index ecd962f81..17cc9e188 100644 --- a/en/_modules/index.html +++ b/en/_modules/index.html @@ -62,6 +62,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -104,6 +106,7 @@

    All modules for which code is available

  • agentscope.agents.text_to_image_agent
  • agentscope.agents.user_agent
  • agentscope.constants
  • +
  • agentscope.exception
  • agentscope.memory.memory
  • agentscope.memory.temporary_memory
  • agentscope.message
  • @@ -116,6 +119,10 @@

    All modules for which code is available

  • agentscope.models.post_model
  • agentscope.models.response
  • agentscope.msghub
  • +
  • agentscope.parsers.code_block_parser
  • +
  • agentscope.parsers.json_object_parser
  • +
  • agentscope.parsers.parser_base
  • +
  • agentscope.parsers.tagged_content_parser
  • agentscope.pipelines.functional
  • agentscope.pipelines.pipeline
  • agentscope.prompt
  • @@ -129,9 +136,9 @@

    All modules for which code is available

  • agentscope.service.file.text
  • agentscope.service.retrieval.retrieval_from_list
  • agentscope.service.retrieval.similarity
  • -
  • agentscope.service.service_factory
  • agentscope.service.service_response
  • agentscope.service.service_status
  • +
  • agentscope.service.service_toolkit
  • agentscope.service.sql_query.mongodb
  • agentscope.service.sql_query.mysql
  • agentscope.service.sql_query.sqlite
  • diff --git a/en/_sources/agentscope.exception.rst.txt b/en/_sources/agentscope.exception.rst.txt new file mode 100644 index 000000000..9ef713c41 --- /dev/null +++ b/en/_sources/agentscope.exception.rst.txt @@ -0,0 +1,6 @@ +agentscope.exception +==================== +.. automodule:: agentscope.exception + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/en/_sources/agentscope.parsers.code_block_parser.rst.txt b/en/_sources/agentscope.parsers.code_block_parser.rst.txt new file mode 100644 index 000000000..0249375e0 --- /dev/null +++ b/en/_sources/agentscope.parsers.code_block_parser.rst.txt @@ -0,0 +1,6 @@ +agentscope.parsers.code_block_parser +==================================== +.. automodule:: agentscope.parsers.code_block_parser + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/en/_sources/agentscope.parsers.json_object_parser.rst.txt b/en/_sources/agentscope.parsers.json_object_parser.rst.txt new file mode 100644 index 000000000..e369969b4 --- /dev/null +++ b/en/_sources/agentscope.parsers.json_object_parser.rst.txt @@ -0,0 +1,6 @@ +agentscope.parsers.json_object_parser +===================================== +.. automodule:: agentscope.parsers.json_object_parser + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/en/_sources/agentscope.parsers.parser_base.rst.txt b/en/_sources/agentscope.parsers.parser_base.rst.txt new file mode 100644 index 000000000..f9e6b2d66 --- /dev/null +++ b/en/_sources/agentscope.parsers.parser_base.rst.txt @@ -0,0 +1,6 @@ +agentscope.parsers.parser_base +============================== +.. automodule:: agentscope.parsers.parser_base + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/en/_sources/agentscope.parsers.rst.txt b/en/_sources/agentscope.parsers.rst.txt new file mode 100644 index 000000000..e081ce0e8 --- /dev/null +++ b/en/_sources/agentscope.parsers.rst.txt @@ -0,0 +1,7 @@ +agentscope.parsers +================== + +.. automodule:: agentscope.parsers + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/en/_sources/agentscope.parsers.tagged_content_parser.rst.txt b/en/_sources/agentscope.parsers.tagged_content_parser.rst.txt new file mode 100644 index 000000000..bfbdaa5e8 --- /dev/null +++ b/en/_sources/agentscope.parsers.tagged_content_parser.rst.txt @@ -0,0 +1,6 @@ +agentscope.parsers.tagged_content_parser +======================================== +.. automodule:: agentscope.parsers.tagged_content_parser + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/zh_CN/_sources/agentscope.service.service_factory.rst.txt b/en/_sources/agentscope.service.service_toolkit.rst.txt similarity index 50% rename from zh_CN/_sources/agentscope.service.service_factory.rst.txt rename to en/_sources/agentscope.service.service_toolkit.rst.txt index cf4ab1d5b..b9765a4dd 100644 --- a/zh_CN/_sources/agentscope.service.service_factory.rst.txt +++ b/en/_sources/agentscope.service.service_toolkit.rst.txt @@ -1,6 +1,6 @@ -agentscope.service.service_factory +agentscope.service.service_toolkit ================================== -.. automodule:: agentscope.service.service_factory +.. automodule:: agentscope.service.service_toolkit :members: :undoc-members: :show-inheritance: \ No newline at end of file diff --git a/en/_sources/index.rst.txt b/en/_sources/index.rst.txt index 091134860..fb81e2e64 100644 --- a/en/_sources/index.rst.txt +++ b/en/_sources/index.rst.txt @@ -33,6 +33,8 @@ AgentScope Documentation agentscope.models agentscope.agents agentscope.memory + agentscope.parsers + agentscope.exception agentscope.pipelines agentscope.service agentscope.rpc diff --git a/en/_sources/tutorial/204-service.md.txt b/en/_sources/tutorial/204-service.md.txt index 826b1fec6..30d82242d 100644 --- a/en/_sources/tutorial/204-service.md.txt +++ b/en/_sources/tutorial/204-service.md.txt @@ -44,30 +44,38 @@ About each service function, you can find detailed information in the ## How to use Service Functions -AgentScope provides two service classes for Service functions, -`ServiceFactory` and `ServiceResponse`. - -- `ServiceFactory` is mainly used to convert general Python functions into - a form that can be directly used by large-scale models, and automatically - generate function descriptions in JSON schema format. -- `ServiceResponse` is a subclass of a dictionary, providing a unified call - result interface for all Service functions. - -### About Service Factory - -The tools used by agents are generally of the function type. Developers -need to prepare functions that can be called directly by large models, and -provide descriptions of the functions. However, general functions often -require developers to provide some parameters (such as keys, usernames, -specific URLs, etc.), and then the large model can use them. At the same -time, it is also a tedious task to generate specific format descriptions -for multiple functions. - -To tackle the above problems, AgentScope introduces `ServiceFactory`. For a -given Service function, it allows developers to specify some parameters, -generate a function that can be called directly by large models, and -automatically generate function descriptions based on the Docstring. Take -the Bing web search function as an example. +AgentScope provides two classes for service functions, +`ServiceToolkit` and `ServiceResponse`. + +### About Service Toolkit + +The use of tools for LLM usually involves five steps: + +1. **Prepare tool functions**. That is, developers should pre-process the +functions by providing necessary parameters, e.g. api key, username, +password, etc. +2. **Prepare instruction for LLM**. A detailed description for these tool +functions are required for the LLM to understand them properly. +3. **Guide LLM how to use tool functions**. A format description for calling +functions is required. +4. **Parse LLM response**. Once the LLM generates a response, +we need to parse it according to above format in the third step. +5. **Call functions and handle exceptions**. Calling the functions, return +the results, and handle exceptions. + +To simplify the above steps and improve reusability, AgentScope introduces +`ServiceToolkit`. It can +- register python functions +- generate tool function descriptions in both string and JSON schema format +- generate usage instruction for LLM +- parse the model response, call the tool functions, and handle exceptions + +#### How to use + +Follow the steps below to use `ServiceToolkit`: + +1. Init a `ServiceToolkit` object and register service functions with necessary +parameters. Take the following Bing search function as an example. ```python def bing_search( @@ -95,73 +103,114 @@ def bing_search( """ ``` -In the above function, `question` is the field filled in by the large model, -while `api_key` and `num_results` are the parameters that the developer needs to provide. -We use the `get` function of `ServiceFactory` to process it: +We register the function in a `ServiceToolkit` object by providing `api_key` and `num_results` as necessary parameters. ```python -from agentscope.service import ServiceFactory +from agentscope.service import ServiceToolkit + +service_toolkit = ServiceToolkit() -func, func_intro = ServiceFactory.get( +service_toolkit.add( bing_search, api_key="xxx", - num_results=3) + num_results=3 +) ``` -In the above code, the `func` generated by ServiceFactory is equivalent to the following function: +2. Use the `tools_instruction` attribute to instruct LLM in prompt, or use the `json_schemas` attribute to get the JSON schema format descriptions to construct customized instruction or directly use in model APIs (e.g. OpenAI Chat API). -```python -def bing_search(question: str) -> ServiceResponse: - """ - Search question in Bing Search API and return the searching results +````text +>> print(service_toolkit.tools_instruction) +## Tool Functions: +The following tool functions are available in the format of +``` +{index}. {function name}: {function description} +{argument1 name} ({argument type}): {argument description} +{argument2 name} ({argument type}): {argument description} +... +``` - Args: - question (`str`): - The search query string. - """ - return bing_search(question, api_key="xxx", num_results=3) +1. bing_search: Search question in Bing Search API and return the searching results + question (str): The search query string. +```` +````text +>> print(service_toolkit.json_schemas) +{ + "bing_search": { + "type": "function", + "function": { + "name": "bing_search", + "description": "Search question in Bing Search API and return the searching results", + "parameters": { + "type": "object", + "properties": { + "question": { + "type": "string", + "description": "The search query string." + } + }, + "required": [ + "question" + ] + } + } + } +} +```` + +3. Guide LLM how to use tool functions by the `tools_calling_format` attribute. +The ServiceToolkit module requires LLM to return a list of dictionaries in +JSON format, where each dictionary represents a function call. It must +contain two fields, `name` and `arguments`, where `name` is the function name +and `arguments` is a dictionary that maps from the argument name to the +argument value. + + +```text +>> print(service_toolkit.tools_calling_format) +[{"name": "{function name}", "arguments": {"{argument1 name}": xxx, "{argument2 name}": xxx}}] ``` -The generated JSON schema format is as follows, which can be directly used -in the `tools` field of the OpenAI API. +4. Parse the LLM response and call functions by its `parse_and_call_func` +method. This function takes a string or a parsed dictionary as input. +- When the input is a string, this function will parse it accordingly and execute the function with the parsed arguments. +- While if the input is a parse dictionary, it will call the function directly. ```python -# print(func_intro) -{ - "type": "function", - "function": { - "name": "bing_search", - "description": "Search question in Bing Search API and return the searching results", - "parameters": { - "type": "object", - "properties": { - "question": { - "type": "string", - "description": "The search query string." - } - }, - "required": [ - "question" - ] - } - } -} +# a string input +string_input = '[{"name": "bing_search", "arguments": {"question": "xxx"}}]' +res_of_string_input = service_toolkit.parse_and_call_func(string_input) + +# or a parsed dictionary +dict_input = [{"name": "bing_search", "arguments": {"question": "xxx"}}] +# res_of_dict_input is the same as res_of_string_input +res_of_dict_input = service_toolkit.parse_and_call_func(dict_input) + +print(res_of_string_input) +``` ``` +1. Execute function bing_search + [ARGUMENTS]: + question: xxx + [STATUS]: SUCCESS + [RESULT]: ... +``` + +More specific examples refer to the `ReActAgent` class in `agentscope.agents`. -**Note**: -The description of the function and arguments are extracted from -its docstring automatically, which should be well-formatted in -**Google style**. Otherwise, their descriptions in the returned -dictionary will be empty. +#### Create new Service Function -**Suggestions**: +A new service function that can be used by `ServiceToolkit` should meet the following requirements: -1. The name of the service function should be self-explanatory, -so that the agent can understand the function and use it properly. -2. The typing of the arguments should be provided when defining +1. Well-formatted docstring (Google style is recommended), so that the +`ServiceToolkit` can extract both the function descriptions. +2. The name of the service function should be self-explanatory, +so that the LLM can understand the function and use it properly. +3. The typing of the arguments should be provided when defining the function (e.g. `def func(a: int, b: str, c: bool)`), so that the agent can specify the arguments properly. + ### About ServiceResponse `ServiceResponse` is a wrapper for the execution results of the services, diff --git a/en/agentscope.agents.agent.html b/en/agentscope.agents.agent.html index 7bc98f138..5ad14cc70 100644 --- a/en/agentscope.agents.agent.html +++ b/en/agentscope.agents.agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.dialog_agent.html b/en/agentscope.agents.dialog_agent.html index f24bd4183..3aedcd62e 100644 --- a/en/agentscope.agents.dialog_agent.html +++ b/en/agentscope.agents.dialog_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.dict_dialog_agent.html b/en/agentscope.agents.dict_dialog_agent.html index 99a1c598b..7c3e5ddbb 100644 --- a/en/agentscope.agents.dict_dialog_agent.html +++ b/en/agentscope.agents.dict_dialog_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.html b/en/agentscope.agents.html index 9a5906216..4326938ef 100644 --- a/en/agentscope.agents.html +++ b/en/agentscope.agents.html @@ -74,6 +74,8 @@
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -527,7 +529,7 @@ their own needs.

    -__init__(name: str, model_config_name: str, tools: List[Tuple], sys_prompt: str = "You're a helpful assistant. Your name is {name}.", max_iters: int = 10, verbose: bool = True) None[source]
    +__init__(name: str, model_config_name: str, service_toolkit: ServiceToolkit | None = None, sys_prompt: str = "You're a helpful assistant. Your name is {name}.", max_iters: int = 10, verbose: bool = True, **kwargs: Any) None[source]

    Initialize the ReAct agent with the given name, model config name and tools.

    @@ -537,10 +539,11 @@
  • sys_prompt (str) – The system prompt of the agent.

  • model_config_name (str) – The name of the model config, which is used to load model from configuration.

  • -
  • tools (List[Tuple]) – A list of tuples, each containing the name of a tool and the -tool’s description in JSON schema format.

  • +
  • service_toolkit (ServiceToolkit) – A ServiceToolkit object that contains the tool functions.

  • max_iters (int, defaults to 10) – The maximum number of iterations of the reasoning-acting loops.

  • -
  • verbose (bool, defaults to True) – Whether to print the output of the tools.

  • +
  • verbose (bool, defaults to True) – Whether to print the detailed information during reasoning and +acting steps. If False, only the content in speak field will +be print out.

  • @@ -553,54 +556,6 @@ The more details please refer to https://arxiv.org/abs/2210.03629

    -
    -
    -execute_func(index: int, func_call: dict) dict[source]
    -

    Execute the tool function and return the result.

    -
    -
    Parameters:
    -
      -
    • index (int) – The index of the tool function.

    • -
    • func_call (dict) – The function call dictionary with keys ‘name’ and ‘arguments’.

    • -
    -
    -
    Returns:
    -

    The execution results.

    -
    -
    Return type:
    -

    ServiceResponse

    -
    -
    -
    - -
    -
    -prepare_funcs_prompt(tools: List[Tuple]) Tuple[str, dict][source]
    -

    Convert function descriptions from json schema format to -string prompt format.

    -
    -
    Parameters:
    -

    tools (List[Tuple]) – The list of tool functions and their descriptions in JSON -schema format.

    -
    -
    Returns:
    -

    -
    The string prompt for the tool functions and a function name

    mapping dict.

    -
    -
    -
    {index}. {function name}: {function description}
    -    {argument name} ({argument type}): {argument description}
    -    ...
    -
    -
    -

    -
    -
    Return type:
    -

    Tuple[str, dict]

    -
    -
    -
    -
    diff --git a/en/agentscope.agents.operator.html b/en/agentscope.agents.operator.html index dc18befdc..9562ac2e8 100644 --- a/en/agentscope.agents.operator.html +++ b/en/agentscope.agents.operator.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.react_agent.html b/en/agentscope.agents.react_agent.html index 121bb51b5..650e891b8 100644 --- a/en/agentscope.agents.react_agent.html +++ b/en/agentscope.agents.react_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -110,7 +112,7 @@ their own needs.

    -__init__(name: str, model_config_name: str, tools: List[Tuple], sys_prompt: str = "You're a helpful assistant. Your name is {name}.", max_iters: int = 10, verbose: bool = True) None[source]
    +__init__(name: str, model_config_name: str, service_toolkit: ServiceToolkit | None = None, sys_prompt: str = "You're a helpful assistant. Your name is {name}.", max_iters: int = 10, verbose: bool = True, **kwargs: Any) None[source]

    Initialize the ReAct agent with the given name, model config name and tools.

    @@ -120,10 +122,11 @@
  • sys_prompt (str) – The system prompt of the agent.

  • model_config_name (str) – The name of the model config, which is used to load model from configuration.

  • -
  • tools (List[Tuple]) – A list of tuples, each containing the name of a tool and the -tool’s description in JSON schema format.

  • +
  • service_toolkit (ServiceToolkit) – A ServiceToolkit object that contains the tool functions.

  • max_iters (int, defaults to 10) – The maximum number of iterations of the reasoning-acting loops.

  • -
  • verbose (bool, defaults to True) – Whether to print the output of the tools.

  • +
  • verbose (bool, defaults to True) – Whether to print the detailed information during reasoning and +acting steps. If False, only the content in speak field will +be print out.

  • @@ -136,54 +139,6 @@ The more details please refer to https://arxiv.org/abs/2210.03629

    -
    -
    -execute_func(index: int, func_call: dict) dict[source]
    -

    Execute the tool function and return the result.

    -
    -
    Parameters:
    -
      -
    • index (int) – The index of the tool function.

    • -
    • func_call (dict) – The function call dictionary with keys ‘name’ and ‘arguments’.

    • -
    -
    -
    Returns:
    -

    The execution results.

    -
    -
    Return type:
    -

    ServiceResponse

    -
    -
    -
    - -
    -
    -prepare_funcs_prompt(tools: List[Tuple]) Tuple[str, dict][source]
    -

    Convert function descriptions from json schema format to -string prompt format.

    -
    -
    Parameters:
    -

    tools (List[Tuple]) – The list of tool functions and their descriptions in JSON -schema format.

    -
    -
    Returns:
    -

    -
    The string prompt for the tool functions and a function name

    mapping dict.

    -
    -
    -
    {index}. {function name}: {function description}
    -    {argument name} ({argument type}): {argument description}
    -    ...
    -
    -
    -

    -
    -
    Return type:
    -

    Tuple[str, dict]

    -
    -
    -
    - diff --git a/en/agentscope.agents.rpc_agent.html b/en/agentscope.agents.rpc_agent.html index e9adbab2d..4a8223c34 100644 --- a/en/agentscope.agents.rpc_agent.html +++ b/en/agentscope.agents.rpc_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.text_to_image_agent.html b/en/agentscope.agents.text_to_image_agent.html index 751f1dfeb..ae79839c3 100644 --- a/en/agentscope.agents.text_to_image_agent.html +++ b/en/agentscope.agents.text_to_image_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.agents.user_agent.html b/en/agentscope.agents.user_agent.html index 6075acb5f..2032c52fd 100644 --- a/en/agentscope.agents.user_agent.html +++ b/en/agentscope.agents.user_agent.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.constants.html b/en/agentscope.constants.html index bf9863774..3a7905fbb 100644 --- a/en/agentscope.constants.html +++ b/en/agentscope.constants.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.exception.html b/en/agentscope.exception.html new file mode 100644 index 000000000..2fe4bb72a --- /dev/null +++ b/en/agentscope.exception.html @@ -0,0 +1,264 @@ + + + + + + + + agentscope.exception — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    agentscope.exception

    +

    AgentScope exception classes.

    +
    +
    +exception agentscope.exception.ResponseParsingError(message: str, raw_response: str | None = None)[source]
    +

    Bases: Exception

    +

    The exception class for response parsing error with uncertain +reasons.

    +
    +
    +__init__(message: str, raw_response: str | None = None) None[source]
    +

    Initialize the exception with the message.

    +
    + +
    +
    +raw_response: str
    +

    Record the raw response.

    +
    + +
    + +
    +
    +exception agentscope.exception.JsonParsingError(message: str, raw_response: str | None = None)[source]
    +

    Bases: ResponseParsingError

    +

    The exception class for JSON parsing error.

    +
    + +
    +
    +exception agentscope.exception.JsonTypeError(message: str, raw_response: str | None = None)[source]
    +

    Bases: ResponseParsingError

    +

    The exception class for JSON type error.

    +
    + +
    +
    +exception agentscope.exception.RequiredFieldNotFoundError(message: str, raw_response: str | None = None)[source]
    +

    Bases: ResponseParsingError

    +

    The exception class for missing required field in model response, when +the response is required to be a JSON dict object with required fields.

    +
    + +
    +
    +exception agentscope.exception.TagNotFoundError(message: str, raw_response: str | None = None, missing_begin_tag: bool = True, missing_end_tag: bool = True)[source]
    +

    Bases: ResponseParsingError

    +

    The exception class for missing tagged content in model response.

    +
    +
    +__init__(message: str, raw_response: str | None = None, missing_begin_tag: bool = True, missing_end_tag: bool = True)[source]
    +

    Initialize the exception with the message.

    +
    +
    Parameters:
    +
      +
    • raw_response (str) – Record the raw response from the model.

    • +
    • missing_begin_tag (bool, defaults to True) – If the response misses the beginning tag, default to True.

    • +
    • missing_end_tag (bool, defaults to True) – If the response misses the end tag, default to True.

    • +
    +
    +
    +
    + +
    +
    +missing_begin_tag: bool
    +

    If the response misses the begin tag.

    +
    + +
    +
    +missing_end_tag: bool
    +

    If the response misses the end tag.

    +
    + +
    + +
    +
    +exception agentscope.exception.FunctionCallError(message: str)[source]
    +

    Bases: Exception

    +

    The base class for exception raising during calling functions.

    +
    +
    +__init__(message: str) None[source]
    +
    + +
    + +
    +
    +exception agentscope.exception.FunctionCallFormatError(message: str)[source]
    +

    Bases: FunctionCallError

    +

    The exception class for function calling format error.

    +
    + +
    +
    +exception agentscope.exception.FunctionNotFoundError(message: str)[source]
    +

    Bases: FunctionCallError

    +

    The exception class for function not found error.

    +
    + +
    +
    +exception agentscope.exception.ArgumentNotFoundError(message: str)[source]
    +

    Bases: FunctionCallError

    +

    The exception class for missing argument error.

    +
    + +
    +
    +exception agentscope.exception.ArgumentTypeError(message: str)[source]
    +

    Bases: FunctionCallError

    +

    The exception class for argument type error.

    +
    + +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/agentscope.file_manager.html b/en/agentscope.file_manager.html index 4d4aeaafb..3e3cf40a2 100644 --- a/en/agentscope.file_manager.html +++ b/en/agentscope.file_manager.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.html b/en/agentscope.html index 6d0cabad6..0c7be4d40 100644 --- a/en/agentscope.html +++ b/en/agentscope.html @@ -67,6 +67,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.memory.html b/en/agentscope.memory.html index 2285187e8..1eeccb61b 100644 --- a/en/agentscope.memory.html +++ b/en/agentscope.memory.html @@ -23,7 +23,7 @@ - + @@ -67,6 +67,8 @@
  • TemporaryMemory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -299,7 +301,7 @@

    diff --git a/en/agentscope.memory.memory.html b/en/agentscope.memory.memory.html index 9a24ef61d..05e20d995 100644 --- a/en/agentscope.memory.memory.html +++ b/en/agentscope.memory.memory.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.memory.temporary_memory.html b/en/agentscope.memory.temporary_memory.html index e5814b096..6f4a583c2 100644 --- a/en/agentscope.memory.temporary_memory.html +++ b/en/agentscope.memory.temporary_memory.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.message.html b/en/agentscope.message.html index 6bdf6ac71..50e7f3607 100644 --- a/en/agentscope.message.html +++ b/en/agentscope.message.html @@ -71,6 +71,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.config.html b/en/agentscope.models.config.html index c20daf317..5c10d9200 100644 --- a/en/agentscope.models.config.html +++ b/en/agentscope.models.config.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.dashscope_model.html b/en/agentscope.models.dashscope_model.html index 41e9ab42d..6b3c6f68d 100644 --- a/en/agentscope.models.dashscope_model.html +++ b/en/agentscope.models.dashscope_model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.gemini_model.html b/en/agentscope.models.gemini_model.html index 4b0764a3f..e536950c0 100644 --- a/en/agentscope.models.gemini_model.html +++ b/en/agentscope.models.gemini_model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.html b/en/agentscope.models.html index a12e2dd8c..713a1541f 100644 --- a/en/agentscope.models.html +++ b/en/agentscope.models.html @@ -63,8 +63,6 @@
  • agentscope.models
    • ModelWrapperBase
    • ModelResponse
    • -
    • ResponseParser
    • -
    • ResponseParsingError
    • PostAPIModelWrapperBase
    • PostAPIChatWrapper
    • OpenAIWrapperBase
    • @@ -87,6 +85,8 @@
    • agentscope.agents
    • agentscope.memory
    • +
    • agentscope.parsers
    • +
    • agentscope.exception
    • agentscope.pipelines
    • agentscope.service
    • agentscope.rpc
    • @@ -188,19 +188,14 @@
      -class agentscope.models.ModelResponse(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None)[source]
      +class agentscope.models.ModelResponse(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None, parsed: Any | None = None)[source]

      Bases: object

      Encapsulation of data returned by the model.

      The main purpose of this class is to align the return formats of different models and act as a bridge between models and agents.

      -
      -
      -json: Any | None = None
      -
      -
      -__init__(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None) None[source]
      +__init__(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None, parsed: Any | None = None) None[source]

      Initialize the model response.

      Parameters:
      @@ -209,6 +204,7 @@
    • embedding (Sequence, optional) – The embedding returned by the model.

    • image_urls (Sequence[str], optional) – The image URLs returned by the model.

    • raw (Any, optional) – The raw data returned by the model.

    • +
    • parsed (Any, optional) – The parsed data returned by the model.

    @@ -234,66 +230,10 @@ raw: Any | None = None
    - - -
    -
    -class agentscope.models.ResponseParser[source]
    -

    Bases: object

    -

    A class that contains several static methods to parse the response.

    -
    -
    -classmethod to_dict(response: ModelResponse) ModelResponse[source]
    -

    Parse the response text to a dict, and feed it into the json -field.

    -
    - -
    -
    -classmethod to_list(response: ModelResponse) ModelResponse[source]
    -

    Parse the response text to a list, and feed it into the json -field.

    -
    - -
    - -
    -
    -exception agentscope.models.ResponseParsingError(*args: Any, parse_func: Callable, error_info: str, response: ModelResponse, **kwargs: Any)[source]
    -

    Bases: Exception

    -

    Exception raised when parsing the response fails.

    -
    -
    -parse_func: str
    -

    The source code of the parsing function.

    -
    - -
    -
    -__init__(*args: Any, parse_func: Callable, error_info: str, response: ModelResponse, **kwargs: Any) None[source]
    -

    Initialize the exception.

    -
    -
    Parameters:
    -
      -
    • parse_func (str) – The source code of the parsing function.

    • -
    • error_info (str) – The detail information of the error.

    • -
    • response (ModelResponse) – The response that fails to be parsed.

    • -
    -
    -
    -
    - -
    -
    -error_info: str
    -

    The detail information of the error.

    -
    -
    -
    -response: ModelResponse
    -

    The response that fails to be parsed.

    -
    +
    +parsed: Any | None = None
    +
    diff --git a/en/agentscope.models.model.html b/en/agentscope.models.model.html index d42ce57bb..753599ca0 100644 --- a/en/agentscope.models.model.html +++ b/en/agentscope.models.model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.ollama_model.html b/en/agentscope.models.ollama_model.html index 1ccd80534..c22397192 100644 --- a/en/agentscope.models.ollama_model.html +++ b/en/agentscope.models.ollama_model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.openai_model.html b/en/agentscope.models.openai_model.html index ec586e032..470f17804 100644 --- a/en/agentscope.models.openai_model.html +++ b/en/agentscope.models.openai_model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.post_model.html b/en/agentscope.models.post_model.html index e41489bee..6dcef6dc7 100644 --- a/en/agentscope.models.post_model.html +++ b/en/agentscope.models.post_model.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.models.response.html b/en/agentscope.models.response.html index 60ab5f556..f5b9e8a76 100644 --- a/en/agentscope.models.response.html +++ b/en/agentscope.models.response.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • @@ -98,19 +100,14 @@

    Parser for model response.

    -class agentscope.models.response.ModelResponse(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None)[source]
    +class agentscope.models.response.ModelResponse(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None, parsed: Any | None = None)[source]

    Bases: object

    Encapsulation of data returned by the model.

    The main purpose of this class is to align the return formats of different models and act as a bridge between models and agents.

    -
    -
    -json: Any | None = None
    -
    -
    -__init__(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None) None[source]
    +__init__(text: str | None = None, embedding: Sequence | None = None, image_urls: Sequence[str] | None = None, raw: Any | None = None, parsed: Any | None = None) None[source]

    Initialize the model response.

    Parameters:
    @@ -119,6 +116,7 @@
  • embedding (Sequence, optional) – The embedding returned by the model.

  • image_urls (Sequence[str], optional) – The image URLs returned by the model.

  • raw (Any, optional) – The raw data returned by the model.

  • +
  • parsed (Any, optional) – The parsed data returned by the model.

  • @@ -144,66 +142,10 @@ raw: Any | None = None
    - - -
    -
    -class agentscope.models.response.ResponseParser[source]
    -

    Bases: object

    -

    A class that contains several static methods to parse the response.

    -
    -
    -classmethod to_dict(response: ModelResponse) ModelResponse[source]
    -

    Parse the response text to a dict, and feed it into the json -field.

    -
    - -
    -
    -classmethod to_list(response: ModelResponse) ModelResponse[source]
    -

    Parse the response text to a list, and feed it into the json -field.

    -
    - -
    - -
    -
    -exception agentscope.models.response.ResponseParsingError(*args: Any, parse_func: Callable, error_info: str, response: ModelResponse, **kwargs: Any)[source]
    -

    Bases: Exception

    -

    Exception raised when parsing the response fails.

    -
    -
    -parse_func: str
    -

    The source code of the parsing function.

    -
    - -
    -
    -__init__(*args: Any, parse_func: Callable, error_info: str, response: ModelResponse, **kwargs: Any) None[source]
    -

    Initialize the exception.

    -
    -
    Parameters:
    -
      -
    • parse_func (str) – The source code of the parsing function.

    • -
    • error_info (str) – The detail information of the error.

    • -
    • response (ModelResponse) – The response that fails to be parsed.

    • -
    -
    -
    -
    - -
    -
    -error_info: str
    -

    The detail information of the error.

    -
    -
    -
    -response: ModelResponse
    -

    The response that fails to be parsed.

    -
    +
    +parsed: Any | None = None
    +
    diff --git a/en/agentscope.msghub.html b/en/agentscope.msghub.html index 82cd96ca3..f165733cb 100644 --- a/en/agentscope.msghub.html +++ b/en/agentscope.msghub.html @@ -61,6 +61,8 @@
  • agentscope.models
  • agentscope.agents
  • agentscope.memory
  • +
  • agentscope.parsers
  • +
  • agentscope.exception
  • agentscope.pipelines
  • agentscope.service
  • agentscope.rpc
  • diff --git a/en/agentscope.parsers.code_block_parser.html b/en/agentscope.parsers.code_block_parser.html new file mode 100644 index 000000000..7ebe476d7 --- /dev/null +++ b/en/agentscope.parsers.code_block_parser.html @@ -0,0 +1,180 @@ + + + + + + + + agentscope.parsers.code_block_parser — AgentScope documentation + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    agentscope.parsers.code_block_parser

    +

    Model response parser class for Markdown code block.

    +
    +
    +class agentscope.parsers.code_block_parser.MarkdownCodeBlockParser(language_name: str)[source]
    +

    Bases: ParserBase

    +

    The base class for parsing the response text by fenced block.

    +
    +
    +content_hint: str = '${your_{language_name}_CODE}'
    +

    The hint of the content.

    +
    + +
    +
    +tag_end: str = '```'
    +

    The ending tag.

    +
    + +
    +
    +__init__(language_name: str) None[source]
    +
    + +
    +
    +name: str = '{language_name} block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```{language_name}'
    +

    The beginning tag.

    +
    + +
    +
    +format_instruction: str = 'You should generate {language_name} code in a {language_name} fenced code block as follows: \n```{language_name}\n${your_{language_name}_CODE}\n```'
    +

    The instruction for the format of the code block.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Extract the content between the tag_begin and tag_end in the +response and store it in the parsed field of the response object.

    +
    + +
    + +
    + + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/agentscope.parsers.html b/en/agentscope.parsers.html new file mode 100644 index 000000000..29adc2157 --- /dev/null +++ b/en/agentscope.parsers.html @@ -0,0 +1,434 @@ + + + + + + + + agentscope.parsers — AgentScope documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    agentscope.parsers

    +

    Model response parser module.

    +
    +
    +class agentscope.parsers.ParserBase[source]
    +

    Bases: ABC

    +

    The base class for model response parser.

    +
    +
    +abstract parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the response text to a specific object, and stored in the +parsed field of the response object.

    +
    + +
    + +
    +
    +class agentscope.parsers.MarkdownJsonObjectParser(content_hint: Any | None = None)[source]
    +

    Bases: ParserBase

    +

    A parser to parse the response text to a json object.

    +
    +
    +name: str = 'json block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```json'
    +

    Opening tag for a code block.

    +
    + +
    +
    +tag_end: str = '```'
    +

    Closing end for a code block.

    +
    + +
    +
    +__init__(content_hint: Any | None = None) None[source]
    +

    Initialize the parser with the content hint.

    +
    +
    Parameters:
    +

    content_hint (Optional[Any], defaults to None) – The hint used to remind LLM what should be fill between the +tags. If it is a string, it will be used as the content hint +directly. If it is a dict, it will be converted to a json +string and used as the content hint.

    +
    +
    +
    + +
    +
    +content_hint: str = '{your_json_object}'
    +

    The hint of the content.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the response text to a json object, and fill it in the parsed +field in the response object.

    +
    + +
    +
    +property format_instruction: str
    +

    Get the format instruction for the json object, if the +format_example is provided, it will be used as the example.

    +
    + +
    + +
    +
    +class agentscope.parsers.MarkdownJsonDictParser(content_hint: Any | None = None, required_keys: List[str] | None = None)[source]
    +

    Bases: MarkdownJsonObjectParser

    +

    A class used to parse a JSON dictionary object in a markdown fenced +code

    +
    +
    +name: str = 'json block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```json'
    +

    Opening tag for a code block.

    +
    + +
    +
    +content_hint: str = '{your_json_dictionary}'
    +

    The hint of the content.

    +
    + +
    +
    +tag_end: str = '```'
    +

    Closing end for a code block.

    +
    + +
    +
    +__init__(content_hint: Any | None = None, required_keys: List[str] | None = None) None[source]
    +

    Initialize the parser with the content hint.

    +
    +
    Parameters:
    +
      +
    • content_hint (Optional[Any], defaults to None) – The hint used to remind LLM what should be fill between the +tags. If it is a string, it will be used as the content hint +directly. If it is a dict, it will be converted to a json +string and used as the content hint.

    • +
    • required_keys (List[str], defaults to []) – A list of required keys in the JSON dictionary object. If the +response misses any of the required keys, it will raise a +RequiredFieldNotFoundError.

    • +
    +
    +
    +
    + +
    +
    +required_keys: List[str]
    +

    A list of required keys in the JSON dictionary object. If the response +misses any of the required keys, it will raise a +RequiredFieldNotFoundError.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the text field of the response to a JSON dictionary object, +store it in the parsed field of the response object, and check if the +required keys exists.

    +
    + +
    + +
    +
    +class agentscope.parsers.MarkdownCodeBlockParser(language_name: str)[source]
    +

    Bases: ParserBase

    +

    The base class for parsing the response text by fenced block.

    +
    +
    +content_hint: str = '${your_{language_name}_CODE}'
    +

    The hint of the content.

    +
    + +
    +
    +tag_end: str = '```'
    +

    The ending tag.

    +
    + +
    +
    +__init__(language_name: str) None[source]
    +
    + +
    +
    +name: str = '{language_name} block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```{language_name}'
    +

    The beginning tag.

    +
    + +
    +
    +format_instruction: str = 'You should generate {language_name} code in a {language_name} fenced code block as follows: \n```{language_name}\n${your_{language_name}_CODE}\n```'
    +

    The instruction for the format of the code block.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Extract the content between the tag_begin and tag_end in the +response and store it in the parsed field of the response object.

    +
    + +
    + +
    +
    +class agentscope.parsers.TaggedContent(name: str, tag_begin: str, content_hint: str, tag_end: str, parse_json: bool = False)[source]
    +

    Bases: object

    +

    A tagged content object to store the tag name, tag begin, content hint +and tag end.

    +
    +
    +__init__(name: str, tag_begin: str, content_hint: str, tag_end: str, parse_json: bool = False) None[source]
    +

    Initialize the tagged content object.

    +
    +
    Parameters:
    +
      +
    • name (str) – The name of the tagged content.

    • +
    • tag_begin (str) – The beginning tag.

    • +
    • content_hint (str) – The hint of the content.

    • +
    • tag_end (str) – The ending tag.

    • +
    • parse_json (bool, defaults to False) – Whether to parse the content as a json object.

    • +
    +
    +
    +
    + +
    +
    +name: str
    +

    The name of the tagged content.

    +
    + +
    +
    +tag_begin: str
    +

    The beginning tag.

    +
    + +
    +
    +content_hint: str
    +

    The hint of the content.

    +
    + +
    +
    +tag_end: str
    +

    The ending tag.

    +
    + +
    +
    +parse_json: bool
    +

    Whether to parse the content as a json object.

    +
    + +
    + +
    +
    +class agentscope.parsers.MultiTaggedContentParser(*tagged_contents: TaggedContent)[source]
    +

    Bases: ParserBase

    +

    Parse response text by multiple tags, and return a dict of their +content. Asking llm to generate JSON dictionary object directly maybe not a +good idea due to involving escape characters and other issues. So we can +ask llm to generate text with tags, and then parse the text to get the +final JSON dictionary object.

    +
    +
    +json_required_hint = ', and the content between {} MUST be a JSON object:'
    +

    If a tagged content is required to be a JSON object by parse_json +equals to True, this instruction will be used to remind the model to +generate JSON object.

    +
    + +
    +
    +__init__(*tagged_contents: TaggedContent) None[source]
    +

    Initialize the parser with tags.

    +
    +
    Parameters:
    +

    tags (dict[str, Tuple[str, str]]) – A dictionary of tags, the key is the tag name, and the value is +a tuple of starting tag and end tag.

    +
    +
    +
    + +
    +
    +format_instruction = 'Respond with specific tags as outlined below{json_required_hint}\n{tag_lines_format}'
    +

    The instruction for the format of the tagged content.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the response text by tags, and return a dict of their content +in the parsed field of the model response object. If the tagged content +requires to parse as a JSON object by parse_json equals to True, it +will be parsed as a JSON object by json.loads.

    +
    + +
    + +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/agentscope.parsers.json_object_parser.html b/en/agentscope.parsers.json_object_parser.html new file mode 100644 index 000000000..a9def88c2 --- /dev/null +++ b/en/agentscope.parsers.json_object_parser.html @@ -0,0 +1,257 @@ + + + + + + + + agentscope.parsers.json_object_parser — AgentScope documentation + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    agentscope.parsers.json_object_parser

    +

    The parser for JSON object in the model response.

    +
    +
    +class agentscope.parsers.json_object_parser.MarkdownJsonObjectParser(content_hint: Any | None = None)[source]
    +

    Bases: ParserBase

    +

    A parser to parse the response text to a json object.

    +
    +
    +name: str = 'json block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```json'
    +

    Opening tag for a code block.

    +
    + +
    +
    +tag_end: str = '```'
    +

    Closing end for a code block.

    +
    + +
    +
    +__init__(content_hint: Any | None = None) None[source]
    +

    Initialize the parser with the content hint.

    +
    +
    Parameters:
    +

    content_hint (Optional[Any], defaults to None) – The hint used to remind LLM what should be fill between the +tags. If it is a string, it will be used as the content hint +directly. If it is a dict, it will be converted to a json +string and used as the content hint.

    +
    +
    +
    + +
    +
    +content_hint: str = '{your_json_object}'
    +

    The hint of the content.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the response text to a json object, and fill it in the parsed +field in the response object.

    +
    + +
    +
    +property format_instruction: str
    +

    Get the format instruction for the json object, if the +format_example is provided, it will be used as the example.

    +
    + +
    + +
    +
    +class agentscope.parsers.json_object_parser.MarkdownJsonDictParser(content_hint: Any | None = None, required_keys: List[str] | None = None)[source]
    +

    Bases: MarkdownJsonObjectParser

    +

    A class used to parse a JSON dictionary object in a markdown fenced +code

    +
    +
    +name: str = 'json block'
    +

    The name of the parser.

    +
    + +
    +
    +tag_begin: str = '```json'
    +

    Opening tag for a code block.

    +
    + +
    +
    +content_hint: str = '{your_json_dictionary}'
    +

    The hint of the content.

    +
    + +
    +
    +tag_end: str = '```'
    +

    Closing end for a code block.

    +
    + +
    +
    +__init__(content_hint: Any | None = None, required_keys: List[str] | None = None) None[source]
    +

    Initialize the parser with the content hint.

    +
    +
    Parameters:
    +
      +
    • content_hint (Optional[Any], defaults to None) – The hint used to remind LLM what should be fill between the +tags. If it is a string, it will be used as the content hint +directly. If it is a dict, it will be converted to a json +string and used as the content hint.

    • +
    • required_keys (List[str], defaults to []) – A list of required keys in the JSON dictionary object. If the +response misses any of the required keys, it will raise a +RequiredFieldNotFoundError.

    • +
    +
    +
    +
    + +
    +
    +required_keys: List[str]
    +

    A list of required keys in the JSON dictionary object. If the response +misses any of the required keys, it will raise a +RequiredFieldNotFoundError.

    +
    + +
    +
    +parse(response: ModelResponse) ModelResponse[source]
    +

    Parse the text field of the response to a JSON dictionary object, +store it in the parsed field of the response object, and check if the +required keys exists.

    +
    + +
    + +
    + + +
    +
    +
    + +
    + +
    +

    © Copyright 2024, Alibaba Tongyi Lab.

    +
    + + Built with Sphinx using a + theme + provided by Read the Docs. + + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/en/agentscope.service.service_factory.html b/en/agentscope.parsers.parser_base.html similarity index 50% rename from en/agentscope.service.service_factory.html rename to en/agentscope.parsers.parser_base.html index 68e7cb74a..d164370f4 100644 --- a/en/agentscope.service.service_factory.html +++ b/en/agentscope.parsers.parser_base.html @@ -5,7 +5,7 @@ - agentscope.service.service_factory — AgentScope documentation + agentscope.parsers.parser_base — AgentScope documentation @@ -44,8 +44,8 @@