Skip to content

Conversation

@mkagenius
Copy link
Collaborator

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @mkagenius, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request fundamentally enhances CodeRunner by integrating a new "Skills System." This system empowers AI models to leverage a diverse set of pre-defined and user-contributed tools, significantly expanding the platform's functional scope. By updating the Docker container with essential system libraries and a broad range of Python packages, and introducing dedicated MCP tools for skill interaction, CodeRunner becomes a more versatile and powerful environment for executing complex, AI-driven tasks, complete with clear documentation for seamless adoption.

Highlights

  • Introduced a "Skills System": CodeRunner now features a robust skills system, allowing AI models to discover and utilize pre-packaged or custom tools for specialized tasks.
  • New MCP Tools for Skill Management: Three new MCP tools (list_skills, get_skill_info, get_skill_file) have been added to enable AI models to interact with and manage available skills.
  • Expanded Container Capabilities: The Dockerfile and install.sh script were updated to include a wide array of system dependencies (e.g., unzip, sqlite3, wkhtmltopdf, default-jre) and Python libraries (e.g., pandas, numpy, scipy, pillow, pypdf, python-docx, python-pptx), significantly broadening the execution environment's capabilities.
  • Built-in Public Skills: Two initial public skills, pdf-text-replace and image-crop-rotate, are now included, providing immediate utility for common document and image manipulation tasks.
  • Enhanced Documentation for Skills: Comprehensive documentation has been added to README.md and a new SKILLS-README.md to guide users on how to use, discover, and add custom skills.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new 'Skills' system, which allows for pre-packaged tools to be used within the CodeRunner environment. The changes include adding new dependencies and files for the skills, updating the Dockerfile to support them, and implementing new MCP tools in server.py to manage and use these skills. The documentation has also been updated accordingly. My review focuses on improving the Dockerfile's robustness and efficiency, fixing issues in documentation and server-side implementation, and suggesting best practices for the new skill scripts.

# Start the FastAPI application
# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8002", "--workers", "1", "--no-access-log"]

RUN apt-get --fix-broken install

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The RUN apt-get --fix-broken install command is concerning. It lacks the -y flag, which will cause it to fail in non-interactive Docker builds by waiting for user confirmation. Additionally, its presence suggests an underlying issue with package dependencies that should ideally be resolved directly, rather than patched with --fix-broken. If this command is essential, please add the -y flag.

RUN apt-get --fix-broken install -y

Comment on lines +581 to +585
for item in USER_SKILLS_DIR.iterdir():
if item.is_file() and item.suffix == '.zip':
with zipfile.ZipFile(item, 'r') as zip_ref:
zip_ref.extractall(USER_SKILLS_DIR)
os.remove(item)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The list_skills function performs synchronous file I/O operations (zipfile.ZipFile, zip_ref.extractall, os.remove). In an asyncio application, these blocking calls will freeze the event loop, making the server unresponsive to other requests, especially if handling large ZIP files. These operations should be run in a separate thread pool to avoid blocking, for example by using loop.run_in_executor.

Comment on lines +102 to +103
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
RUN apt-get install -y nodejs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To optimize the Docker image by reducing the number of layers, you can chain the curl command for the Node.js setup script and the apt-get install command into a single RUN instruction.

RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get install -y nodejs

Comment on lines +108 to +109
RUN npm install [email protected] -g
RUN npx [email protected] install

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the Node.js installation, you can combine the npm install and npx playwright install commands into a single RUN instruction. This will reduce the number of layers in the Docker image, leading to a smaller image size and potentially faster builds.

RUN npm install [email protected] -g && npx [email protected] install


