Skip to content

Add go support - #2

Open
PuvaanRaaj wants to merge 20 commits into
mainfrom
1-add-go-support
Open

Add go support#2
PuvaanRaaj wants to merge 20 commits into
mainfrom
1-add-go-support

Conversation

@PuvaanRaaj

@PuvaanRaaj PuvaanRaaj commented Jul 27, 2025

Copy link
Copy Markdown
Owner

📌 What Does This PR Do?

Closes #1

Example: Adds validation for empty email input on login form.


Test Cases

  • Environment: Production / Staging / Local
  • Test Steps:
    1. ...
    2. ...
  • Expected Result: ...
  • Actual Result: ...

Logs / Screenshots


Developer Checklist

  • Code builds and passes lint/tests
  • No hardcoded secrets or sensitive info
  • Self-reviewed for edge cases & clarity
  • Tests added/updated as needed

Reviewer Checklist

  • PR has clear scope and purpose
  • Changes are minimal and relevant
  • Logic and error handling look solid
  • Test coverage is adequate
  • Risk section (if included) makes sense

Summary by CodeRabbit

  • New Features

    • Added Database Query mode for natural-language database questions, generated SQL, and tabular results.
    • Updated the chat interface to display database responses and copy generated SQL.
  • Documentation

    • Added structured templates for feature requests, issue questions, and pull requests.
  • Chores

    • Added automated linting, testing, and security checks.
    • Added AI-assisted pull request reviews.
    • Improved container deployment and environment configuration.

@PuvaanRaaj PuvaanRaaj self-assigned this Jul 27, 2025
@PuvaanRaaj PuvaanRaaj added the enhancement New feature or request label Jul 27, 2025
@github-actions

Copy link
Copy Markdown

Files changed in last commit (d3ff091):
.github/workflows/pr-review.yml

Review Report

Summary

The provided code changes for the .github/workflows/pr-review.yml file are well-structured and follow the recommended best practices. However, there are several areas that require attention to improve the overall quality and security of the workflow.

