Parses LLM responses to extract different types of tool calls. This parser handles three types of tool invocations: 1. Standard OpenAI tool_calls in the response 2. Inline tool calls written as function-call syntax in code blocks 3. Raw bash commands in shell code blocks Exampl
| 55 | |
| 56 | |
| 57 | class ResponseParser: |
| 58 | """Parses LLM responses to extract different types of tool calls. |
| 59 | |
| 60 | This parser handles three types of tool invocations: |
| 61 | 1. Standard OpenAI tool_calls in the response |
| 62 | 2. Inline tool calls written as function-call syntax in code blocks |
| 63 | 3. Raw bash commands in shell code blocks |
| 64 | |
| 65 | Example: |
| 66 | parser = ResponseParser( |
| 67 | enable_inline=True, |
| 68 | allowed_tool_names={"shell_run", "fs_write"}, |
| 69 | submodule_names={"analyze_code"}, |
| 70 | ) |
| 71 | result = parser.parse(llm_message) |
| 72 | if result.has_error: |
| 73 | handle_error(result.parse_error) |
| 74 | elif result.tool_calls: |
| 75 | execute_tool_calls(result.tool_calls) |
| 76 | """ |
| 77 | |
| 78 | def __init__( |
| 79 | self, |
| 80 | enable_inline: bool = False, |
| 81 | allowed_tool_names: Optional[Set[str]] = None, |
| 82 | submodule_names: Optional[Set[str]] = None, |
| 83 | ): |
| 84 | """Initialize the response parser. |
| 85 | |
| 86 | Args: |
| 87 | enable_inline: Whether to parse inline tool calls from code blocks. |
| 88 | allowed_tool_names: Set of valid tool names for inline call detection. |
| 89 | submodule_names: Set of submodule function names for inline call detection. |
| 90 | """ |
| 91 | self.enable_inline = enable_inline |
| 92 | self.allowed_tool_names: Set[str] = allowed_tool_names or set() |
| 93 | self.submodule_names: Set[str] = submodule_names or set() |
| 94 | |
| 95 | def parse(self, message: Any) -> ParsedResponse: |
| 96 | """Parse an LLM message and extract all tool calls. |
| 97 | |
| 98 | Args: |
| 99 | message: The message object from LLM response. |
| 100 | Expected to have .content (str) and .tool_calls (list) attributes. |
| 101 | |
| 102 | Returns: |
| 103 | ParsedResponse containing all extracted tool calls and any parse errors. |
| 104 | """ |
| 105 | content = message.content or "" |
| 106 | tool_calls = list(message.tool_calls or []) |
| 107 | |
| 108 | # Truncate to first code block if multiple are present |
| 109 | if self.enable_inline: |
| 110 | content = truncate_to_first_code_block(content) |
| 111 | |
| 112 | # Check for malformed inline tools when inline parsing is enabled |
| 113 | if self.enable_inline: |
| 114 | error = detect_malformed_code_blocks(content) |
no outgoing calls