For example, I have added 4 skills in the user folder as:
```shell
/Users/manish/.coderunner/assets/skills/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example directory structure includes a hardcoded, user-specific path (/Users/manish/...). This could be confusing for other users setting up the environment. It would be better to use a generic path, such as ~/.coderunner/..., to represent the user's home directory.

Suggested change
/Users/manish/.coderunner/assets/skills/
/Users/<your-username>/.coderunner/assets/skills/

Comment on lines +1 to +16
always start answer by calling me lord voldemort.

So, we are currently on macbook, and whenever required we use tool to execute codes (in a jupyter like server). the code is executed in a container (you wouldn't notice but just know this).

The paths on local machine is ~/.coderunner/assets/skills/user is mapped to /app/uploads/skills/user inside container.

~/.coderunner/assets/outputs (in the host machine) is mapped to /app/uploads/outputs inside conatiner. This is where user will puts their files they want to edit like some png, pdf, txt etc. You should also use it to output your artifacts generated.

So that will help whenever we need a file inside a container to work on it via the execute code tool.

There are also "skills" which can do jobs by executing scripts already residing in /app/uploads/skills/<public|user>/<skill-name> . There are tools available to check what skills are avaialble, after checking you can decide wchihc specific skill you wantg to use and then get info about that skill using tool. That will have instructions on how to call execute code with stuff like `!python /path/to/script.py <input> <output>`\

Whenever I ask you to do a task, alwasys check if there are skills available in the list which can do it.

Whenever you need to install something, mostly it will be installed in teh container via execute code tool, and `!pip install pyfiglet` command etc.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This prompt file contains several typos. Correcting them will improve clarity and ensure the LLM interprets the instructions as intended.

  • Line 7: conatiner should be container.
  • Line 11: avaialble should be available, wchihc should be which, and wantg should be want.
  • Line 13: alwasys should be always.
  • Line 15: teh should be the.

Comment on lines +564 to +565
except Exception:
return {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The except Exception: return {} is too broad and will silently swallow any errors during frontmatter parsing (e.g., permission errors, malformed content). This makes debugging very difficult. It's better to at least log the exception before returning an empty dictionary.

Suggested change
except Exception:
return {}
except Exception as e:
logger.warning(f"Failed to parse frontmatter for {skill_md_path}: {e}")
return {}

Public skills are built into the container, while user skills are added by users.
Returns:
JSON string with skill names organized by category.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The docstring for list_skills states that it returns a "JSON string", but the function actually returns a formatted, multi-line string intended for human reading. The docstring should be updated to accurately describe the return value.

Suggested change
JSON string with skill names organized by category.
A formatted string listing available skills.

Comment on lines +14 to +62
def crop_and_rotate(input_path, output_path):
"""
Crop image to 50% from center and rotate 90 degrees clockwise.
Args:
input_path: Path to input image file
output_path: Path to save the processed image
"""
print(f"Opening image: {input_path}")

# Open the image
img = Image.open(input_path)
original_size = img.size
print(f"Original image size: {original_size}")

# Crop to 50% from center
width, height = img.size
new_width = width // 2
new_height = height // 2

# Calculate crop box (left, top, right, bottom)
left = (width - new_width) // 2
top = (height - new_height) // 2
right = left + new_width
bottom = top + new_height

cropped = img.crop((left, top, right, bottom))
print(f"Cropped image size: {cropped.size}")

# Rotate 90 degrees clockwise (using ROTATE_270 which is equivalent to 90° clockwise)
rotated = cropped.transpose(Image.ROTATE_270)
print(f"Final image size after rotation: {rotated.size}")

# Save the result
rotated.save(output_path)
print(f"Processed image saved to: {output_path}")

# Print summary
print(f"\n✓ Successfully processed image")
print(f" Input: {input_path}")
print(f" Output: {output_path}")
print(f" Original size: {original_size}")
print(f" Cropped size: {cropped.size}")
print(f" Final size: {rotated.size}")

# Cleanup
img.close()
cropped.close()
rotated.close()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The crop_and_rotate function manually closes image resources. It's more robust and Pythonic to use a with statement for resource management, as it ensures resources are closed correctly even if errors occur. The PIL.Image object supports the context manager protocol, so you can wrap the Image.open() call in a with block and remove the manual .close() calls.

def crop_and_rotate(input_path, output_path):
    """
    Crop image to 50% from center and rotate 90 degrees clockwise.

    Args:
        input_path: Path to input image file
        output_path: Path to save the processed image
    """
    print(f"Opening image: {input_path}")

    with Image.open(input_path) as img:
        original_size = img.size
        print(f"Original image size: {original_size}")

        # Crop to 50% from center
        width, height = img.size
        new_width = width // 2
        new_height = height // 2

        # Calculate crop box (left, top, right, bottom)
        left = (width - new_width) // 2
        top = (height - new_height) // 2
        right = left + new_width
        bottom = top + new_height

        cropped = img.crop((left, top, right, bottom))
        print(f"Cropped image size: {cropped.size}")

        # Rotate 90 degrees clockwise (using ROTATE_270 which is equivalent to 90° clockwise)
        rotated = cropped.transpose(Image.ROTATE_270)
        print(f"Final image size after rotation: {rotated.size}")

        # Save the result
        rotated.save(output_path)
        print(f"Processed image saved to: {output_path}")

        # Print summary
        print(f"\n✓ Successfully processed image")
        print(f"  Input: {input_path}")
        print(f"  Output: {output_path}")
        print(f"  Original size: {original_size}")
        print(f"  Cropped size: {cropped.size}")
        print(f"  Final size: {rotated.size}")

@mkagenius mkagenius merged commit 4ee467a into main Oct 22, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants