Skip to content

toolset_code_generator

Class info

Classes

Name Children Inherits
NamespaceCallable
llmling_agent.resource_providers.codemode.namespace_callable
Wrapper for tool functions with proper repr and call interface.
    ToolCodeGenerator
    llmling_agent.resource_providers.codemode.tool_code_generator
    Generates code artifacts for a single tool.
      ToolsetCodeGenerator
      llmling_agent.resource_providers.codemode.toolset_code_generator
      Generates code artifacts for multiple tools.

        🛈 DocStrings

        Orchestrates code generation for multiple tools.

        ToolsetCodeGenerator dataclass

        Generates code artifacts for multiple tools.

        Source code in src/llmling_agent/resource_providers/codemode/toolset_code_generator.py
         21
         22
         23
         24
         25
         26
         27
         28
         29
         30
         31
         32
         33
         34
         35
         36
         37
         38
         39
         40
         41
         42
         43
         44
         45
         46
         47
         48
         49
         50
         51
         52
         53
         54
         55
         56
         57
         58
         59
         60
         61
         62
         63
         64
         65
         66
         67
         68
         69
         70
         71
         72
         73
         74
         75
         76
         77
         78
         79
         80
         81
         82
         83
         84
         85
         86
         87
         88
         89
         90
         91
         92
         93
         94
         95
         96
         97
         98
         99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        126
        127
        128
        129
        130
        131
        132
        133
        @dataclass
        class ToolsetCodeGenerator:
            """Generates code artifacts for multiple tools."""
        
            generators: Sequence[ToolCodeGenerator]
            """ToolCodeGenerator instances for each tool."""
        
            include_signatures: bool = True
            """Include function signatures in documentation."""
        
            include_docstrings: bool = True
            """Include function docstrings in documentation."""
        
            @classmethod
            def from_tools(
                cls,
                tools: Sequence[Tool],
                include_signatures: bool = True,
                include_docstrings: bool = True,
            ) -> ToolsetCodeGenerator:
                """Create a ToolsetCodeGenerator from a sequence of Tools.
        
                Args:
                    tools: Tools to generate code for
                    include_signatures: Include function signatures in documentation
                    include_docstrings: Include function docstrings in documentation
        
                Returns:
                    ToolsetCodeGenerator instance
                """
                generators = [ToolCodeGenerator.from_tool(tool) for tool in tools]
                return cls(generators, include_signatures, include_docstrings)
        
            def generate_tool_description(self) -> str:
                """Generate comprehensive tool description with available functions."""
                if not self.generators:
                    return "Execute Python code (no tools available)"
        
                # Generate return type models if available
                return_models = self.generate_return_models()
        
                parts = [
                    "Execute Python code with the following tools available as async functions:",
                    "",
                ]
        
                if return_models:
                    parts.extend([
                        "# Generated return type models",
                        return_models,
                        "",
                        "# Available functions:",
                        "",
                    ])
        
                for generator in self.generators:
                    if self.include_signatures:
                        signature = generator.get_function_signature()
                        parts.append(f"async def {signature}:")
                    else:
                        parts.append(f"async def {generator.name}(...):")
        
                    if self.include_docstrings and generator.callable.__doc__:
                        indented_desc = "    " + generator.callable.__doc__.replace(
                            "\n", "\n    "
                        )
                        parts.append(f'    """{indented_desc}"""')
                    parts.append("")
        
                parts.extend([
                    "Usage notes:",
                    "- Write your code inside an 'async def main():' function",
                    "- All tool functions are async, use 'await'",
                    "- Use 'return' statements to return values from main()",
                    "- Generated model classes are available for type checking",
                    "- Use 'await report_progress(current, total, message)' for long-running operations",  # noqa: E501
                    # "- Use 'await ask_user(message, response_type)' to get user input during execution",  # noqa: E501
                    # "  - response_type can be: 'string', 'bool', 'int', 'float', 'json'",
                    "- DO NOT call asyncio.run() or try to run the main function yourself",
                    "- DO NOT import asyncio or other modules - tools are already available",
                    "- Example:",
                    "    async def main():",
                    "        for i in range(5):",
                    "            await report_progress(i, 5, f'Step {i+1} for {name}')",
                    "            should_continue = await ask_user('Continue?', 'bool')",
                    "            if not should_continue:",
                    "                break",
                    "        return f'Completed for {name}'",
                ])
        
                return "\n".join(parts)
        
            def generate_execution_namespace(self) -> dict[str, Any]:
                """Build Python namespace with tool functions and generated models."""
                namespace: dict[str, Any] = {"__builtins__": __builtins__, "_result": None}
        
                # Add tool functions
                for generator in self.generators:
                    namespace[generator.name] = NamespaceCallable.from_generator(generator)
        
                # Add generated model classes to namespace
                if models_code := self.generate_return_models():
                    with contextlib.suppress(Exception):
                        exec(models_code, namespace)
        
                return namespace
        
            def generate_return_models(self) -> str:
                """Generate Pydantic models for tool return types."""
                model_parts = [
                    code for g in self.generators if (code := g.generate_return_model())
                ]
                return "\n\n".join(model_parts) if model_parts else ""
        

        generators instance-attribute

        ToolCodeGenerator instances for each tool.

        include_docstrings class-attribute instance-attribute

        include_docstrings: bool = True
        

        Include function docstrings in documentation.

        include_signatures class-attribute instance-attribute

        include_signatures: bool = True
        

        Include function signatures in documentation.

        from_tools classmethod

        from_tools(
            tools: Sequence[Tool],
            include_signatures: bool = True,
            include_docstrings: bool = True,
        ) -> ToolsetCodeGenerator
        

        Create a ToolsetCodeGenerator from a sequence of Tools.

        Parameters:

        Name Type Description Default
        tools Sequence[Tool]

        Tools to generate code for

        required
        include_signatures bool

        Include function signatures in documentation

        True
        include_docstrings bool

        Include function docstrings in documentation

        True

        Returns:

        Type Description
        ToolsetCodeGenerator

        ToolsetCodeGenerator instance

        Source code in src/llmling_agent/resource_providers/codemode/toolset_code_generator.py
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        @classmethod
        def from_tools(
            cls,
            tools: Sequence[Tool],
            include_signatures: bool = True,
            include_docstrings: bool = True,
        ) -> ToolsetCodeGenerator:
            """Create a ToolsetCodeGenerator from a sequence of Tools.
        
            Args:
                tools: Tools to generate code for
                include_signatures: Include function signatures in documentation
                include_docstrings: Include function docstrings in documentation
        
            Returns:
                ToolsetCodeGenerator instance
            """
            generators = [ToolCodeGenerator.from_tool(tool) for tool in tools]
            return cls(generators, include_signatures, include_docstrings)
        

        generate_execution_namespace

        generate_execution_namespace() -> dict[str, Any]
        

        Build Python namespace with tool functions and generated models.

        Source code in src/llmling_agent/resource_providers/codemode/toolset_code_generator.py
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        126
        def generate_execution_namespace(self) -> dict[str, Any]:
            """Build Python namespace with tool functions and generated models."""
            namespace: dict[str, Any] = {"__builtins__": __builtins__, "_result": None}
        
            # Add tool functions
            for generator in self.generators:
                namespace[generator.name] = NamespaceCallable.from_generator(generator)
        
            # Add generated model classes to namespace
            if models_code := self.generate_return_models():
                with contextlib.suppress(Exception):
                    exec(models_code, namespace)
        
            return namespace
        

        generate_return_models

        generate_return_models() -> str
        

        Generate Pydantic models for tool return types.

        Source code in src/llmling_agent/resource_providers/codemode/toolset_code_generator.py
        128
        129
        130
        131
        132
        133
        def generate_return_models(self) -> str:
            """Generate Pydantic models for tool return types."""
            model_parts = [
                code for g in self.generators if (code := g.generate_return_model())
            ]
            return "\n\n".join(model_parts) if model_parts else ""
        

        generate_tool_description

        generate_tool_description() -> str
        

        Generate comprehensive tool description with available functions.

        Source code in src/llmling_agent/resource_providers/codemode/toolset_code_generator.py
         54
         55
         56
         57
         58
         59
         60
         61
         62
         63
         64
         65
         66
         67
         68
         69
         70
         71
         72
         73
         74
         75
         76
         77
         78
         79
         80
         81
         82
         83
         84
         85
         86
         87
         88
         89
         90
         91
         92
         93
         94
         95
         96
         97
         98
         99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        def generate_tool_description(self) -> str:
            """Generate comprehensive tool description with available functions."""
            if not self.generators:
                return "Execute Python code (no tools available)"
        
            # Generate return type models if available
            return_models = self.generate_return_models()
        
            parts = [
                "Execute Python code with the following tools available as async functions:",
                "",
            ]
        
            if return_models:
                parts.extend([
                    "# Generated return type models",
                    return_models,
                    "",
                    "# Available functions:",
                    "",
                ])
        
            for generator in self.generators:
                if self.include_signatures:
                    signature = generator.get_function_signature()
                    parts.append(f"async def {signature}:")
                else:
                    parts.append(f"async def {generator.name}(...):")
        
                if self.include_docstrings and generator.callable.__doc__:
                    indented_desc = "    " + generator.callable.__doc__.replace(
                        "\n", "\n    "
                    )
                    parts.append(f'    """{indented_desc}"""')
                parts.append("")
        
            parts.extend([
                "Usage notes:",
                "- Write your code inside an 'async def main():' function",
                "- All tool functions are async, use 'await'",
                "- Use 'return' statements to return values from main()",
                "- Generated model classes are available for type checking",
                "- Use 'await report_progress(current, total, message)' for long-running operations",  # noqa: E501
                # "- Use 'await ask_user(message, response_type)' to get user input during execution",  # noqa: E501
                # "  - response_type can be: 'string', 'bool', 'int', 'float', 'json'",
                "- DO NOT call asyncio.run() or try to run the main function yourself",
                "- DO NOT import asyncio or other modules - tools are already available",
                "- Example:",
                "    async def main():",
                "        for i in range(5):",
                "            await report_progress(i, 5, f'Step {i+1} for {name}')",
                "            should_continue = await ask_user('Continue?', 'bool')",
                "            if not should_continue:",
                "                break",
                "        return f'Completed for {name}'",
            ])
        
            return "\n".join(parts)