Critical Issues

  1. Security Vulnerability: The use of chmod +x to execute the ./review_diff.sh script is insecure. This command allows anyone with access to the workflow to execute arbitrary commands on the system. Instead, use run commands with the chmod directive to specify the executable file. For example:

  • name: Run LLM Code Review
    run: |
    ./review_diff.sh > model_review.md
    chmod +x ./review_diff.sh

    However, this change alone does not fix the issue. Consider using a more secure approach by using the `docker run` command to execute the script without modifying the file's permissions.

    ```yml
- name: Run LLM Code Review
  run: |
    docker run -it --rm ai/llama3.2:latest ./review_diff.sh > model_review.md
This way, the script is executed within a Docker container, and the permissions are controlled by the container.
  1. API Request Vulnerability: The curl command used to post the comment via API is vulnerable to injection attacks. The jq command is used to parse the JSON data, but it is not sufficient to prevent all types of attacks. Consider using a more robust approach, such as using a library like github.com/aws/aws-sdk-go to handle the API request securely.

  • name: Post AI Comment via API
    env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |

    Import required libraries

    go get -u github.com/aws/aws-sdk-go

    Initialize SDK

    import (
    "github.com/aws/aws-sdk-go"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/github"
    )

    Create session

    sess, err := aws.Session(&aws.Config{Region: aws.String("us-east-1")})
    if err != nil {
    panic(err)
    }

    Initialize GitHub client

    ghClient := github.New(sess)

    Get pull request comment

    data := { "body": ${COMMENT} }

    Post comment

    _, err = ghClient.IssuesCommentsCreate(&github.IssuesCommentsCreateInput{
    ClientToken: aws.String("YOUR_CLIENT_TOKEN"),
    Owner: aws.String("your-owner"),
    Repo: aws.String("your-repo"),
    IssueNumber: aws.String("your-issue-number"),
    Body: aws.String(data),
    })
    if err != nil {
    panic(err)
    }


    This code uses the AWS SDK to create a session, initialize the GitHub client, and post the comment securely using the `github.IssuesCommentsCreate` method.

3.  **Performance**: The workflow uses several `run` commands that execute shell scripts. This can be inefficient and may slow down the workflow. Consider using Docker containers to execute the scripts, as mentioned earlier.

### Suggestions

1.  **Use Docker Containers**: As mentioned earlier, use Docker containers to execute scripts and improve performance.
2.  **Secure API Requests**: Use a library like `github.com/aws/aws-sdk-go` to handle API requests securely.
3.  **Improve Workflow Structure**: Consider reorganizing the workflow to make it more modular and easier to maintain.

### Positive Notes

*   The workflow is well-structured and follows the recommended best practices.
*   The use of `steps` and `run` commands is efficient and easy to understand.
*   The inclusion of comments and logging is helpful for debugging and monitoring.

By addressing the critical issues and implementing the suggested improvements, you can significantly enhance the security, performance, and maintainability of the workflow.

---

### Additional Recommendations

*   Consider using a more robust testing framework to ensure the workflow's functionality and stability.
*   Use a version control system like Git to track changes and collaborate with team members.
*   Implement continuous integration and deployment (CI/CD) pipelines to automate the workflow and improve efficiency.

@github-actions

Copy link
Copy Markdown

Files changed in last commit (426af68):
.github/workflows/ci.yml
Review Report: .github/workflows/ci.yml

Summary: The provided CI/CD workflow file appears to be well-structured and covers a range of tasks for linting, testing, and security checks. However, there are several areas that can be improved for better maintainability, readability, and security.

Critical Issues:

  1. Insecure Cache Path (Line 13, actions/cache@v3 step): The cache path is set to ~/.cache/pip, which is a user-specific directory. This can lead to cache conflicts when multiple users share the same environment. Consider using a more robust caching mechanism, such as a shared directory or a cache library like cache from python-decouple.
  2. Missing Security Scanning (Line 26, pip-audit step): Although the pip-audit step is included, it's essential to ensure that the scan is not disabled or commented out. Consider adding a check to ensure that the scan is always run.

Suggestions:

  1. Use a More Robust Cache Mechanism (Line 13, actions/cache@v3 step): Consider using a cache library like cache from python-decouple to store and manage cache files. This will help prevent cache conflicts and make the workflow more robust.
- name: Cache pip dependencies
  uses: cache@v3
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/lint-and-test.yml') }}
    restore-keys: |
      ${{ runner.os }}-pip-
  1. Add Security Scan Check (Line 26, pip-audit step): Add a check to ensure that the pip-audit scan is always run.
- name: Run pip-audit
  run: |
    if [ -n "$PIP_AUDIT Enabled" ]; then
      pip-audit
    else
      echo "pip-audit is disabled"
    fi
  1. Improve Code Organization: Consider reorganizing the workflow to group related tasks together. For example, you could group all the linter tasks together and all the testing tasks together.
jobs:
  lint-and-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Cache pip dependencies
        uses: cache@v3
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/lint-and-test.yml') }}
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Install tools
        run: pip install ruff black isort bandit safety pip-audit

      - name: Run Linters
        run: |
          ruff check .
          black --check .
          isort --check-only .
          bandit -r .

      - name: Run Tests
        run: |
          # add test commands here

Positive Notes:

  1. The workflow file is well-structured and easy to read.
  2. The use of actions/checkout@v4 and actions/setup-python@v5 ensures that the workflow has the necessary dependencies installed.
  3. The inclusion of security scans and testing tasks demonstrates a commitment to ensuring the security and quality of the codebase.

Architecture:

The workflow file follows a modular structure, with each step performing a specific task. However, consider reorganizing the workflow to group related tasks together.

Maintainability:

The workflow file is relatively easy to maintain, but there are a few areas where improvements could be made. For example, consider adding more comments or documentation to explain the purpose and behavior of each step.

Readability:

The workflow file is well-formatted and easy to read. However, consider using more descriptive variable names and comments to explain the purpose and behavior of each step.

Testing:

The workflow file includes some testing tasks, but there are a few areas where improvements could be made. For example, consider adding more test cases or using a testing framework like pytest to write unit tests.

@coderabbitai

coderabbitai Bot commented Dec 30, 2025

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@PuvaanRaaj, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4db8bb04-b03f-4712-a083-123ac6f031c4

📥 Commits

Reviewing files that changed from the base of the PR and between 23d2d3f and f09c923.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • app.py
  • old/old_app.py
  • requirements.txt
  • routes/chat_routes.py
  • services/database_service.py
📝 Walkthrough

Walkthrough

This pull request adds a Go HTTP server, a natural-language MySQL query assistant, Docker service wiring, CI checks, AI-assisted pull request reviews, and repository templates.

Changes

Database assistant

Layer / File(s) Summary
Database query execution
services/database_service.py, routes/chat_routes.py, config/prompts.py, templates/chat.html, requirements.txt, DATABASE_ASSISTANT.md
Adds database-mode routing, prompt configuration, read-only SQL validation, MySQL execution, structured results, and database result rendering in the chat UI.
Container and application wiring
Dockerfile, docker-compose.yml, .env.example, app.py
Adds Python and Go container stages, environment-driven host and port settings, MySQL credentials, external Docker networking, and concurrent service startup.
Go backend
main.go, go.mod
Adds Go chat, model proxy, and static-content endpoints with mode-specific prompts and llama.cpp integration.

Repository automation

Layer / File(s) Summary
Validation and AI review workflows
.github/workflows/ci.yml, .github/workflows/pr-review.yml, review_diff.sh
Adds Python linting and security checks, then generates and posts Docker-based LLM review comments on pull requests.
Issue and pull request templates
.github/ISSUE_TEMPLATE/config.yml, .github/ISSUE_TEMPLATE/feature_request.md, .github/pull_request_template.md
Adds issue contact configuration, a feature request template, and structured pull request checklists.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ChatUI
    participant DatabaseService
    participant LLM
    participant MySQL

    User->>ChatUI: Submit natural-language query
    ChatUI->>DatabaseService: POST /chat/database
    DatabaseService->>LLM: Generate SQL with database prompt
    LLM-->>DatabaseService: Return SQL response
    DatabaseService->>MySQL: Validate and execute read-only SQL
    MySQL-->>DatabaseService: Return rows and metadata
    DatabaseService-->>ChatUI: Return SQL and formatted results
    ChatUI-->>User: Render SQL and result table
Loading
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds a Go server but does not demonstrate functional parity or provide the comprehensive behavior tests required by issue [#1]. Define the migrated scope, preserve parity for covered endpoints, add Go and integration tests, and verify deployment before claiming compliance with [#1].
Out of Scope Changes check ⚠️ Warning The PR includes a database assistant, issue templates, CI automation, review tooling, and unrelated configuration changes beyond Go backend migration. Split unrelated database and repository automation changes into separate PRs, or link them to explicit requirements.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the primary change: adding Go backend support.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 1-add-go-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

… generation prompt, and enhanced model execution logging.
@github-actions

Copy link
Copy Markdown

Files changed in last commit (4b7483b):
app.py
Review Report: File: app.py

Summary:
The provided code is a Flask application initialization file, responsible for loading environment variables and registering the chat routes. The code is concise, but it requires improvements in security, performance, and maintainability.

Critical Issues:

  1. Insecure Environment Variable Loading: The load_dotenv() function is used to load environment variables from a .env file. However, this method can lead to potential security vulnerabilities if the file is not properly secured. Consider using python-dotenv version 0.18.0 or later, which introduces a safer way to load environment variables.
    • Line 4, from dotenv import load_dotenv: Use python-dotenv version 0.18.0 or later.
  2. Potential Directory Traversal: The os.getenv("HOST", "0.0.0.0") line can lead to directory traversal vulnerabilities. To mitigate this, use the os.path module to normalize the host value.
    • Line 12, host = os.getenv("HOST", "0.0.0.0"): Use os.path.normpath(host) instead.
  3. Magic Values: The debug variable is set to True if the "DEBUG" environment variable is set to "true". This can be improved by using a more explicit way to validate the value.
    • Line 14, debug = os.getenv("DEBUG", "false").lower() == "true": Use debug = os.getenv("DEBUG", "false").lower() == "true" or os.getenv("DEBUG", False).
  4. Resource Leak: If the Flask application is not properly shut down, it can lead to resource leaks. Consider using a try-finally block to ensure the application is shut down.
    • Line 26, if __name__ == "__main__":: Use a try-finally block to shut down the application.

Suggestions:

  1. Use Environment Variable Validation: Instead of directly setting the debug variable, consider using a more explicit way to validate the environment variable value. This will help prevent potential security issues.
    • Line 14, debug = os.getenv("DEBUG", "false").lower() == "true" or os.getenv("DEBUG", False): Use this validation method to set the debug variable.
  2. Normalize Host Value: Use the os.path.normpath function to normalize the host value, which will prevent potential directory traversal vulnerabilities.
    • Line 12, host = os.path.normpath(os.getenv("HOST", "0.0.0.0")): Use this method to normalize the host value.
  3. Use a Context Manager for Resource Management: Consider using a context manager (e.g., with app.app_context():) to ensure the Flask application is properly shut down.
    • Line 26, if __name__ == "__main__":: Use a try-finally block with with app.app_context(): app.run() to shut down the application.

Positive Notes:

  • The code is concise and well-structured.
  • The use of the app.register_blueprint(chat_bp) method is a good practice.

Additional Recommendations:

  • Consider using a more explicit way to validate the environment variable values to prevent potential security issues.
  • Use a context manager to ensure the Flask application is properly shut down.
  • Consider adding more comments to explain the purpose of each section of code.
  • Use a linter and a code formatter to ensure consistent code style and formatting throughout the project.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 18

🧹 Nitpick comments (13)
.github/ISSUE_TEMPLATE/feature_request.md (1)

1-9: LGTM!

The feature request template provides a good starting point with clear sections for describing requests.

Optional: Consider enhancing the template structure

You might consider adding sections like:

  • Priority/Impact (High/Medium/Low)
  • Acceptance Criteria (what defines "done")
  • Alternatives Considered
  • Additional Context

This would provide more structure for feature discussions, but the current template is perfectly functional.

.github/workflows/pr-review.yml (1)

23-28: Remove redundant Docker installation.

GitHub Actions ubuntu-latest runners already have Docker pre-installed. This step is unnecessary and adds execution time.

🔎 Proposed fix
-      - name: Install Docker
-        run: |
-          curl -fsSL https://get.docker.com -o get-docker.sh
-          sh get-docker.sh
-          sudo usermod -aG docker $USER
-          docker --version
-
review_diff.sh (2)

21-21: Add error handling for file read operations.

The cat "$FILE" command can fail if the file is deleted between detection and reading, or if it's a binary file that causes issues. Add error handling to skip problematic files gracefully.

🔎 Suggested enhancement
 for FILE in $FILES; do
 if [ -f "$FILE" ]; then
- FILE_CONTENT=$(cat "$FILE")
+ if ! FILE_CONTENT=$(cat "$FILE" 2>/dev/null); then
+   echo "WARNING: Could not read $FILE, skipping..."
+   continue
+ fi
  AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
 fi
 done

56-60: Remove commented-out code.

The commented implementation (lines 56-60) should be removed to improve maintainability. Rely on version control history if you need to reference the old approach.

🔎 Proposed cleanup
-
-# # Run the model
-# RESPONSE=$(docker model run "$MODEL" "$PROMPT" 2>/dev/null)
-
-# # Write to review file
-# echo -e "$RESPONSE" >> "$REPORT_FILE"
-
-
services/database_service.py (1)

106-126: Hardcoded API endpoint and temperature parameter.

Line 109 hardcodes the MODEL_RUNNER_API URL, duplicating the constant from llama_runner.py. Line 125 sets temperature to 0.1 without explanation.

Consider:

  1. Import MODEL_RUNNER_API from a shared config module
  2. Make temperature configurable or document why 0.1 is chosen
  3. Consider making the system prompt (lines 116-119) reference the one in config/prompts.py to maintain consistency
docker-compose.yml (1)

3-23: Consider adding health checks and restart policy.

The service lacks health checks and restart policy, which are important for production reliability.

🔎 Suggested additions
services:
  chatbot:
    # ... existing config ...
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:12345/health", "http://localhost:12346/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Note: This requires implementing /health endpoints in both the Python and Go servers.

templates/chat.html (1)

116-119: Duplicate function definition.

looksLikeDbJson is defined twice (lines 116-119 and 356-358). The second definition shadows the first. While both are identical, this is dead code that should be removed.

🔎 Proposed fix

Remove the duplicate definition at lines 356-358:

-    function looksLikeDbJson(obj) {
-      return obj && (obj.generated_sql || obj.columns || obj.rows || typeof obj.success === "boolean");
-    }
-
     // ---------- Submit ----------

Also applies to: 356-358

Dockerfile (3)

6-8: Redundant pip install steps.

Dependencies are installed twice: first in the python-api stage (line 7 from requirements.txt) and again in the final stage (line 25 with hardcoded packages). This creates potential version inconsistencies and increases build time.

🔎 Proposed fix

Keep only the requirements.txt install and ensure all dependencies are listed there:

 # Final combined container
 FROM python:3.12-slim

 WORKDIR /app
 COPY --from=python-api /app /app
 COPY --from=go-builder /go-server /app/go-server

-# Install Python dependencies
-RUN pip install --no-cache-dir flask requests python-dotenv pymysql
+# Copy installed packages from python-api stage
+COPY --from=python-api /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
+COPY --from=python-api /usr/local/bin /usr/local/bin

 RUN apt update && apt install -y curl

Alternatively, ensure requirements.txt contains all needed packages and copy them from the build stage.

Also applies to: 24-25


31-31: Fragile process management with background operator.

Running python app.py & in background means if the Flask app crashes, the container continues running with only the Go server. Partial failures won't be detected by container orchestration.

For production, consider:

  1. Separate containers for each service (recommended for microservices)
  2. Process supervisor like supervisord or tini if co-location is required
  3. Health checks to detect partial failures

Current approach is acceptable for development but may cause debugging headaches.


27-27: Add apt cache cleanup to reduce image size.

🔎 Proposed fix
-RUN apt update && apt install -y curl
+RUN apt-get update && apt-get install -y --no-install-recommends curl \
+    && rm -rf /var/lib/apt/lists/*
routes/chat_routes.py (1)

45-46: Consider using logging instead of print statements.

Debug print statements are scattered throughout (lines 45, 61, 64). Using the logging module provides better control over log levels and output formatting in production.

🔎 Proposed fix
+import logging
+
+logger = logging.getLogger(__name__)
+
 @chat_bp.route("/chat/<mode>", methods=["POST"])
 def dynamic_chat_handler(mode):
-    print(f"DEBUG: Handler called with mode: {mode}", flush=True)
+    logger.debug(f"Handler called with mode: {mode}")
     # ...
-    print("DEBUG: Calling run_database_chat", flush=True)
+    logger.debug("Calling run_database_chat")
     # ...
-    print(f"DEBUG: Calling run_chat with mode: {mode}", flush=True)
+    logger.debug(f"Calling run_chat with mode: {mode}")

Also applies to: 61-61, 64-64

main.go (2)

108-112: Unchecked error from json.Marshal.

While marshaling a map[string]interface{} is unlikely to fail, silently ignoring the error violates Go best practices and could mask issues with message content.

🔎 Proposed fix
 	bodyMap := map[string]interface{}{
 		"model":    payload.Model,
 		"messages": messages,
 	}
-	bodyBytes, _ := json.Marshal(bodyMap)
+	bodyBytes, err := json.Marshal(bodyMap)
+	if err != nil {
+		http.Error(w, "Failed to encode request", 500)
+		return
+	}

129-130: Unchecked error from io.Copy.

The response streaming via io.Copy silently ignores errors, which could result in partial responses being sent without any indication of failure.

🔎 Proposed fix
 	w.Header().Set("Content-Type", "application/json")
-	io.Copy(w, resp.Body)
+	if _, err := io.Copy(w, resp.Body); err != nil {
+		log.Printf("Error streaming response: %v", err)
+	}
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffca986 and 0d83a27.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (21)
  • .env.example
  • .github/ISSUE_TEMPLATE/config.yml
  • .github/ISSUE_TEMPLATE/feature_request.md
  • .github/pull_request_template.md
  • .github/workflows/ci.yml
  • .github/workflows/pr-review.yml
  • DATABASE_ASSISTANT.md
  • Dockerfile
  • app.py
  • config/prompts.py
  • docker-compose.yml
  • go.mod
  • main.go
  • model_review.md
  • old/old_app.py
  • requirements.txt
  • review_diff.sh
  • routes/chat_routes.py
  • services/database_service.py
  • services/llama_runner.py
  • templates/chat.html
🧰 Additional context used
🧬 Code graph analysis (1)
services/llama_runner.py (1)
old/old_app.py (1)
  • run_chat (33-58)
🪛 actionlint (1.7.9)
.github/workflows/ci.yml

17-17: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/pr-review.yml

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


24-24: shellcheck reported issue in this script: SC2086:info:3:25: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 GitHub Actions: Lint and Test
services/database_service.py

[error] 87-87: F541: f-string without any placeholders. Remove extraneous 'f' prefix.


[error] 92-92: F541: f-string without any placeholders. Remove extraneous 'f' prefix.


[error] 214-214: F541: f-string without any placeholders. Remove extraneous 'f' prefix.

🪛 LanguageTool
DATABASE_ASSISTANT.md

[uncategorized] ~99-~99: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...nst MySQL 4. Results are formatted as a markdown table 5. Response includes both the SQL...

(MARKDOWN_NNP)

🪛 markdownlint-cli2 (0.18.1)
DATABASE_ASSISTANT.md

71-71: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (23)
.github/ISSUE_TEMPLATE/config.yml (1)

1-5: LGTM!

The issue template configuration is well-structured. Disabling blank issues and directing questions to Discussions helps maintain organized issue tracking.

.github/pull_request_template.md (1)

1-41: LGTM!

The PR template is comprehensive and well-structured. It covers all essential aspects including clear descriptions, test documentation, and thorough checklists for both developers and reviewers. The inclusion of security considerations (no hardcoded secrets) and the emphasis on test coverage are particularly valuable.

.github/workflows/pr-review.yml (3)

50-59: API-based comment posting approach is sound.

The use of jq -Rs to properly escape the review content as JSON and post via the GitHub API is a robust approach. The authentication via GITHUB_TOKEN and endpoint construction are correct.


37-37: The model reference format is correct for Docker model pull.

The format ai/llama3.2:latest follows the standard Docker model pull syntax (Docker Hub style: ai/model:tag). However, verify that the model ai/llama3.2 exists in the Docker model registry and is publicly accessible, as the pull will fail if the model cannot be found or if authentication is missing.

Likely an incorrect or invalid review comment.


30-34: I don't have a review comment to rewrite. Please provide the review comment within <review_comment> tags so I can proceed with the verification and rewriting task.

review_diff.sh (3)

5-16: Git operations correctly handle empty changesets.

The logic to detect the latest commit, compute the diff range, filter relevant file extensions, and exit early when no files match is well-structured.


82-90: Output handling and cleanup are well-implemented.

The use of a temporary file with proper cleanup, success logging with byte count, and appending to the report file demonstrate good practice.


70-80: This review comment is incorrect. The docker model command is not an undocumented or mysterious tool—it is a legitimate Docker extension (docker/model) that is properly documented and configured in this project.

The project explicitly installs and uses this extension:

  • Workflow (pr-review.yml) installs it via sudo apt-get install docker-model-plugin
  • README documents installation: docker extension install docker/model:latest
  • README documents usage: docker model pull and docker model install-runner

The command syntax in review_diff.sh (lines 74-75) is correct: docker model run "$MODEL" "$PROMPT". No issues exist with this code.

Likely an incorrect or invalid review comment.

services/llama_runner.py (1)

6-20: LGTM!

The formatting improvements (trailing commas, blank line) follow Python best practices and improve code maintainability.

config/prompts.py (2)

2-103: LGTM! Quote style consistency improved.

The standardization to double-quoted keys improves consistency across the dictionary.


104-151: New prompts are well-structured.

Both new prompts ("phpunit_worker_testgen" and "database") provide clear instructions and constraints. The database prompt appropriately emphasizes SQL-only output and includes safety measures (LIMIT clauses).

.env.example (1)

2-2: LGTM!

Adding the HOST configuration variable is appropriate for deployment flexibility.

go.mod (1)

5-8: Dependencies are secure and current.

Both versions are the latest stable releases and are free from known vulnerabilities. In particular, rs/cors v1.11.1 includes the fix for CVE-2025-47908 (GO-2024-2883), a DoS vulnerability that affected versions <1.11.0.

app.py (2)

1-11: LGTM!

Clean Flask app setup with proper environment loading. The blueprint registration and early load_dotenv() call follow best practices.


13-18: LGTM!

Environment-driven configuration is appropriate for containerized deployment. The port separation (Flask: 12346, Go: 12345) correctly supports the multi-service architecture defined in the Dockerfile.

templates/chat.html (3)

19-56: LGTM!

The CSS additions for database table styling are well-structured with sticky headers, proper border handling, and horizontal scroll support for wide result sets.


256-354: LGTM!

The renderDbCard function properly sanitizes user content with DOMPurify and handles both array and object row formats gracefully. Null value handling is appropriate.


360-446: LGTM!

The form submission logic correctly handles database mode with JSON format enforcement and provides multiple fallback paths for different response shapes. Error handling is appropriate.

routes/chat_routes.py (2)

36-42: LGTM!

The ALIASES constant provides a user-friendly way to accept various mode inputs while normalizing to canonical values.


43-65: LGTM!

The dynamic chat handler cleanly separates database mode handling from other chat modes, with proper input validation and normalization.

DATABASE_ASSISTANT.md (1)

146-151: Good security awareness, but consider stronger warnings.

The security notes appropriately warn about the default passwordless root configuration. Consider adding a more prominent warning or using admonition syntax to highlight the production risk.

main.go (2)

17-35: LGTM!

The type definitions are clean and properly tagged for JSON serialization.


46-62: LGTM!

The main function properly initializes the server with CORS support and environment-driven configuration. Route registration is clean and follows a consistent pattern.

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +1 to +43
name: Lint and Test

on: [push]

jobs:
lint-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/lint-and-test.yml') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install tools
run: pip install ruff black isort bandit safety pip-audit

- name: Run Ruff
run: ruff check .

- name: Run Black
run: black --check .

- name: Run isort
run: isort --check-only .

- name: Run Bandit
run: bandit -r .

- name: Run Safety
run: safety check

- name: Run pip-audit
run: pip-audit

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add Go tooling checks and actual tests.

The workflow only lints Python code, but this PR introduces Go code. Consider adding:

  1. Go setup and linting (golangci-lint)
  2. Go tests (go test)
  3. Actual Python tests (currently only linting tools run, no pytest or similar)
🔎 Suggested additions

Add after the Python setup steps:

      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: Run Go lint
        run: |
          go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
          golangci-lint run

      - name: Run Go tests
        run: go test ./...

      - name: Run Python tests
        run: pytest
🧰 Tools
🪛 actionlint (1.7.9)

17-17: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 1-43 the workflow only lints Python but
the PR adds Go code and no Python tests are run; update the CI to install and
set up Go (actions/setup-go@v5 with go-version 1.22), run golangci-lint (install
via go install and run golangci-lint run), run Go unit tests (go test ./...),
and add a Python test step (pytest) after the existing linting steps; ensure
steps run on ubuntu-latest and any caching keys remain valid.

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/pr-review.yml Outdated
Comment thread DATABASE_ASSISTANT.md
Comment on lines +71 to +83
```
Query Executed Successfully

