Skip to main content
Glama

ShallowCodeResearch_agent_code_generator

Generate Python code from user requests using context-guided generation to produce functional implementations.

Instructions

Wrapper for CodeGeneratorAgent to generate Python code. Returns: A tuple containing the generation result and raw code

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
user_requestNoThe user's request for code generation
grounded_contextNoContext information to guide generation

Implementation Reference

  • Core handler implementing the code generation logic using LLM with security checks (disallowed functions), syntax validation via ast.compile, retry mechanism up to max attempts, and detailed prompting for safe executable Python code.
    def generate_code(
        self, user_request: str, grounded_context: str
    ) -> tuple[Dict[str, Any], str]:
        """
        Generate Python code based on user request and grounded context with enhanced security.
    
        Creates safe, executable Python code using LLM models with built-in security
        validation. Includes iterative error correction, syntax checking, and
        security violation detection to ensure safe code generation.
    
        Args:
            user_request (str): The user's request describing what code to generate
            grounded_context (str): Contextual information to inform code generation
    
        Returns:
            tuple[Dict[str, Any], str]: A tuple containing the generation result dictionary
                                       and the raw generated code string
        """
        try:
            validate_non_empty_string(user_request, "User request")
            logger.info("Generating Python code with security checks")
    
            prev_error = ""
            
            for attempt in range(1, app_config.max_code_generation_attempts + 1):
                try:
                    logger.info(f"Code generation attempt {attempt}")
    
                    prompt_text = self._make_prompt(user_request, grounded_context, prev_error)
                    messages = [{"role": "user", "content": prompt_text}]
                    
                    logger.info(f"LLM provider is: {api_config.llm_provider}, model used: {model_config.get_model_for_provider('code_generator', api_config.llm_provider)}")
    
                    raw_output = make_llm_completion(
                        model=model_config.get_model_for_provider("code_generator", api_config.llm_provider),
                        messages=messages,
                        temperature=app_config.code_gen_temperature,
                    )
                    logger.info(f"Generated code (attempt {attempt}):\n{raw_output}\n")
                    
                    # First, validate that the code compiles (syntax check)
                    try:
                        code_compiled = compile(raw_output, "<string>", "exec")
                    except SyntaxError as syntax_err:
                        prev_error = f"Syntax error: {str(syntax_err)}"
                        logger.warning(f"Generated code syntax error (attempt {attempt}): {syntax_err}")
                        if attempt == app_config.max_code_generation_attempts:
                            raise CodeGenerationError(
                                f"Failed to generate valid Python syntax after {attempt} attempts"
                            )
                        continue
                    
                    # Then security check: look for disallowed calls (only if syntax is valid)
                    has_violations, violations = self._uses_disallowed_calls(raw_output)
                    if has_violations:
                        prev_error = f"Security violation - used disallowed functions: {', '.join(violations)}"
                        logger.warning(f"Security violation in attempt {attempt}: {violations}")
                        if attempt == app_config.max_code_generation_attempts:
                            raise CodeGenerationError(f"Code contains security violations: {violations}")
                        continue
    
                    logger.info(f"The generated code is as follows: \n\n{raw_output}\n")
                    logger.info("Code generation successful with security checks passed")
    
                    return {"status": "success", "generated_code": code_compiled, "code": code_compiled}, raw_output
    
                except SyntaxError as e:
                    prev_error = f"Syntax error: {str(e)}"
                    logger.warning(f"Generated code syntax error (attempt {attempt}): {e}")
                    if attempt == app_config.max_code_generation_attempts:
                        raise CodeGenerationError(
                            f"Failed to generate valid Python after {attempt} attempts"
                        )
                    continue
    
                except APIError as e:
                    raise CodeGenerationError(f"Unexpected API error: {e}") from e
    
                except Exception as e:
                    prev_error = f"Unexpected error: {str(e)}"
                    logger.error(f"Code generation error (attempt {attempt}): {e}")
                    if attempt == app_config.max_code_generation_attempts:
                        raise CodeGenerationError(f"Unexpected error: {e}")
                    continue
    
            raise CodeGenerationError("No valid code produced after all attempts")        
        except (ValidationError, APIError, CodeGenerationError) as e:
            logger.error("Code generation failed: %s", e)
            return {"error": str(e), "generated_code": ""}, ""
            
        except Exception as e:
            logger.error("Unexpected error in code generation: %s", e)
            return {"error": f"Unexpected error: {e}", "generated_code": ""}, ""
  • app.py:1017-1027 (registration)
    Gradio Interface that registers the agent_code_generator wrapper as an MCP tool with name 'agent_code_generator_service' (likely prefixed as 'ShallowCodeResearch_agent_code_generator' in the HF space MCP context).
    gr.Interface(
        fn=agent_code_generator,
        inputs=[
            gr.Textbox(label="User Request", lines=12, placeholder="Describe the code you need…"),
            gr.Textbox(label="Grounded Context", lines=12, placeholder="Context for code generation…")
        ],
        outputs=gr.JSON(label="Generated Code", height=610),
        title="Code Generation Agent",
        description="Generates Python code based on user requests and context.",
        api_name="agent_code_generator_service",
    )
  • app.py:776-787 (handler)
    Wrapper handler function exposed directly via Gradio/MCP that delegates to CodeGeneratorAgent.generate_code.
    def agent_code_generator(user_request: str, grounded_context: str) -> tuple:
        """
        Wrapper for CodeGeneratorAgent to generate Python code.
    
        Args:
            user_request (str): The user's request for code generation
            grounded_context (str): Context information to guide generation
    
        Returns:
            tuple: A tuple containing the generation result and raw code
        """
        return code_generator.generate_code(user_request, grounded_context)
  • Helper function constructing the LLM prompt with strict rules for safe code generation, error feedback, and output formatting guidelines.
    def _make_prompt(self, user_req: str, ctx: str, prev_err: str = "") -> str:
        """Create a prompt for code generation with error feedback."""
        disallowed_list = ", ".join(self.DISALLOWED_CALLS)
        prev_error_text = ""
        if prev_err:
            prev_error_text = f"Previous attempt failed:\n{prev_err}\nFix it."
        
        return f"""
                You are an expert Python developer. **Rules**:
                - Never use these functions: {disallowed_list}
                - Never import os, subprocess, or sys modules
                - After defining functions/classes, call them and print the result.
                - Always include print statements to show output
                {prev_error_text}
    
                USER REQUEST:
                \"\"\"{user_req}\"\"\"
    
                CONTEXT:
                \"\"\"{ctx}\"\"\"
    
                Provide only valid Python code that can be executed safely.
    
                Provide only the Python code and never under any circumstance include any
                explanations in your response. **Do not include back ticks or the word python
                and dont include input fields**
    
                for example,
    
                import requests
                response = requests.get("https://api.example.com/data")
                print(response.json())
    
                or
    
                def add_numbers(a, b):
                    return a + b
                result = add_numbers(5, 10)
                print(result)
    
                NEVER include input() or Never use input(), even in disguised forms like raw_input()
    
                ALWAYS return valid Python code that can be executed without errors. The code returned should be
                a function or class depending on the complexity. For simple requests, return a function, 
                and for more complex requests, return a class with methods that can be called.
    
                After the creation of classes or functions, classes should be instantiated or functions should be called
                to demonstrate their usage. The final step is include the print function of the result of the class and/or function.
    
                for example
    
                class DataFetcher:
                def __init__(self, url):
                    self.url = url
                def fetch_data(self):
                    response = requests.get(self.url)
                    return response.json()
                fetcher = DataFetcher("https://api.example.com/data")
                data = fetcher.fetch_data()
                print(data)
    
                if the code requires and data manipulation etc, generate the code to test the code and print the result.
    
                for example;
                def process_data(data):
                    # Perform some data manipulation
                    return data * 2
                data = 5
    
                or 
    
                For example, to get the mean of a column in a pandas DataFrame:
    
                import pandas as pd
    
                def get_mean_of_column(df, column_name):
                    return df[column_name].mean()
    
                df = pd.DataFrame({{'A': [1, 2, 3], 'B': [4, 5, 6]}})
                mean_value = get_mean_of_column(df, 'A')
                print(mean_value)
    
                # If you want to pretty-print the DataFrame:
                import json
                print(json.dumps(df.to_dict(), indent=2))
    
                Never wrap dictionaries or lists in f-strings in print statements (e.g., avoid print(f"{{my_dict}}")).
    
                To print a dict or list, use print(my_dict) or, if you want pretty output, use the json module:
    
                import json
                print(json.dumps(my_dict, indent=2))
                If you need to include a variable in a string, only use f-strings with simple values, not dicts or lists.
    
    
                
                Never wrap dictionaries or lists in f-strings in print statements, like this:
    
                # ❌ BAD EXAMPLE — NEVER DO THIS:
                my_dict = {{'A': [1,2,3], 'B': [4,5,6]}}
                print(f"{{my_dict}}")
    
                # ❌ BAD EXAMPLE — NEVER DO THIS:
                my_list = [1, 2, 3]
                print(f"{{my_list}}")
    
                # ✅ GOOD EXAMPLES — ALWAYS DO THIS INSTEAD:
                print(my_dict)
                print(my_list)
    
                # ✅ Or, for pretty output, do:
                import json
                print(json.dumps(my_dict, indent=2))
    
                If you need to include a variable in a string, only use f-strings with simple scalar values, not dicts or lists. For example:
    
                # ✅ Good f-string with a simple value:
                mean = 3.5
                print(f"The mean is {{mean}}")
    
                # ❌ Bad f-string with a dict:
                print(f"The data is {{my_dict}}")   # <-- NEVER DO THIS
    
                # ✅ Good way to show a dict:
                print("The data is:", my_dict)
    
                Generated code like this is stricly forbidden due to the word python and the backticks
                ```python
                import x
                import y
                def my_function(i):
                    return i + 1
                ```
    
                ### **Summary**
    
                - Repeat the "NEVER wrap dicts/lists in f-strings" rule.
                - Use all-caps or bold/emoji to make "NEVER" and "ALWAYS" pop out.
                - Finish the prompt by *repeating* the most important style rule.
                - **NEVER** include backticks like this ` or the word "python" in the response.
                - Return **ONLY** the actual code as a string without any additional text.
                """
  • Security helper that parses generated code AST to block dangerous function calls and imports.
    def _uses_disallowed_calls(self, code_str: str) -> tuple[bool, list[str]]:
        """Check if code uses disallowed function calls."""
        violations = []
        try:
            tree = ast.parse(code_str)
            for node in ast.walk(tree):
                if isinstance(node, ast.Call):
                    if isinstance(node.func, ast.Name) and node.func.id in self.DISALLOWED_CALLS:
                        violations.append(node.func.id)
                elif isinstance(node, ast.Import):
                    for alias in node.names:
                        if alias.name in ["os", "subprocess", "sys"]:
                            violations.append(f"import {alias.name}")
                elif isinstance(node, ast.ImportFrom):
                    if node.module in ["os", "subprocess", "sys"]:
                        violations.append(f"from {node.module} import ...")        
        except SyntaxError:
            # Don't treat syntax errors as security violations - let them be handled separately
            return False, []
        
        return len(violations) > 0, violations
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It mentions it's a wrapper and returns a tuple, but doesn't disclose behavioral traits like whether it's read-only or mutating, authentication needs, rate limits, error handling, or what the 'generation result' entails. For a tool with no annotations, this leaves significant gaps in understanding its behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately concise with two sentences that directly state the tool's function and return value. It's front-loaded with the main purpose. However, the second sentence about the return tuple could be slightly clearer about what 'generation result' means, but overall it's efficient with minimal waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and a tool that generates code (which implies potential complexity), the description is incomplete. It doesn't explain the return format beyond 'tuple', what errors might occur, or how the wrapper interacts with CodeGeneratorAgent. For a code generation tool with no structured output documentation, more context is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters (user_request and grounded_context). The description adds no additional meaning about parameters beyond what the schema provides. With high schema coverage, the baseline is 3 even without param info in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states it's a wrapper for CodeGeneratorAgent to generate Python code, which provides a basic purpose (verb+resource). However, it doesn't differentiate from sibling tools like ShallowCodeResearch_code_runner_wrapper or explain what makes this specific to code generation versus other processing tools. The purpose is clear but lacks sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description doesn't mention when this wrapper should be chosen over other code-related tools (like code_runner_wrapper) or when to use it versus general processing tools (like llm_processor). There's no context about prerequisites or typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CodeHalwell/gradio-mcp-agent-hack'

If you have feedback or need assistance with the MCP directory API, please join our Discord server