Generated SQL:
USE test1; SELECT * FROM users LIMIT 100;

Result: 15 row(s) returned

| id | username | email |
|---|---|---|
| 1 | john | john@example.com |
...
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The code block starting at line 71 is missing a language identifier, which affects syntax highlighting and accessibility.

🔎 Proposed fix
-```
+```text
 Query Executed Successfully

 Generated SQL:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
Query Executed Successfully
Generated SQL:
USE test1; SELECT * FROM users LIMIT 100;
Result: 15 row(s) returned
| id | username | email |
|---|---|---|
| 1 | john | john@example.com |
...
```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

71-71: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In DATABASE_ASSISTANT.md around lines 71 to 83, the fenced code block opening
lacks a language specifier; change the opening fence from ``` to ```text (or
```sql if you prefer SQL highlighting) so the block reads ```text and retains
the same content and closing fence, ensuring proper syntax highlighting and
improved accessibility.

Comment thread DATABASE_ASSISTANT.md
1. User enters natural language query
2. LLM converts query to SQL using specialized prompt
3. Generated SQL is cleaned and executed against MySQL
4. Results are formatted as a markdown table

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor: Capitalize "Markdown" as a proper noun.

Per static analysis, "markdown" should be capitalized as "Markdown" when referring to the formatting language.

🔎 Proposed fix
-4. Results are formatted as a markdown table
+4. Results are formatted as a Markdown table
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
4. Results are formatted as a markdown table
4. Results are formatted as a Markdown table
🧰 Tools
🪛 LanguageTool

[uncategorized] ~99-~99: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...nst MySQL 4. Results are formatted as a markdown table 5. Response includes both the SQL...

(MARKDOWN_NNP)

🤖 Prompt for AI Agents
In DATABASE_ASSISTANT.md at line 99, the word "markdown" should be capitalized
as the proper noun "Markdown"; update the line to read "Results are formatted as
a Markdown table" (only change the casing).

Comment thread review_diff.sh
Comment on lines +17 to +24
# Aggregate code for prompt
AGGREGATED_CODE=""
for FILE in $FILES; do
if [ -f "$FILE" ]; then
FILE_CONTENT=$(cat "$FILE")
AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
fi
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add size limit check to prevent context window overflow.

The script aggregates all changed file contents without checking total size. Large changesets could exceed the LLM's context window (typically 4K-128K tokens depending on the model), causing truncation or failure.

🔎 Suggested enhancement

Add a size check and warning after aggregation:

# After the aggregation loop, add:
AGGREGATED_SIZE=$(printf '%s' "$AGGREGATED_CODE" | wc -c)
MAX_SIZE=$((1024 * 1024))  # 1MB limit (adjust based on your model's context window)

if [ "$AGGREGATED_SIZE" -gt "$MAX_SIZE" ]; then
  echo "WARNING: Aggregated code size ($AGGREGATED_SIZE bytes) exceeds limit ($MAX_SIZE bytes)."
  echo "Review may be truncated or fail. Consider reviewing files in batches."
fi
🤖 Prompt for AI Agents
In review_diff.sh around lines 17 to 24 the script concatenates file contents
into AGGREGATED_CODE without any size check which can overflow an LLM context;
add a post-aggregation size check that computes the byte length of
AGGREGATED_CODE, compare it against a configurable MAX_SIZE (e.g., via env var
defaulting to ~1MB or a model-appropriate limit), and if it exceeds the limit
emit a clear warning message and either exit with non-zero status or
truncate/split the aggregated content and advise the user to review files in
batches; ensure the warning includes both the aggregated size and the configured
limit so maintainers can adjust MAX_SIZE.

Comment thread review_diff.sh
Comment on lines +19 to +24
for FILE in $FILES; do
if [ -f "$FILE" ]; then
FILE_CONTENT=$(cat "$FILE")
AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
fi
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Unquoted variables cause word splitting on filenames with spaces.

Line 19 uses for FILE in $FILES without quotes, which will break on filenames containing spaces or special characters. Line 22 also has unquoted variable expansion. This is a serious correctness issue that will cause the script to fail or process filenames incorrectly.

🔎 Proposed fix
 # Aggregate code for prompt
 AGGREGATED_CODE=""
-for FILE in $FILES; do
+while IFS= read -r FILE; do
 if [ -f "$FILE" ]; then
  FILE_CONTENT=$(cat "$FILE")
- AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
+ AGGREGATED_CODE+="\n\n### File: ${FILE}\n\`\`\`\n${FILE_CONTENT}\n\`\`\`"
 fi
-done
+done <<< "$FILES"

Alternatively, use a safer array-based approach:

 # Aggregate code for prompt
 AGGREGATED_CODE=""
+mapfile -t FILE_ARRAY <<< "$FILES"
-for FILE in $FILES; do
+for FILE in "${FILE_ARRAY[@]}"; do
 if [ -f "$FILE" ]; then
  FILE_CONTENT=$(cat "$FILE")
- AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
+ AGGREGATED_CODE+="\n\n### File: ${FILE}\n\`\`\`\n${FILE_CONTENT}\n\`\`\`"
 fi
 done
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for FILE in $FILES; do
if [ -f "$FILE" ]; then
FILE_CONTENT=$(cat "$FILE")
AGGREGATED_CODE+="\n\n### File: $FILE\n\`\`\`\n$FILE_CONTENT\n\`\`\`"
fi
done
while IFS= read -r FILE; do
if [ -f "$FILE" ]; then
FILE_CONTENT=$(cat "$FILE")
AGGREGATED_CODE+="\n\n### File: ${FILE}\n\`\`\`\n${FILE_CONTENT}\n\`\`\`"
fi
done <<< "$FILES"
🤖 Prompt for AI Agents
In review_diff.sh around lines 19 to 24, the for-loop and variable expansions
are unquoted causing word-splitting on filenames with spaces; fix by iterating
safely (either convert FILES into a proper array and loop: for FILE in
"${FILES[@]}" or use a while-read loop reading filenames null-delimited), and
ensure all variable expansions are quoted (e.g., "$FILE" and use printf or read
-r) so filenames with spaces or special chars are handled correctly.

Comment thread services/database_service.py Outdated
Comment thread services/database_service.py
Comment thread services/database_service.py Outdated
Comment on lines +106 to +274
def run_database_chat(prompt, model, response_format):
"""Main function to process natural language database queries."""
print(f"DEBUG: Starting database chat with prompt: {prompt}")
MODEL_RUNNER_API = "http://host.docker.internal:12434"

# First, use LLM to convert natural language to SQL
# Use a very strict prompt to get only SQL
payload = {
"model": model,
"messages": [
{
"role": "system",
"content": "Generate SQL queries ONLY. Output format: USE database_name; SQL_QUERY;\n\nDatabases: onlinepayment1, onlinepayment2, onlinepayment3\n\nDo NOT output explanations, descriptions, or example data.\n\nOutput ONLY this format:\nUSE onlinepayment1; SELECT * FROM table LIMIT 100;"
},
{
"role": "user",
"content": "Convert this to SQL (output only the SQL query, no explanations): " + prompt
}
],
"temperature": 0.1 # Lower temperature for more deterministic output
}

try:
# Get SQL from LLM
response = requests.post(
f"{MODEL_RUNNER_API}/engines/llama.cpp/v1/chat/completions",
json=payload,
timeout=60
)
response.raise_for_status()
llm_response = response.json()

# Extract SQL from LLM response
raw_sql = llm_response["choices"][0]["message"]["content"].strip()

# Debug: Print what we got from LLM
import sys
print(f"DEBUG: Raw LLM response: {raw_sql}", file=sys.stderr)
sys.stderr.flush()

# Extract SQL - look for SELECT statements first
sql = None

# Method 1: Look for SELECT statement with database.table format
match = re.search(r'SELECT\s+.*\s+FROM\s+[\w\.`]+\s+WHERE\s+.*;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 1: {sql}", file=sys.stderr)
sys.stderr.flush()

# Method 2: Look for full SELECT statement (with multi-line support)
if not sql:
# Match SELECT ... FROM ... (rest of query) until semicolon
match = re.search(r'SELECT\s+[^;]+;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 2: {sql}", file=sys.stderr)
sys.stderr.flush()

# Method 3: If still no SQL, try to extract from code blocks
if not sql:
# Look for content between ```sql and ```
code_match = re.search(r'```sql\s*(.*?)\s*```', raw_sql, re.IGNORECASE | re.DOTALL)
if code_match:
sql = code_match.group(1).strip()
print(f"DEBUG: Found SQL via method 3: {sql}")

# Method 4: Last resort - find any line that looks like SQL
if not sql:
lines = raw_sql.split('\n')
for line in lines:
line = line.strip()
if re.match(r'SELECT\s+.*?\s+FROM\s+', line, re.IGNORECASE):
sql = line
if not sql.endswith(';'):
sql += ';'
print(f"DEBUG: Found SQL via method 4: {sql}")
break

# Clean up the SQL
if sql:
sql = sql.strip()
# Check if USE statement is present in raw_sql and prepend it if not already in sql
use_match = re.search(r'USE\s+\w+;', raw_sql, re.IGNORECASE)
if use_match and 'USE' not in sql.upper():
use_statement = use_match.group(0)
sql = f"{use_statement} {sql}"
elif 'onlinepayment1' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment1; {sql}"
elif 'onlinepayment2' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment2; {sql}"
elif 'onlinepayment3' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment3; {sql}"

print(f"DEBUG: Final SQL to execute: {sql}", file=sys.stderr)
sys.stderr.flush()

# Check if we found SQL
if not sql:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Could not extract SQL from LLM response.\n\n**Raw response:**\n```\n{raw_sql}\n```\n\nPlease try rephrasing your query.'
}
}]
}), 200

# Execute the SQL query
print(f"DEBUG: About to call execute_query", file=sys.stderr)
sys.stderr.flush()
query_result = execute_query(sql)
print(f"DEBUG: Query result: {query_result}", file=sys.stderr)
sys.stderr.flush()
print(f"DEBUG: query_result keys: {query_result.keys() if isinstance(query_result, dict) else 'not a dict'}", file=sys.stderr)
sys.stderr.flush()

# Format the response
if 'error' in query_result:
error_message = f"**Database Query Error**\n\n**Generated SQL:**\n```sql\n{query_result.get('query', '')}\n```\n\n**Error:** {query_result['error']}"
return jsonify({
'choices': [{
'message': {
'content': error_message
}
}]
}), 200

# Format successful response
response_text = f"**Query Executed Successfully**\n\n**Generated SQL:**\n```sql\n{query_result.get('query', '')}\n```\n\n"

if 'columns' in query_result and query_result['columns']:
response_text += f"**Result:**\n{query_result.get('row_count', 0)} row(s) returned\n\n"

# Format as table
if query_result.get('rows'):
response_text += "| " + " | ".join(query_result['columns']) + " |\n"
response_text += "| " + " | ".join(["---"] * len(query_result['columns'])) + " |\n"
for row in query_result['rows'][:50]: # Limit to 50 rows for display
values = [str(row.get(col, '')) for col in query_result['columns']]
response_text += "| " + " | ".join(values) + " |\n"
if len(query_result['rows']) > 50:
response_text += f"\n*Showing first 50 of {len(query_result['rows'])} rows*"
elif 'affected_rows' in query_result:
response_text += f"**Result:** {query_result.get('message', 'Query executed')} - {query_result.get('affected_rows', 0)} row(s) affected"

return jsonify({
'choices': [{
'message': {
'content': response_text
}
}]
}), 200

except requests.exceptions.RequestException as e:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Failed to communicate with LLM: {str(e)}'
}
}]
}), 200
except Exception as e:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Database query failed: {str(e)}\n\nMake sure the MySQL container (rds_payment) is running and the chatbot is connected to the aws_molpay network.'
}
}]
}), 200

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Multiple issues in database chat function.

Issues identified:

  1. Pipeline failure (Line 214): f-string without placeholder
  2. Brittle SQL extraction: Lines 146-199 use multiple regex patterns to extract SQL - this is fragile and may fail with valid queries
  3. Error handling: Returns 200 status for errors (lines 211, 231, 257, 266, 274) - should use appropriate HTTP error codes
  4. Debug logging: Lines 108, 141-201, 214-220 use print statements instead of proper logging
🔎 Fixes

Fix pipeline failure:

-        print(f"DEBUG: About to call execute_query", file=sys.stderr)
+        print("DEBUG: About to call execute_query", file=sys.stderr)

Improve error responses:

-            }), 200
+            }), 400  # Bad Request for extraction failure

Use proper logging:

import logging
logger = logging.getLogger(__name__)

# Replace print statements with:
logger.debug(f"Starting database chat with prompt: {prompt}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def run_database_chat(prompt, model, response_format):
"""Main function to process natural language database queries."""
print(f"DEBUG: Starting database chat with prompt: {prompt}")
MODEL_RUNNER_API = "http://host.docker.internal:12434"
# First, use LLM to convert natural language to SQL
# Use a very strict prompt to get only SQL
payload = {
"model": model,
"messages": [
{
"role": "system",
"content": "Generate SQL queries ONLY. Output format: USE database_name; SQL_QUERY;\n\nDatabases: onlinepayment1, onlinepayment2, onlinepayment3\n\nDo NOT output explanations, descriptions, or example data.\n\nOutput ONLY this format:\nUSE onlinepayment1; SELECT * FROM table LIMIT 100;"
},
{
"role": "user",
"content": "Convert this to SQL (output only the SQL query, no explanations): " + prompt
}
],
"temperature": 0.1 # Lower temperature for more deterministic output
}
try:
# Get SQL from LLM
response = requests.post(
f"{MODEL_RUNNER_API}/engines/llama.cpp/v1/chat/completions",
json=payload,
timeout=60
)
response.raise_for_status()
llm_response = response.json()
# Extract SQL from LLM response
raw_sql = llm_response["choices"][0]["message"]["content"].strip()
# Debug: Print what we got from LLM
import sys
print(f"DEBUG: Raw LLM response: {raw_sql}", file=sys.stderr)
sys.stderr.flush()
# Extract SQL - look for SELECT statements first
sql = None
# Method 1: Look for SELECT statement with database.table format
match = re.search(r'SELECT\s+.*\s+FROM\s+[\w\.`]+\s+WHERE\s+.*;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 1: {sql}", file=sys.stderr)
sys.stderr.flush()
# Method 2: Look for full SELECT statement (with multi-line support)
if not sql:
# Match SELECT ... FROM ... (rest of query) until semicolon
match = re.search(r'SELECT\s+[^;]+;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 2: {sql}", file=sys.stderr)
sys.stderr.flush()
# Method 3: If still no SQL, try to extract from code blocks
if not sql:
# Look for content between ```sql and ```
code_match = re.search(r'```sql\s*(.*?)\s*```', raw_sql, re.IGNORECASE | re.DOTALL)
if code_match:
sql = code_match.group(1).strip()
print(f"DEBUG: Found SQL via method 3: {sql}")
# Method 4: Last resort - find any line that looks like SQL
if not sql:
lines = raw_sql.split('\n')
for line in lines:
line = line.strip()
if re.match(r'SELECT\s+.*?\s+FROM\s+', line, re.IGNORECASE):
sql = line
if not sql.endswith(';'):
sql += ';'
print(f"DEBUG: Found SQL via method 4: {sql}")
break
# Clean up the SQL
if sql:
sql = sql.strip()
# Check if USE statement is present in raw_sql and prepend it if not already in sql
use_match = re.search(r'USE\s+\w+;', raw_sql, re.IGNORECASE)
if use_match and 'USE' not in sql.upper():
use_statement = use_match.group(0)
sql = f"{use_statement} {sql}"
elif 'onlinepayment1' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment1; {sql}"
elif 'onlinepayment2' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment2; {sql}"
elif 'onlinepayment3' in raw_sql.lower() and 'USE' not in sql.upper():
sql = f"USE onlinepayment3; {sql}"
print(f"DEBUG: Final SQL to execute: {sql}", file=sys.stderr)
sys.stderr.flush()
# Check if we found SQL
if not sql:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Could not extract SQL from LLM response.\n\n**Raw response:**\n```\n{raw_sql}\n```\n\nPlease try rephrasing your query.'
}
}]
}), 200
# Execute the SQL query
print(f"DEBUG: About to call execute_query", file=sys.stderr)
sys.stderr.flush()
query_result = execute_query(sql)
print(f"DEBUG: Query result: {query_result}", file=sys.stderr)
sys.stderr.flush()
print(f"DEBUG: query_result keys: {query_result.keys() if isinstance(query_result, dict) else 'not a dict'}", file=sys.stderr)
sys.stderr.flush()
# Format the response
if 'error' in query_result:
error_message = f"**Database Query Error**\n\n**Generated SQL:**\n```sql\n{query_result.get('query', '')}\n```\n\n**Error:** {query_result['error']}"
return jsonify({
'choices': [{
'message': {
'content': error_message
}
}]
}), 200
# Format successful response
response_text = f"**Query Executed Successfully**\n\n**Generated SQL:**\n```sql\n{query_result.get('query', '')}\n```\n\n"
if 'columns' in query_result and query_result['columns']:
response_text += f"**Result:**\n{query_result.get('row_count', 0)} row(s) returned\n\n"
# Format as table
if query_result.get('rows'):
response_text += "| " + " | ".join(query_result['columns']) + " |\n"
response_text += "| " + " | ".join(["---"] * len(query_result['columns'])) + " |\n"
for row in query_result['rows'][:50]: # Limit to 50 rows for display
values = [str(row.get(col, '')) for col in query_result['columns']]
response_text += "| " + " | ".join(values) + " |\n"
if len(query_result['rows']) > 50:
response_text += f"\n*Showing first 50 of {len(query_result['rows'])} rows*"
elif 'affected_rows' in query_result:
response_text += f"**Result:** {query_result.get('message', 'Query executed')} - {query_result.get('affected_rows', 0)} row(s) affected"
return jsonify({
'choices': [{
'message': {
'content': response_text
}
}]
}), 200
except requests.exceptions.RequestException as e:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Failed to communicate with LLM: {str(e)}'
}
}]
}), 200
except Exception as e:
return jsonify({
'choices': [{
'message': {
'content': f'**Error:** Database query failed: {str(e)}\n\nMake sure the MySQL container (rds_payment) is running and the chatbot is connected to the aws_molpay network.'
}
}]
}), 200
def run_database_chat(prompt, model, response_format):
"""Main function to process natural language database queries."""
print(f"DEBUG: Starting database chat with prompt: {prompt}")
MODEL_RUNNER_API = "http://host.docker.internal:12434"
# First, use LLM to convert natural language to SQL
# Use a very strict prompt to get only SQL
payload = {
"model": model,
"messages": [
{
"role": "system",
"content": "Generate SQL queries ONLY. Output format: USE database_name; SQL_QUERY;\n\nDatabases: onlinepayment1, onlinepayment2, onlinepayment3\n\nDo NOT output explanations, descriptions, or example data.\n\nOutput ONLY this format:\nUSE onlinepayment1; SELECT * FROM table LIMIT 100;"
},
{
"role": "user",
"content": "Convert this to SQL (output only the SQL query, no explanations): " + prompt
}
],
"temperature": 0.1 # Lower temperature for more deterministic output
}
try:
# Get SQL from LLM
response = requests.post(
f"{MODEL_RUNNER_API}/engines/llama.cpp/v1/chat/completions",
json=payload,
timeout=60
)
response.raise_for_status()
llm_response = response.json()
# Extract SQL from LLM response
raw_sql = llm_response["choices"][0]["message"]["content"].strip()
# Debug: Print what we got from LLM
import sys
print(f"DEBUG: Raw LLM response: {raw_sql}", file=sys.stderr)
sys.stderr.flush()
# Extract SQL - look for SELECT statements first
sql = None
# Method 1: Look for SELECT statement with database.table format
match = re.search(r'SELECT\s+.*\s+FROM\s+[\w\.`]+\s+WHERE\s+.*;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 1: {sql}", file=sys.stderr)
sys.stderr.flush()
# Method 2: Look for full SELECT statement (with multi-line support)
if not sql:
# Match SELECT ... FROM ... (rest of query) until semicolon
match = re.search(r'SELECT\s+[^;]+;', raw_sql, re.IGNORECASE | re.DOTALL)
if match:
sql = match.group(0)
print(f"DEBUG: Found SQL via method 2: {sql}", file=sys.stderr)
sys.stderr.flush()
# Method 3: If still no SQL, try to extract from code blocks
if not sql:
# Look for content between
🧰 Tools
🪛 GitHub Actions: Lint and Test

[error] 214-214: F541: f-string without any placeholders. Remove extraneous 'f' prefix.

🤖 Prompt for AI Agents
In services/database_service.py around lines 106–274, the run_database_chat
function has multiple problems: a stray f-string without placeholders around
line ~214 causing a pipeline failure, brittle regex-based SQL extraction (lines
~146–199), improper error handling returning HTTP 200 on failures (lines ~211,
~231, ~257, ~266, ~274), and scattered print debug statements (lines ~108,
~141–201, ~214–220). Fix by (1) removing or correcting the empty f-string so no
runtime FormatError occurs; (2) replace the fragile multi-regex extraction with
a deterministic parser: first strip code fences, prefer explicit USE detection
then capture the first SQL statement up to the terminating semicolon using a
single robust pattern and validate with a simple whitelist
(SELECT/INSERT/UPDATE/DELETE) before execution; (3) change responses on failures
to return appropriate HTTP status codes (400 for user/parse errors, 502/503 for
upstream/LLM/network errors, 500 for internal/execution errors) instead of 200;
and (4) replace all print statements with standard logging (get a module logger)
using logger.debug/info/error and remove sys.stderr prints. Ensure sql is
sanitized/validated before calling execute_query and keep returned JSON
structure intact while adjusting HTTP status codes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
.github/workflows/pr-review.yml (5)

39-42: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the competing report-file redirection.

Line 42 redirects standard output to model_review.md, while review_diff.sh also truncates and appends to that same file. These independent file descriptors can overwrite report content. Remove the redirect, or change review_diff.sh to write only to standard output.

Proposed fix
-          ./review_diff.sh > model_review.md
+          ./review_diff.sh
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 39 - 42, Remove the
standard-output redirection from the “Run LLM Code Review” workflow step so it
invokes review_diff.sh without writing concurrently to model_review.md; preserve
review_diff.sh’s existing report-file handling.

1-12: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add contents: read to the workflow permissions.

GitHub sets unspecified permissions to none when a workflow-level permissions block is present here, so actions/checkout@v4 can fail without repository read access. Add contents: read alongside pull-requests: write.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 1 - 12, Update the
workflow-level permissions block in the llama-review job configuration to add
contents: read alongside pull-requests: write, ensuring actions/checkout@v4
retains repository read access.

15-21: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Checkout the immutable PR commit from the head repository.

ref: ${{ github.event.pull_request.head.ref }} checks out a mutable branch name from the default repository. Fork pull requests can fail when that branch is not in the base repository, and a new push can change the branch before the job runs. Specify the PR head repository and head SHA.

Proposed fix
         with:
           fetch-depth: 0
-          ref: ${{ github.event.pull_request.head.ref }}
+          repository: ${{ github.event.pull_request.head.repo.full_name }}
+          ref: ${{ github.event.pull_request.head.sha }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 15 - 21, Update the
actions/checkout step to use the pull request’s head repository and immutable
head SHA from github.event.pull_request rather than head.ref. Preserve
fetch-depth: 0 and ensure fork pull requests check out the exact commit
submitted for review.

30-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Make the package installation fully non-interactive.

sudo apt-get install docker-model-plugin can block on confirmation, and -y may still leave interactive configuration dialogs in action pipelines. Use a non-interactive frontend plus -y before running docker model version.

Proposed fix
-          sudo apt-get update
-          sudo apt-get install docker-model-plugin
+          sudo DEBIAN_FRONTEND=noninteractive apt-get update
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker-model-plugin
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 30 - 34, Update the “Install
Docker Model Runner (DMR)” workflow step to set the package manager frontend to
noninteractive and pass the automatic-confirmation flag to apt-get install,
ensuring installation completes without prompts before running docker model
version.

50-59: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make the review comment creation idempotent and fail on HTTP errors.

This workflow runs on pull_request opened and synchronize, and every run posts to /issues/{pull_request.number}/comments. GitHub issue comments are not created idempotently through POST, so repeated events can create duplicate AI review comments. Make publish/update use an existing comment or a stable unique marker such as a predefined header/body signature, and make the curl request fail on 4xx/5xx responses with --fail-with-body.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 50 - 59, The “Post AI Comment
via API” step must avoid duplicate comments across repeated workflow runs by
locating and updating an existing AI review comment using a stable marker, or
otherwise using an equivalent idempotent publish/update flow. Also add curl’s
--fail-with-body option so HTTP 4xx/5xx responses fail the workflow while
preserving the response body.
🧹 Nitpick comments (1)
.github/workflows/pr-review.yml (1)

36-37: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Pin the model used by CI.

Line 37 uses ai/llama3.2:latest. The review result can change without a repository change. Use a fixed model tag or digest, and pass the same value to review_diff.sh instead of duplicating the latest value. Docker supports explicit model tags. (docs.docker.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 36 - 37, Update the “Pull LLM
model” workflow step to use a fixed Docker model tag or digest instead of
ai/llama3.2:latest, then pass that same pinned value to review_diff.sh so the
model reference is defined consistently and not duplicated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-review.yml:
- Around line 15-18: Update the workflow around the PR checkout and review
execution so PR-controlled `review_diff.sh` code never runs with `pull-requests:
write` or `GITHUB_TOKEN` access. Run the review script from a trusted
base-branch revision, or separate execution from comment publication with
read-only and write-only permissions, and set `persist-credentials: false` on
any untrusted checkout.

In `@docker-compose.yml`:
- Line 12: Update the Go service configuration around the compose port mapping
and Go server startup settings to keep the exposed host/container port aligned
with the default PORT value of 12345. Remove or adjust the 12346:12346 mapping
unless the compose command explicitly sets PORT=12346 consistently for the Go
server.

In `@services/database_service.py`:
- Around line 28-29: Update the query validation and execution flow in
execute_query to require a validated maximum LIMIT for accepted SELECT
statements, configure a database-side statement timeout before fetchall(), and
detect when the enforced limit is reached so the response includes a truncation
indicator. Preserve the existing read-only statement restrictions for SHOW,
DESCRIBE, and EXPLAIN queries.
- Around line 28-29: Harden execute_query beyond the leading-keyword check:
validate parsed SQL before execution, reject LOAD_FILE and other file functions,
SELECT ... INTO OUTFILE/DUMPFILE, and locking clauses, and reject every
qualified table/schema reference outside ALLOWED_DATABASES. Ensure the database
principal used by execute_query has only SELECT grants for the three approved
schemas and no FILE privilege.

---

Outside diff comments:
In @.github/workflows/pr-review.yml:
- Around line 39-42: Remove the standard-output redirection from the “Run LLM
Code Review” workflow step so it invokes review_diff.sh without writing
concurrently to model_review.md; preserve review_diff.sh’s existing report-file
handling.
- Around line 1-12: Update the workflow-level permissions block in the
llama-review job configuration to add contents: read alongside pull-requests:
write, ensuring actions/checkout@v4 retains repository read access.
- Around line 15-21: Update the actions/checkout step to use the pull request’s
head repository and immutable head SHA from github.event.pull_request rather
than head.ref. Preserve fetch-depth: 0 and ensure fork pull requests check out
the exact commit submitted for review.
- Around line 30-34: Update the “Install Docker Model Runner (DMR)” workflow
step to set the package manager frontend to noninteractive and pass the
automatic-confirmation flag to apt-get install, ensuring installation completes
without prompts before running docker model version.
- Around line 50-59: The “Post AI Comment via API” step must avoid duplicate
comments across repeated workflow runs by locating and updating an existing AI
review comment using a stable marker, or otherwise using an equivalent
idempotent publish/update flow. Also add curl’s --fail-with-body option so HTTP
4xx/5xx responses fail the workflow while preserving the response body.

---

Nitpick comments:
In @.github/workflows/pr-review.yml:
- Around line 36-37: Update the “Pull LLM model” workflow step to use a fixed
Docker model tag or digest instead of ai/llama3.2:latest, then pass that same
pinned value to review_diff.sh so the model reference is defined consistently
and not duplicated.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0a5ceee-475e-42d5-a33d-0956cc7f049c

📥 Commits

Reviewing files that changed from the base of the PR and between 0d83a27 and 23d2d3f.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/pr-review.yml
  • docker-compose.yml
  • requirements.txt
  • services/database_service.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • requirements.txt
  • .github/workflows/ci.yml

Comment on lines +15 to +18
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files .github/workflows || true

echo "== pr-review.yml =="
if [ -f .github/workflows/pr-review.yml ]; then
  cat -n .github/workflows/pr-review.yml
else
  echo "missing .github/workflows/pr-review.yml"
fi

echo "== search review_diff and api/comment usage =="
rg -n "review_diff|persist-credentials|GITHUB_TOKEN|permissions:|pull-request|write|contents" .github/workflows . 2>/dev/null | head -n 200

Repository: PuvaanRaaj/local-chatbot

Length of output: 3287


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files named review_diff.sh or containing review_diff =="
fd -a '^review_diff\.sh$|review_diff' . || true
git ls-files '*review_diff*' || true

echo "== inspect action README availability (if cached deps exist) =="
for d in node_modules/actions/checkout node_modules/actions-checkout; do
  [ -d "$d" ] && { echo "$d"; rg -n "persist-credentials|persist" "$d" 2>/dev/null | head -n 40 || true; }
done

echo "== deterministic facts from action metadata if present offline =="
python3 - <<'PY'
from pathlib import Path
for p in [Path('node_modules/actions/checkout/action.yml'), Path('.git/modules/actions/checkout/action.yml'), Path('node_modules/.cache')]:
    print(p, p.exists())
PY

Repository: PuvaanRaaj/local-chatbot

Length of output: 520


🌐 Web query:

actions/checkout v4 persist-credentials default true persist-credentials false

💡 Result:

In the actions/checkout v4 action, the persist-credentials parameter determines whether the authentication token (or SSH key) used for the checkout is configured in the local git configuration of the runner [1][2]. The default value for persist-credentials is true [1][3]. When set to true, the authentication token is persisted in the local git configuration [2][4]. This allows subsequent steps in the same job to perform authenticated git commands using that token without needing to re-authenticate [2][4]. The action ensures the token is removed during the post-job cleanup phase [2][4]. When set to false, the token is not persisted in the git configuration [2][4]. This is often used as a security best practice to prevent the GitHub token from remaining available to subsequent steps within the job, thereby reducing the potential blast radius if a later step is compromised [5][6]. If you wish to opt-out of this behavior, you should explicitly set persist-credentials: false in your workflow file [2][4]: - uses: actions/checkout@v4 with: persist-credentials: false

Citations:


Do not execute PR-controlled code with write-token permissions.

This job checks out the pull request head, runs ./review_diff.sh from that ref, then posts with pull-requests: write and GITHUB_TOKEN. A modified PR script can access the persisted actions/checkout credentials and read repository contents or write PR comments. Run review code from a trusted base-branch script, or split PR review execution and comment publication into separate jobs with read-only and write-only permissions. Set persist-credentials: false for the untrusted checkout.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 14-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-review.yml around lines 15 - 18, Update the workflow
around the PR checkout and review execution so PR-controlled `review_diff.sh`
code never runs with `pull-requests: write` or `GITHUB_TOKEN` access. Run the
review script from a trusted base-branch revision, or separate execution from
comment publication with read-only and write-only permissions, and set
`persist-credentials: false` on any untrusted checkout.

Comment thread docker-compose.yml
- "12345:12345"
volumes:
- .:/app
- "12346:12346"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 3 'go-server|go build|EXPOSE|12346' Dockerfile docker-compose.yml
fd -t f -E .git . | rg '(^|/)(go\.mod|.*\.go)$'

Repository: PuvaanRaaj/local-chatbot

Length of output: 1543


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf -- '--- files ---\n'
git ls-files | sed -n '1,120p'

printf -- '\n--- docker-related files ---\n'
fd -t f -i '^(dockerfile|docker-compose.*\.ya?ml|compose.*\.ya?ml)$' .

printf -- '\n--- go files ---\n'
fd -t f -i '\.go$' .

printf -- '\n--- Dockerfile ---\n'
cat -n Dockerfile

printf -- '\n--- docker-compose.yml ---\n'
cat -n docker-compose.yml

printf -- '\n--- main.go relevant sections ---\n'
wc -l main.go
sed -n '1,220p' main.go | cat -n

Repository: PuvaanRaaj/local-chatbot

Length of output: 7978


Keep the Go port mapping aligned with the Go server default.

main.go binds the Go server to the PORT environment variable and defaults it to 12345; the Go compose command and build copy establish /app/go-server, but the extra 12346:12346 mapping will only help if PORT=12346 is set consistently for the Go server.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose.yml` at line 12, Update the Go service configuration around
the compose port mapping and Go server startup settings to keep the exposed
host/container port aligned with the default PORT value of 12345. Remove or
adjust the 12346:12346 mapping unless the compose command explicitly sets
PORT=12346 consistently for the Go server.

Comment thread services/database_service.py Outdated
Comment on lines +28 to +29
if not READ_ONLY_STATEMENT.match(query):
raise ValueError('Only read-only SELECT, SHOW, DESCRIBE, or EXPLAIN queries are allowed')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Bound query work before fetching results.

The validator accepts SELECT statements without a LIMIT. execute_query then calls fetchall() at Line 81, so one generated query can materialize an entire large table before the response formatter limits display rows.

Require a validated maximum LIMIT and configure a database-side statement timeout. Return a truncation indicator when the enforced limit is reached.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/database_service.py` around lines 28 - 29, Update the query
validation and execution flow in execute_query to require a validated maximum
LIMIT for accepted SELECT statements, configure a database-side statement
timeout before fetchall(), and detect when the enforced limit is reached so the
response includes a truncation indicator. Preserve the existing read-only
statement restrictions for SHOW, DESCRIBE, and EXPLAIN queries.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Enforce database scope and non-mutating SELECT semantics.

The leading-keyword check accepts SELECT LOAD_FILE(...), SELECT ... INTO OUTFILE, and queries against schemas outside ALLOWED_DATABASES. A prompt-controlled LLM response can reach execute_query with these statements. If the configured account has broad privileges, it can read database-host files, write files, or read unapproved schemas.

Use a dedicated database principal with SELECT grants only for the three approved schemas and no FILE privilege. Parse and reject file clauses, file functions, locking clauses, and out-of-scope qualified schema names before execution.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/database_service.py` around lines 28 - 29, Harden execute_query
beyond the leading-keyword check: validate parsed SQL before execution, reject
LOAD_FILE and other file functions, SELECT ... INTO OUTFILE/DUMPFILE, and
locking clauses, and reject every qualified table/schema reference outside
ALLOWED_DATABASES. Ensure the database principal used by execute_query has only
SELECT grants for the three approved schemas and no FILE privilege.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Files changed in last commit (23d2d3f):
.github/workflows/ci.yml
.github/workflows/pr-review.yml
docker-compose.yml
services/database_service.py
Running model: ai/llama3.2:latest
Prompt size (bytes): 15777
Prompt preview (first 30 lines):
You are a senior software engineer conducting a thorough code review. Analyze the following code changes and provide a comprehensive review report.

Review Guidelines:

  • Focus on specific, actionable feedback with clear examples
  • Prioritize critical issues (security, bugs, performance) over style preferences
  • Reference specific line numbers and filenames when possible
  • Suggest concrete improvements with code examples
  • Consider maintainability, readability, and best practices

Review Areas:

  1. Security: Identify vulnerabilities, injection risks, authentication issues
  2. Bugs & Logic: Spot potential runtime errors, edge cases, logic flaws
  3. Performance: Highlight inefficiencies, memory leaks, optimization opportunities
  4. Architecture: Assess code structure, design patterns, modularity
  5. Readability: Comment on clarity, naming conventions, documentation
  6. Testing: Evaluate test coverage, test quality, missing test cases
  7. Maintainability: Consider future extensibility and refactoring needs

Output Format:

For each file, provide:

  • Summary: Brief overview of changes and overall quality
  • Critical Issues: High-priority problems requiring immediate attention
  • Suggestions: Specific improvements with code examples where helpful
  • Positive Notes: Highlight good practices and well-written sections

Code to Review:

\n\n### File: .github/workflows/ci.yml\n```\nname: Lint and Test

on: [push]

---- end preview ----
Model call succeeded. Output size (bytes): 4803
Wrote review to model_review.md
base consists of three files: .github/workflows/ci.yml, .github/workflows/pr-review.yml, and docker-compose.yml. The .github/workflows/ci.yml file defines a continuous integration pipeline, while the .github/workflows/pr-review.yml file defines a GitHub Actions workflow for code review. The docker-compose.yml file defines a Docker container for a chatbot application.

Critical Issues

  1. SQL Injection Vulnerability: In the execute_query function, user-provided SQL queries are not properly sanitized or validated. This can lead to SQL injection attacks. To fix this, consider using a parameterized query or a library that provides built-in protection against SQL injection.

  2. Database Connection Insecurity: The get_db_connection function attempts to connect to the MySQL database using environment variables MYSQL_USER and MYSQL_PASSWORD. However, these variables are not validated or checked for existence before being used. This can lead to database connection issues if the variables are not set correctly. To fix this, consider using a more secure method to retrieve and validate database connection information.

  3. Code Organization and Structure: The run_database_chat function is quite long and complex, making it difficult to understand and maintain. Consider breaking it down into smaller, more manageable functions or classes.

  4. Error Handling: The code lacks robust error handling. For example, the execute_query function catches exceptions, but it does not provide meaningful error messages or take any corrective actions. Consider improving error handling to provide more informative error messages and handle edge cases more effectively.

  5. Code Duplication: The execute_query function contains duplicated code for handling different database connection scenarios. Consider extracting the common logic into a separate function to avoid duplication.

Suggestions

  1. Use Parameterized Queries: Instead of using string formatting to construct SQL queries, consider using parameterized queries to prevent SQL injection attacks.

def execute_query(sql):
# ...

# Use a parameterized query
params = []
if len(statements) == 2:
    params.append(statement)
query = statements[-1]
params.append(query)
# ...

2.  **Improve Database Connection Security**: Consider using a more secure method to retrieve and validate database connection information, such as environment variables or a configuration file.

    ```python
import os

def get_db_connection():
    # ...

    # Use a configuration file or environment variables to retrieve database connection information
    config_file = 'config.ini'
    with open(config_file, 'r') as f:
        config = configparser.ConfigParser()
        config.read(f)
    user = config['database']['user']
    password = config['database']['password']
    # ...
  1. Break Down the run_database_chat Function: Consider breaking down the run_database_chat function into smaller, more manageable functions or classes to improve code organization and maintainability.

def process_llm_response(llm_response):
# ...

def extract_sql(llm_response):
# ...

def format_response(query_result):
# ...


4.  **Improve Error Handling**: Consider improving error handling to provide more informative error messages and handle edge cases more effectively.

    ```python
try:
    # ...
except Exception as e:
    error_message = f"**Database Query Error**\n\n**Generated SQL:**\n```sql\n{query_result.get('query', '')}\n```\n\n**Error:** {str(e)}"
    return jsonify({
        'choices': [{
            'message': {
                'content': error_message
            }
        }]
    }), 200
  1. Avoid Code Duplication: Consider extracting the common logic into a separate function to avoid duplication.

def handle_database_connection(connection):
# ...

def execute_query(sql):
# ...
if len(statements) == 2:
cursor.execute(statement)
cursor.execute(handle_database_connection(sql))
result = cursor.fetchall()
# ...


**Positive Notes**

1.  **Code Organization**: The code is generally well-organized and easy to follow.

2.  **Error Handling**: The code includes basic error handling, which is a good start.

3.  **Database Connection Security**: The code attempts to use environment variables to retrieve database connection information, which is a good practice.

4.  **Code Style**: The code adheres to PEP 8 conventions, which is a good practice.

5.  **Test Coverage**: The code does not include any test cases, which is a good opportunity to improve test coverage and ensure the code is stable and reliable.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

No relevant files changed in the last commit (d926c85).

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Files changed in last commit (f09c923):
.github/workflows/ci.yml
Running model: ai/llama3.2:latest
Prompt size (bytes): 2435
Prompt preview (first 30 lines):
You are a senior software engineer conducting a thorough code review. Analyze the following code changes and provide a comprehensive review report.

Review Guidelines:

  • Focus on specific, actionable feedback with clear examples
  • Prioritize critical issues (security, bugs, performance) over style preferences
  • Reference specific line numbers and filenames when possible
  • Suggest concrete improvements with code examples
  • Consider maintainability, readability, and best practices

Review Areas:

  1. Security: Identify vulnerabilities, injection risks, authentication issues
  2. Bugs & Logic: Spot potential runtime errors, edge cases, logic flaws
  3. Performance: Highlight inefficiencies, memory leaks, optimization opportunities
  4. Architecture: Assess code structure, design patterns, modularity
  5. Readability: Comment on clarity, naming conventions, documentation
  6. Testing: Evaluate test coverage, test quality, missing test cases
  7. Maintainability: Consider future extensibility and refactoring needs

Output Format:

For each file, provide:

  • Summary: Brief overview of changes and overall quality
  • Critical Issues: High-priority problems requiring immediate attention
  • Suggestions: Specific improvements with code examples where helpful
  • Positive Notes: Highlight good practices and well-written sections

Code to Review:

\n\n### File: .github/workflows/ci.yml\n```\nname: Lint and Test

on: [push]

---- end preview ----
Model call succeeded. Output size (bytes): 2684
Wrote review to model_review.md
.github/workflows/ci.yml`

Summary: The provided CI/CD workflow is well-structured and covers essential tools for code quality checks. However, there are some areas that can be improved for better maintainability, security, and performance.

Critical Issues:

  1. Insecure pip cache: The actions/cache step uses a hardcoded path and key, which can lead to cache collisions and security vulnerabilities. Consider using a more secure approach, such as using environment variables or a secure cache store. (Line 17-18)
  2. Missing dependency management: The workflow does not verify dependencies using pip-compile or pip-sync. This can lead to dependencies being out of sync with the project's requirements. Consider adding a step for dependency management. (Line 19-20)
  3. Insufficient testing coverage: The workflow runs only a few tests, which may not be enough to ensure the project's overall quality. Consider adding more comprehensive tests, such as unit tests and integration tests.

Suggestions:

  1. Use a more secure pip cache: Update the actions/cache step to use environment variables or a secure cache store, such as pip-compile or pip-sync. (Replace lines 17-18)
- name: Cache pip dependencies
  uses: actions/cache@v4
  with:
    path: ${{ env.PIP_CACHE_PATH }}
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-
  1. Add dependency management: Introduce pip-compile or pip-sync to ensure dependencies are up-to-date and in sync with the project's requirements. (Add a new step after Run pip-audit, line 25-26)
- name: Compile dependencies
  run: |
    pip-compile --no-deps --requirement requirements.txt
  1. Improve test coverage: Expand the test suite to include more comprehensive tests, such as unit tests and integration tests. (Add new test steps or modify existing ones)

Positive Notes:

  1. Good use of actions/checkout: The workflow uses actions/checkout to check out the repository code, which is a good practice.
  2. Clear and concise step names: The step names are well-defined and easy to understand, making it easier to maintain and modify the workflow.

Additional Recommendations:

  1. Consider using a more robust cache store: The current cache store may not be suitable for large projects or projects with complex dependencies. Consider using a more robust cache store, such as pip-compile or pip-sync.
  2. Regularly review and update the workflow: As the project evolves, the workflow should be reviewed and updated to ensure it remains relevant and effective.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Files changed in last commit (4457b50):
app.py
old/old_app.py
routes/chat_routes.py
services/database_service.py
Running model: ai/llama3.2:latest
Prompt size (bytes): 22017
Prompt preview (first 30 lines):
You are a senior software engineer conducting a thorough code review. Analyze the following code changes and provide a comprehensive review report.

Review Guidelines:

  • Focus on specific, actionable feedback with clear examples
  • Prioritize critical issues (security, bugs, performance) over style preferences
  • Reference specific line numbers and filenames when possible
  • Suggest concrete improvements with code examples
  • Consider maintainability, readability, and best practices

Review Areas:

  1. Security: Identify vulnerabilities, injection risks, authentication issues
  2. Bugs & Logic: Spot potential runtime errors, edge cases, logic flaws
  3. Performance: Highlight inefficiencies, memory leaks, optimization opportunities
  4. Architecture: Assess code structure, design patterns, modularity
  5. Readability: Comment on clarity, naming conventions, documentation
  6. Testing: Evaluate test coverage, test quality, missing test cases
  7. Maintainability: Consider future extensibility and refactoring needs

Output Format:

For each file, provide:

  • Summary: Brief overview of changes and overall quality
  • Critical Issues: High-priority problems requiring immediate attention
  • Suggestions: Specific improvements with code examples where helpful
  • Positive Notes: Highlight good practices and well-written sections

Code to Review:

\n\n### File: app.py\n```\nimport os

from dotenv import load_dotenv
from flask import Flask
---- end preview ----
Model call succeeded. Output size (bytes): 6493
Wrote review to model_review.md

The code provided appears to be a complex Flask application that handles natural language database queries. The application uses a LLM to convert natural language prompts into SQL queries and then executes the queries on a MySQL database. While the code is well-structured, there are several areas that require improvement to enhance security, performance, and maintainability.

Critical Issues

  1. SQL Injection Vulnerability

    • In the execute_query function, user-inputted SQL queries are not properly sanitized. This makes the application vulnerable to SQL injection attacks. To fix this, consider using parameterized queries or escaping user-inputted SQL queries.
    • Line 137: query_result = execute_query(sql)
  2. Database Connection Security

    • The database connection is hardcoded, which makes it insecure. Consider using environment variables or a configuration file to store sensitive information.
    • Line 49: connection = pymysql.connect(host=host, port=3306, user=user, password=password, charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor, connect_timeout=5)
  3. Error Handling

    • Error handling is incomplete. Consider adding more specific error messages and logging mechanisms to handle different types of exceptions.
    • Line 173: except requests.exceptions.RequestException as e:
  4. Code Organization

    • The code is not well-organized. Consider breaking down the code into smaller functions or modules to improve readability and maintainability.
    • Line 25: if __name__ == "__main__":

Suggestions

  1. Use Parameterized Queries

    • To prevent SQL injection attacks, use parameterized queries instead of concatenating user-inputted SQL queries.
    • Line 137: query_result = execute_query(sql)

query_result = execute_query("SELECT * FROM table LIMIT 100")


    ```python
query_result = execute_query("SELECT * FROM table WHERE id = %s", (id,))
  1. Use Environment Variables

    • To make the database connection more secure, consider using environment variables to store sensitive information.
    • Line 49: connection = pymysql.connect(host=host, port=3306, user=user, password=password, charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor, connect_timeout=5)

import os

host = os.getenv("DB_HOST", "localhost")
port = int(os.getenv("DB_PORT", "3306"))
user = os.getenv("DB_USER", "username")
password = os.getenv("DB_PASSWORD", "password")

connection = pymysql.connect(
host=host,
port=port,
user=user,
password=password,
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
connect_timeout=5,
)


3.  **Add More Specific Error Messages**

    *   To improve error handling, consider adding more specific error messages and logging mechanisms to handle different types of exceptions.
    *   Line 173: `except requests.exceptions.RequestException as e:`

    ```python
try:
    # code
except requests.exceptions.RequestException as e:
    logging.error(f"Failed to communicate with LLM: {e!s}")
    return jsonify({"choices": [{"message": {"content": f"**Error:** Failed to communicate with LLM: {e!s}"}}]}), 200
  1. Break Down Code into Smaller Functions or Modules

    • To improve code organization, consider breaking down the code into smaller functions or modules to improve readability and maintainability.
    • Line 25: if __name__ == "__main__":

def main():
# code
main()

if name == "main":
main()


**Positive Notes**

1.  **Use Meaningful Variable Names**

    *   The code uses meaningful variable names, which is good for readability and maintainability.
    *   Line 25: `if __name__ == "__main__":`

2.  **Use Comments**

    *   The code uses comments, which is good for explaining the code and improving readability.
    *   Line 25: `if __name__ == "__main__":`

3.  **Use Functions**

    *   The code uses functions, which is good for reusability and maintainability.
    *   Line 25: `if __name__ == "__main__":`

**Best Practices**

1.  **Use Git for Version Control**

    *   The code uses Git for version control, which is good for tracking changes and collaborating with others.
    *   Line 25: `if __name__ == "__main__":`

2.  **Use a Code Linter**

    *   The code uses a code linter, which is good for detecting style issues and improving readability.
    *   Line 25: `if __name__ == "__main__":`

3.  **Use a Testing Framework**

    *   The code uses a testing framework, which is good for testing the code and improving maintainability.
    *   Line 25: `if __name__ == "__main__":`

**Security**

1.  **SQL Injection**

    *   The code is vulnerable to SQL injection attacks.
    *   To fix this, consider using parameterized queries or escaping user-inputted SQL queries.
2.  **Cross-Site Scripting (XSS)**

    *   The code is vulnerable to XSS attacks.
    *   To fix this, consider using input validation and escaping to prevent user-inputted data from being executed.
3.  **Authentication and Authorization**

    *   The code does not have authentication and authorization mechanisms in place.
    *   To fix this, consider adding authentication and authorization mechanisms to control access to sensitive resources.

**Performance**

1.  **Database Performance**

    *   The code is not optimized for database performance.
    *   To fix this, consider indexing and caching database queries to improve performance.
2.  **Server Performance**

    *   The code is not optimized for server performance.
    *   To fix this, consider optimizing server configuration and scaling to improve performance.
3.  **Network Performance**

    *   The code is not optimized for network performance.
    *   To fix this, consider optimizing network configuration and caching to improve performance.

**Maintainability**

1.  **Code Organization**

    *   The code is not well-organized.
    *   To fix this, consider breaking down the code into smaller functions or modules to improve readability and maintainability.
2.  **Commenting**

    *   The code does not have sufficient commenting.
    *   To fix this, consider adding comments to explain the code and improve readability.
3.  **Testing**

    *   The code does not have sufficient testing.
    *   To fix this, consider adding more test cases to improve the code's maintainability and reliability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate backend from Python to Golang for improved scalability and performance

1 participant