Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

Dev#5

Merged
AdithaBuwaneka merged 16 commits intomainfrom
dev
Nov 12, 2025
Merged

Dev#5
AdithaBuwaneka merged 16 commits intomainfrom
dev

Conversation

@RandithaK
Copy link
Copy Markdown
Member

@RandithaK RandithaK commented Nov 11, 2025

Summary by CodeRabbit

  • Chores

    • Added Docker ignore, Dockerfile, pinned dependencies, .env example, and CI workflows for build, packaging, and automated deploys.
  • Documentation

    • Added CI/CD & Kubernetes deployment guide, full integration guide, quick reference, setup and setup/quick-start docs.
  • Improvements

    • Production-ready startup defaults, improved resilience/logging, async user-context handling, batch document ingestion, and clearer tool invocation/status reporting.
  • Tests

    • Relaxed RAG/tool-routing tests and Windows stdout compatibility.

RandithaK and others added 4 commits November 5, 2025 17:45
…t service

- Created GitHub Actions workflows for build and deployment
- Added Dockerfile for building the Agent Bot container
- Updated requirements.txt with necessary dependencies
- Developed comprehensive Kubernetes configuration including ConfigMap and Secrets
- Documented CI/CD process and deployment steps in CICD_K8S_DEPLOYMENT.md
- Added quick reference guide for common commands and troubleshooting
- Implemented health checks and logging for the service
- Enhanced API Gateway configuration to route requests to the Agent Bot service
feat: Implement CI/CD pipeline and Kubernetes deployment for Agent Bot service
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 11, 2025

Warning

Rate limit exceeded

@AdithaBuwaneka has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 42f3530 and 3c34eff.

📒 Files selected for processing (2)
  • .github/workflows/build.yaml (1 hunks)
  • requirements.txt (1 hunks)

Walkthrough

Adds containerization and Docker context ignores, pinned Python dependencies, GitHub Actions build and deploy workflows, Kubernetes manifests and deployment docs, various docs/guides, and multiple runtime changes: agent initialization refactor to initialize_agent, StructuredTool wrapping for tools, async microservice client and user-context calls, document batch ingestion + singleton, Pinecone init robustness, typing additions, uvicorn reload toggle, and test adjustments.

Changes

Cohort / File(s) Summary
Docker & Context
​.dockerignore, Dockerfile
Adds a comprehensive .dockerignore and a production-oriented Dockerfile (python:3.11-slim, system deps, pip caching, exposes port 8091, healthcheck, uvicorn startup).
CI/CD Workflows
.github/workflows/build.yaml, .github/workflows/deploy.yaml
New GitHub Actions: build.yaml installs Python 3.11, caches pip, installs deps, optional lint/import check; deploy.yaml triggers after build, updates k8s manifests with image SHA, applies to cluster and waits for rollout.
Kubernetes & Docs
CICD_K8S_DEPLOYMENT.md, COMPLETE_INTEGRATION_GUIDE.md, IMPLEMENTATION_SUMMARY.md, QUICK_REFERENCE.md
Adds comprehensive CI/CD, integration, implementation, and quick-reference documentation describing manifests, secrets, configmaps, deployment procedure, and verification commands.
K8s Config / Secret Helpers
k8s-config/..., k8s-config/scripts/create-secrets.sh*
Adds/updates Kubernetes manifests, configmap/secret templates and secret-creation scripts (paths abbreviated).
Dependencies & Env
requirements.txt, .env.example
Adds pinned Python dependencies and an example .env with placeholders for Gemini, Pinecone, RAG params, and service URLs.
Entrypoint tweak
main.py
Changes uvicorn launcher flag from reload=True to reload=False.
Routing types
routes/chatAgent.py
Adds typing imports (List, Dict, Any) — no runtime behavior changes.
Agent construction & flow
services/agent_core.py
Replaces create_tool_calling_agent with initialize_agent (uses AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION), passes prompt via agent_kwargs, adds pre-filtering for off-topic queries, switches to async tool invocation (ainvoke), derives tool_executed from intermediate steps, and updates invoke_agent signature to accept session_id.
Tools exposure
services/agent_tools.py
Moves from decorator-based tools to StructuredTool.from_function wrappers; exposes all_tools list of StructuredTool instances; async tool bodies preserved.
Document service
services/document.py
Adds ingest_multiple_documents(...) batch ingestion, a module-level singleton _document_service_instance, and get_document_service() accessor.
Microservice client async
services/microservice_client.py
Makes get_user_context async (async def get_user_context(...)) and awaits internal async helper instead of using synchronous wrappers.
Pinecone robustness
services/vector.py
Adds init/info logs, wraps index existence checks in try/except, uses list_indexes() fallback, and nulls client/index on failure to allow graceful continuation.
Tests
test_agent_rag.py
Adjusts tests for Windows stdout encoding and relaxes/asserts agent/tool routing and RAG response match conditions.

Sequence Diagram(s)

sequenceDiagram
    participant Client as User
    participant API as FastAPI
    participant Agent as AIAgentService
    participant Docs as DocumentService
    participant Tools as StructuredTools
    participant MS as MicroserviceClient

    Client->>API: POST /chat (query, session_id, token)
    API->>Agent: invoke_agent(user_query, session_id, user_token, chat_history)

    alt RAG has no sources and query off-topic
        Agent-->>API: canned automotive-focused refusal (no tools)
    else Proceed with RAG or tools
        Agent->>Docs: async fetch RAG sources (if needed)
        Agent->>Tools: async ainvoke(...) to run StructuredTools
        Tools-->>Agent: tool results + intermediate_steps
        Agent->>MS: await get_user_context(user_token)
        Agent-->>API: composed reply, tool_executed flag, user_context
    end
Loading
sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub
    participant Build as build-test
    participant Docker as build-and-push
    participant GHCR as GHCR
    participant Deploy as deploy workflow
    participant K8s as Kubernetes

    Dev->>GH: push to main/devOps/dev or open PR
    GH->>Build: run build-test (Python 3.11, cache, deps, lint/import check)
    Build-->>GH: success
    GH->>Docker: build-and-push (on push + build success)
    Docker->>GHCR: build image, tag (sha, latest), push
    GH->>Deploy: workflow_run triggers deploy (main/devOps)
    Deploy->>K8s: update deployment image to ghcr/...:<sha> and apply
    K8s-->>Deploy: rollout complete
    Deploy-->>GH: deployment complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • services/agent_core.py — agent initialization change, prompt passing, async ainvoke, pre-filtering, and signature change (session_id).
    • services/agent_tools.py — StructuredTool wrapping and metadata alignment with agent expectations.
    • services/microservice_client.py — async signature change and all call sites that must now await.
    • services/vector.py — Pinecone initialization error-handling and index discovery fallback.
    • CI/CD deploy workflow — kubeconfig usage, external repo checkout path, and image tag substitution.

Possibly related PRs

Poem

🐇 I hopped through Dockerfiles and YAML seas,
Pushed images, secrets, and K8s keys.
I wrapped tools in structures and made agents async,
Nibbled docs and tests while pipelines blinked.
Agent Bot now hops — carrots for CI! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The pull request title 'Dev' is vague and non-descriptive, failing to convey the actual changes made in the changeset. Replace the title with a specific, descriptive summary of the main change, such as 'Add CI/CD pipelines, Docker configuration, and Kubernetes deployment' or 'Implement Agent Bot deployment automation and infrastructure setup'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%.

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (9)
QUICK_REFERENCE.md (2)

167-167: Specify language for fenced code block.

Line 167 has a code fence without a language identifier, making it less readable in rendered Markdown and harder to syntax-highlight.

Apply this diff:

- File Structure
- ```
+ File Structure
+ ```tree

192-195: Wrap bare URLs in Markdown link syntax.

Lines 193–195 contain bare URLs. For better readability and maintainability in rendered Markdown, wrap them using the [text](url) syntax.

Apply this diff:

  ## Links
- - **Repository**: https://github.com/TechTorque-2025/Agent_Bot
- - **Container Registry**: ghcr.io/techtorque-2025/agent_bot
- - **K8s Config**: https://github.com/TechTorque-2025/k8s-config
+ - **Repository**: [github.com/TechTorque-2025/Agent_Bot](https://github.com/TechTorque-2025/Agent_Bot)
+ - **Container Registry**: [ghcr.io/techtorque-2025/agent_bot](https://ghcr.io/techtorque-2025/agent_bot)
+ - **K8s Config**: [github.com/TechTorque-2025/k8s-config](https://github.com/TechTorque-2025/k8s-config)
Dockerfile (1)

29-30: Consider using a simpler health check mechanism.

The current health check (line 30) uses Python requests.get(), which adds unnecessary overhead and runtime dependencies to health checks. Since requests is already in requirements.txt, this works, but simpler alternatives exist.

Consider one of these approaches:

Option 1: Use curl (simplest)

- HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
-     CMD python -c "import requests; requests.get('http://localhost:8091/health')" || exit 1
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+     CMD curl -f http://localhost:8091/health || exit 1

Requires curl installation: add curl to the apt-get install line (line 11).

Option 2: Use a minimal shell check (if curl not available)

- HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
-     CMD python -c "import requests; requests.get('http://localhost:8091/health')" || exit 1
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+     CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8091/health'); exit(0)" 2>/dev/null || exit 1

For a production deployment, Option 1 with curl is recommended as it's more efficient and widely used in container health checks.

.github/workflows/deploy.yaml (2)

43-46: Consider using a dedicated action or pre-caching for yq installation.

Installing yq from GitHub releases on every workflow run (lines 44–46) adds ~10–15 seconds of overhead and is prone to rate limiting or network issues. For better reliability and performance:

Option 1: Use a community action (recommended)

  - name: Install yq
-   run: |
-     sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq
-     sudo chmod +x /usr/bin/yq
+   uses: chrisdickinson/setup-yq@latest
+   with:
+     yq-version: v4.35.1

Option 2: Cache the downloaded binary

  - name: Install yq
+   uses: actions/cache@v4
+   with:
+     path: /usr/local/bin/yq
+     key: yq-v4.35.1
+     restore-keys: yq-
+
  - name: Install yq (cached or download)
    run: |
      if [ ! -f /usr/local/bin/yq ]; then
        sudo wget https://github.com/mikefarah/yq/releases/v4.35.1/download/yq_linux_amd64 -O /usr/local/bin/yq
        sudo chmod +x /usr/local/bin/yq
      fi

Option 1 is simpler and more maintainable.


54-56: Add validation or error handling for YAML updates.

Line 54–56 uses yq to update the image tag inline, but if the Kubernetes manifest structure changes or doesn't exist, the update may fail silently or apply incorrect changes. Consider adding a validation step:

  - name: Update image tag in YAML
    run: |
      yq -i '(select(.kind == "Deployment") | .spec.template.spec.containers[0].image) = "ghcr.io/techtorque-2025/agent_bot:${{ steps.get_sha.outputs.sha }}"' config-repo/k8s/services/agent-bot-deployment.yaml
+     # Validate the update was applied
+     if ! grep -q "ghcr.io/techtorque-2025/agent_bot:${{ steps.get_sha.outputs.sha }}" config-repo/k8s/services/agent-bot-deployment.yaml; then
+       echo "ERROR: Image tag update failed or did not apply correctly"
+       exit 1
+     fi

This ensures the deployment manifest is correctly updated before applying it to the cluster.

CICD_K8S_DEPLOYMENT.md (1)

123-123: Specify language for fenced code block.

Line 123 has an empty code fence. Add a language identifier for better syntax highlighting:

- The Agent_Bot service is accessible through the API Gateway at:
- ```
+ The Agent_Bot service is accessible through the API Gateway at:
+ ```text
IMPLEMENTATION_SUMMARY.md (1)

114-114: Specify language for fenced code blocks.

Lines 114, 225, and 237 have code fences without language identifiers. These appear to be plain text or ASCII diagrams, so use text or diagram:

  ## 🔄 CI/CD Flow
-
- ```
+
+ ```text

and

  ### Agent_Bot Repository
- ```
+ ```text

and

  ### k8s-config Repository
- ```
+ ```text

Also applies to: 225-225, 237-237

COMPLETE_INTEGRATION_GUIDE.md (2)

88-88: Format URLs as Markdown links instead of bare URLs.

Markdownlint requires URLs to be wrapped in angle brackets or link syntax for consistency and accessibility.

-1. Visit https://makersuite.google.com/app/apikey
+1. Visit <https://makersuite.google.com/app/apikey>
 2. Create a new API key
 3. Save the key securely
 
 #### Pinecone
-1. Visit https://app.pinecone.io/
+1. Visit <https://app.pinecone.io/>
 2. Create account if needed

Also applies to: 93-93


10-10: Add language specification to fenced code blocks.

Three code blocks (directory structures) lack language identifiers. Use txt, tree, or similar to comply with Markdown linting standards.

-```
+```txt
 Agent_Bot/
 ├── .github/workflows/
 │   ├── build.yaml          ✅ NEW - Build & push Docker image

Apply the same fix to lines 24–35 and 38–41.

Also applies to: 24-24, 38-38

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c2b78a and 959bd56.

📒 Files selected for processing (9)
  • .dockerignore (1 hunks)
  • .github/workflows/build.yaml (1 hunks)
  • .github/workflows/deploy.yaml (1 hunks)
  • CICD_K8S_DEPLOYMENT.md (1 hunks)
  • COMPLETE_INTEGRATION_GUIDE.md (1 hunks)
  • Dockerfile (1 hunks)
  • IMPLEMENTATION_SUMMARY.md (1 hunks)
  • QUICK_REFERENCE.md (1 hunks)
  • requirements.txt (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.29.0)
COMPLETE_INTEGRATION_GUIDE.md

[high] 369-371: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🪛 LanguageTool
CICD_K8S_DEPLOYMENT.md

[uncategorized] ~22-~22: The official name of this software platform is spelled with a capital “H”.
Context: ...microservices: #### 1. Build Workflow (.github/workflows/build.yaml) Triggers: -...

(GITHUB)


[uncategorized] ~44-~44: The official name of this software platform is spelled with a capital “H”.
Context: ...t_bot:latest #### 2. Deploy Workflow (.github/workflows/deploy.yaml`) Triggers: ...

(GITHUB)


[grammar] ~108-~108: Ensure spelling is correct
Context: ...e limits:** - Memory: 512Mi (request) / 1Gi (limit) - CPU: 250m (request) / 500m (l...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

IMPLEMENTATION_SUMMARY.md

[uncategorized] ~9-~9: The official name of this software platform is spelled with a capital “H”.
Context: ...ices pattern: #### Build Workflow (.github/workflows/build.yaml) - ✅ Runs on push...

(GITHUB)


[uncategorized] ~21-~21: The official name of this software platform is spelled with a capital “H”.
Context: ...5/agent_bot #### **Deploy Workflow** (.github/workflows/deploy.yaml`) - ✅ Triggers af...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
COMPLETE_INTEGRATION_GUIDE.md

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

(MD040, fenced-code-language)


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

(MD040, fenced-code-language)


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

(MD040, fenced-code-language)


88-88: Bare URL used

(MD034, no-bare-urls)


93-93: Bare URL used

(MD034, no-bare-urls)

CICD_K8S_DEPLOYMENT.md

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

(MD040, fenced-code-language)

QUICK_REFERENCE.md

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

(MD040, fenced-code-language)


193-193: Bare URL used

(MD034, no-bare-urls)


195-195: Bare URL used

(MD034, no-bare-urls)

IMPLEMENTATION_SUMMARY.md

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

(MD040, fenced-code-language)


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

(MD040, fenced-code-language)


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

(MD040, fenced-code-language)

🪛 OSV Scanner (2.2.4)
requirements.txt

[HIGH] 1-1: fastapi 0.109.0: undefined

(PYSEC-2024-38)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-115)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-118)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-43)


[CRITICAL] 11-11: langchain 0.1.6: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 11-11: langchain 0.1.6: Langchain SQL Injection vulnerability

(GHSA-45pg-36p6-83v9)


[CRITICAL] 1-1: langchain-community 0.0.20: undefined

(PYSEC-2025-70)


[CRITICAL] 1-1: langchain-community 0.0.20: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 1-1: langchain-community 0.0.20: LangChain pickle deserialization of untrusted data

(GHSA-f2jm-rw3h-6phg)


[CRITICAL] 1-1: langchain-community 0.0.20: LangChain Community SSRF vulnerability exists in RequestsToolkit component

(GHSA-h5gc-rm8j-5gpr)


[CRITICAL] 1-1: langchain-community 0.0.20: Langchain Community Vulnerable to XML External Entity (XXE) Attacks

(GHSA-pc6w-59fv-rh23)


[CRITICAL] 1-1: langchain-community 0.0.20: Server-Side Request Forgery in langchain-community.retrievers.web_research.WebResearchRetriever

(GHSA-q25c-c977-4cmh)


[HIGH] 25-25: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 25-25: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 1-1: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms

(GHSA-2c2j-9gv5-cj73)


[HIGH] 1-1: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data

(GHSA-f96h-pmfr-66vw)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install Dependencies and Test
  • GitHub Check: Install Dependencies and Test
🔇 Additional comments (12)
Dockerfile (1)

1-33: LGTM on overall structure.

The Dockerfile follows best practices: multi-layer caching (requirements.txt before code), proper use of --no-cache-dir for pip, clean cleanup of apt lists, and appropriate port exposure. The base image python:3.11-slim is a good choice for a FastAPI service.

.dockerignore (1)

1-68: LGTM. Comprehensive and well-organized ignore patterns.

The .dockerignore file appropriately excludes build artifacts, virtual environments, IDE files, testing artifacts, environment files, Git metadata, documentation, CI/CD workflows, test files, OS artifacts, logs, and temp files. This keeps the Docker context lean and prevents secrets/unnecessary files from being copied into images.

Notably, excluding .github/ (line 51) and *.md files (line 45) is correct for a runtime container that doesn't need CI/CD metadata or documentation.

.github/workflows/build.yaml (2)

49-56: Optional linting is good for CI maturity.

The flake8 linting step (lines 49–56) with continue-on-error: true is a pragmatic approach for a new service. It catches syntax errors and common issues early without blocking the build. As the codebase matures, consider promoting lint failures to hard errors.


75-100: Docker tagging and GHCR push strategy is sound.

Uses docker/metadata-action for intelligent tagging (commit SHA + latest on default branch), GHCR login with auto-generated GITHUB_TOKEN scoped to packages:write, and docker/build-push-action for the build. The dependency chain (needs: build-test) ensures tests pass before pushing images.

.github/workflows/deploy.yaml (2)

9-11: Note: Dev branch builds but does not auto-deploy.

The deploy workflow only triggers on main and devOps branches (lines 9–11), while the build workflow triggers on main, devOps, and dev (build.yaml lines 5–8). This means commits to the dev branch will build and push Docker images but won't auto-deploy to Kubernetes.

If this is intentional (requiring manual approval before dev deployments), document it clearly. If dev should auto-deploy, add dev to line 11.


1-69: Overall workflow structure is sound.

The workflow_run trigger properly chains the deploy after a successful build, branch filtering is intentional, and the deployment steps correctly fetch the k8s-config repo, update manifests, and apply them with rollout monitoring. The job will fail if any step errors, preventing partial deployments.

CICD_K8S_DEPLOYMENT.md (1)

1-288: Comprehensive and well-structured deployment documentation.

The guide clearly explains the CI/CD pipeline, Kubernetes configuration, deployment process, verification steps, troubleshooting, and security considerations. It accurately reflects the workflows and infrastructure introduced in this PR and provides actionable guidance for operators. The comparison to Java microservices is helpful context for teams unfamiliar with Python deployments.

IMPLEMENTATION_SUMMARY.md (1)

1-305: Excellent implementation summary that ties together all changes.

Provides a clear overview of completed tasks, compares the Python/FastAPI approach to existing Java services, shows the CI/CD flow visually, outlines security measures, and gives operators actionable next steps. The verification checklist and file inventory make it easy for teams to validate the deployment is complete. Well-organized and comprehensive.

COMPLETE_INTEGRATION_GUIDE.md (4)

162-164: Clarify the git branch name.

Line 162 references git push origin devOps, but the PR source branch is dev. Confirm whether the target branch should be dev or if devOps is intentional.

-git push origin devOps
+git push origin dev

49-52: Clarify the port number change and API Gateway routing.

Line 51 changes the target URL from 8089 to 8091, but no explanation is provided for why this port differs from the standard FastAPI default (8000) or what service previously used 8089. Document this decision clearly so maintainers understand the routing logic.

Add a clarifying comment like:

- name: "ai"
  path_prefix: "/api/v1/ai/"
  target_url: "http://localhost:8091"  # Agent Bot service port
  strip_prefix: "/api/v1/ai"
  auth_required: true
  env_var: "AGENT_BOT_SERVICE_URL"

74-81: Verify configuration values are production-ready.

The document specifies hardcoded model and index names:

  • GEMINI_MODEL: "gemini-2.5-flash" — is this version available and stable?
  • PINECONE_INDEX_NAME: "techtorque-kb" — clarify if this name is standardized across all environments
  • PINECONE_ENVIRONMENT: "us-east-1-aws" — confirm this is the shared environment for the team

Consider whether these should be configurable per environment (dev/staging/prod).


1-575: Clarify scope: Agent_Bot files present, but k8s-config files belong to separate repository.

Agent_Bot repository files are all present and accounted for. However, the integration guide references k8s-config files (agent-bot-configmap.yaml, agent-bot-deployment.yaml, agent-bot-secrets.template.yaml, gateway-deployment.yaml, create-all-secrets.sh) that do not exist in this PR. These belong to a separate k8s-config repository.

Recommendation:

  1. If k8s-config changes are part of this deployment effort, create a separate PR for the k8s-config repository with those files.
  2. Update the integration guide to clarify that it coordinates changes across two separate repositories and PRs (Agent_Bot + k8s-config), with instructions for merging both PRs in sequence.
  3. If k8s-config changes have already been merged separately, update the guide to reference them as already deployed rather than pending.

Comment on lines +369 to +371
curl https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent \
-H "Content-Type: application/json" \
-H "x-goog-api-key: YOUR_API_KEY" \
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 | 🟠 Major

⚠️ Security: Remove or mask API key from example code.

The curl example exposes the actual API key syntax in documentation. Users who copy-paste this will leak credentials. Either remove the example or use a placeholder.

-curl https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent \
-  -H "Content-Type: application/json" \
-  -H "x-goog-api-key: YOUR_API_KEY" \
-  -d '{"contents":[{"parts":[{"text":"Hello"}]}]}'
+curl https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent \
+  -H "Content-Type: application/json" \
+  -H "x-goog-api-key: <YOUR_API_KEY_HERE>" \
+  -d '{"contents":[{"parts":[{"text":"Hello"}]}]}'
+
+# ⚠️  Replace <YOUR_API_KEY_HERE> with your actual key

This was flagged by Gitleaks as a security concern.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Gitleaks (8.29.0)

[high] 369-371: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🤖 Prompt for AI Agents
In COMPLETE_INTEGRATION_GUIDE.md around lines 369 to 371, the curl example
exposes an API key placeholder that may encourage leaking credentials; replace
the actual header content with a neutral placeholder or mask (e.g.,
"x-goog-api-key: <YOUR_API_KEY>") or remove the header entirely and add a short
note instructing readers to securely provision keys via environment variables or
a secrets manager before running curl. Ensure the example no longer contains
copy-pasteable secrets and add a one-line warning about not committing keys to
source control.

requirements.txt Outdated
Comment on lines +1 to +25
# Core FastAPI and Web Framework
fastapi==0.109.0
uvicorn[standard]==0.27.0
pydantic==2.5.3
python-dotenv==1.0.0

# HTTP Client
httpx==0.26.0
requests==2.31.0

# LangChain and AI/ML
langchain==0.1.6
langchain-core==0.1.23
langchain-google-genai==0.0.9
google-generativeai==0.3.2

# Vector Database
pinecone-client==3.0.0

# Embeddings
sentence-transformers==2.3.1
numpy==1.24.3

# Logging and utilities
python-multipart==0.0.6
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

🧩 Analysis chain

CRITICAL: Multiple high-severity security vulnerabilities in pinned dependencies.

OSV Scanner identified several critical vulnerabilities in the locked versions:

  • langchain 0.1.6 (line 12): Multiple CRITICAL vulnerabilities

  • python-multipart 0.0.6 (line 25): HIGH severity vulnerabilities

  • fastapi 0.109.0 (line 2): HIGH severity

    • PYSEC-2024-38
  • starlette 0.35.1 (transitive): HIGH severity DoS via multipart

These versions are significantly outdated and expose the service to known exploits. This should be resolved before production deployment.

Please upgrade to the latest stable versions of these libraries. For example:

  • langchain==0.1.x → latest 0.2.x or 1.x
  • python-multipart==0.0.6 → latest stable (currently 0.0.8+)
  • fastapi==0.109.0 → latest stable (currently 0.110.0+)

Run the following command to check for available updates:


🏁 Script executed:

#!/bin/bash
# Check for outdated packages and available upgrades
pip list --outdated | grep -E "langchain|fastapi|uvicorn|python-multipart|starlette"
# Or use pip-audit for security scanning
pip install pip-audit
pip-audit --desc

Length of output: 4604


🌐 Web query:

langchain 0.1.6 security vulnerabilities CVE GHSA

💡 Result:

Short answer: Yes — LangChain v0.1.6 (and related LangChain integration packages) is affected by known security issues (notably SSRF and unsafe deserialization). You should upgrade. Sources:

  • Snyk: RequestsToolkit / Web Research Retriever SSRF affecting versions < 0.1.12 (so 0.1.6 is vulnerable). Recommendation: upgrade to >= 0.1.12 / >= 0.2.10 as noted. [1]

  • OSV / NVD (CVE-2024-5998, GHSA-f2jm-rw3h-6phg): FAISS.deserializefrombytes pickle deserialization issue — affects langchain-ai21 versions including 0.1.6 (fixed in subsequent commit). [2]

  • Product vulnerability index / CVE listings (aggregated LangChain CVEs) — shows multiple high/critical CVEs recorded against the project (review individual CVE pages for details & fixed versions). [3]

Recommended action: upgrade to the fixed LangChain release(s) referenced in each advisory (or to the latest stable LangChain), and review your use of toolkits that perform HTTP requests or deserialize untrusted data.

Sources:
[1] Snyk — langchain@0.1.6 vulnerabilities (SSRF).
[2] OSV / NVD — CVE-2024-5998 (GHSA-f2jm-rw3h-6phg) affecting langchain-ai21 0.1.6.
[3] CVE/product aggregate listing for LangChain (vulnerability index).


🌐 Web query:

python-multipart 0.0.6 ReDoS vulnerability GHSA-2jv5-9r88-3w3p

💡 Result:

Short summary

  • ID: GHSA-2jv5-9r88-3w3p (CVE-2024-24762). [1]
  • Affected: python-multipart versions ≤ 0.0.6. [2]
  • Issue: Regular-expression Denial of Service (ReDoS) in parsing the HTTP Content-Type header options — a specially crafted header can cause excessive CPU usage and stall the event loop. [1][3]
  • Fixed: Upgrade to python-multipart >= 0.0.7. [2][3]

Recommended action

  • Immediately upgrade any project or dependency that uses python-multipart to >= 0.0.7. If you can't upgrade immediately, block/untrusted requests that include multipart form parsing or validate/sanitize Content-Type headers at your edge (WAF/reverse proxy). [2][3]

Sources
[1] OSV / CVE-2024-24762 summary.
[2] GitLab advisory / python-multipart (affected versions and fix).
[3] Vendor/advisory summaries discussing impact and mitigation.


🌐 Web query:

fastapi 0.109.0 security vulnerability PYSEC-2024-38

💡 Result:

Short summary — FastAPI PYSEC-2024-38 (CVE-2024-24762)

  • What it is: a Regular‑Expression DoS (ReDoS) in python-multipart used by FastAPI when parsing Content-Type form-data options; an attacker can send a crafted Content-Type that consumes CPU and stalls the event loop. Severity: High (CVSS 7.5). [1][2]

  • Affected versions: fastapi <= 0.109.0 (transitive: python-multipart < 0.0.7). [2][3]

  • Fixed in: fastapi 0.109.1 (which raises python-multipart minimum to >=0.0.7). Upgrade recommended. [1][2]

  • Mitigation: upgrade FastAPI to >= 0.109.1 (or ensure python-multipart >= 0.0.7); if you cannot upgrade immediately, avoid parsing untrusted form data or front the app with rate‑limiting / request size/time limits. [1][4]

Sources:
[1] OSV entry for PYSEC-2024-38 / CVE-2024-24762.
[2] GitLab advisory / FastAPI advisory (notes affected versions and fix).
[3] CVE summary (CVE-2024-24762) / vulnerability databases.
[4] FastAPI release/commit addressing the fix.


🌐 Web query:

langchain latest version 2024

💡 Result:

The latest LangChain release in 2024 was LangChain v0.3, published on September 16, 2024. [1][2]

Sources:

  • LangChain v0.3 release announcement (GitHub discussion). [1]
  • LangChain v0.2 / migration notes (context on 2024 releases). [2]

🏁 Script executed:

# Check if there's any documentation about version pinning strategy
fd -e md -e rst -e txt . --type f | xargs grep -l "requirement\|version\|pin\|lock" 2>/dev/null | head -5

# Look for any CI/deployment configs that might explain version choices
fd -e yml -e yaml -e toml . --type f | head -10

Length of output: 107


🏁 Script executed:

# Check commit history or comments in requirements.txt for context
cat requirements.txt 2>/dev/null || echo "File not found"

Length of output: 426


CRITICAL: High-severity security vulnerabilities in pinned dependencies require immediate upgrade.

Web verification confirms the following vulnerabilities in requirements.txt:

  • python-multipart 0.0.6 (line 25): ReDoS vulnerability (GHSA-2jv5-9r88-3w3p / CVE-2024-24762) in HTTP Content-Type parsing; affected versions ≤ 0.0.6 are fixed in >= 0.0.7.

  • fastapi 0.109.0 (line 2): ReDoS vulnerability (PYSEC-2024-38 / CVE-2024-24762) via transitive python-multipart dependency; fixed in 0.109.1.

  • langchain 0.1.6 (line 12): Contains known vulnerabilities (SSRF and unsafe deserialization). The latest stable version is LangChain v0.3 (September 2024), making 0.1.6 significantly outdated.

Recommended upgrades:

  • python-multipart==0.0.6python-multipart>=0.0.7
  • fastapi==0.109.0fastapi>=0.109.1
  • langchain==0.1.6langchain>=0.2.0 or latest 0.3.x

These are actively exploitable vulnerabilities affecting multipart form parsing. The python-multipart and fastapi issues must be resolved before production deployment.

🧰 Tools
🪛 OSV Scanner (2.2.4)

[HIGH] 1-1: fastapi 0.109.0: undefined

(PYSEC-2024-38)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-115)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-118)


[CRITICAL] 11-11: langchain 0.1.6: undefined

(PYSEC-2024-43)


[CRITICAL] 11-11: langchain 0.1.6: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 11-11: langchain 0.1.6: Langchain SQL Injection vulnerability

(GHSA-45pg-36p6-83v9)


[CRITICAL] 1-1: langchain-community 0.0.20: undefined

(PYSEC-2025-70)


[CRITICAL] 1-1: langchain-community 0.0.20: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 1-1: langchain-community 0.0.20: LangChain pickle deserialization of untrusted data

(GHSA-f2jm-rw3h-6phg)


[CRITICAL] 1-1: langchain-community 0.0.20: LangChain Community SSRF vulnerability exists in RequestsToolkit component

(GHSA-h5gc-rm8j-5gpr)


[CRITICAL] 1-1: langchain-community 0.0.20: Langchain Community Vulnerable to XML External Entity (XXE) Attacks

(GHSA-pc6w-59fv-rh23)


[CRITICAL] 1-1: langchain-community 0.0.20: Server-Side Request Forgery in langchain-community.retrievers.web_research.WebResearchRetriever

(GHSA-q25c-c977-4cmh)


[HIGH] 25-25: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 25-25: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 1-1: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms

(GHSA-2c2j-9gv5-cj73)


[HIGH] 1-1: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data

(GHSA-f96h-pmfr-66vw)

🤖 Prompt for AI Agents
In requirements.txt lines 1-25, several pinned dependencies are insecure:
python-multipart==0.0.6 (ReDoS, fixed >=0.0.7), fastapi==0.109.0 (transitive
ReDoS via python-multipart, fixed >=0.109.1), and langchain==0.1.6 (multiple
vulnerabilities/very outdated). Update the pins accordingly: bump
python-multipart to >=0.0.7, bump fastapi to >=0.109.1, and upgrade langchain to
at least 0.2.0 (preferably the latest 0.3.x); then run dependency resolution
(pip-compile/pip install -U or poetry update), run tests, and regenerate
lockfile to ensure transitive fixes are applied before deploying.

RandithaK and others added 3 commits November 12, 2025 03:40
- Adapt agent_core for LangChain 0.1.6 (STRUCTURED_CHAT agent)
- Add missing imports and singleton functions
- Make Pinecone initialization resilient
- Create requirements.txt and .env configuration
- Service now running successfully on port 8091
fix: Resolve all startup errors and launch Agent Bot service
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 959bd56 and 8d17020.

📒 Files selected for processing (8)
  • .env.example (1 hunks)
  • SETUP_GUIDE.md (1 hunks)
  • main.py (1 hunks)
  • requirements.txt (1 hunks)
  • routes/chatAgent.py (1 hunks)
  • services/agent_core.py (2 hunks)
  • services/document.py (1 hunks)
  • services/vector.py (1 hunks)
🧰 Additional context used
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 8-8: [UnorderedKey] The PINECONE_DIMENSION key should go before the PINECONE_ENVIRONMENT key

(UnorderedKey)


[warning] 15-15: [UnorderedKey] The RAG_CHUNK_OVERLAP key should go before the RAG_CHUNK_SIZE key

(UnorderedKey)


[warning] 16-16: [UnorderedKey] The MAX_CONTEXT_LENGTH key should go before the RAG_CHUNK_OVERLAP key

(UnorderedKey)


[warning] 20-20: [UnorderedKey] The AUTHENTICATION_SERVICE_URL key should go before the BASE_SERVICE_URL key

(UnorderedKey)


[warning] 22-22: [UnorderedKey] The PROJECT_SERVICE_URL key should go before the VEHICLE_SERVICE_URL key

(UnorderedKey)


[warning] 23-23: [UnorderedKey] The TIME_LOGGING_SERVICE_URL key should go before the VEHICLE_SERVICE_URL key

(UnorderedKey)


[warning] 24-24: [UnorderedKey] The APPOINTMENT_SERVICE_URL key should go before the AUTHENTICATION_SERVICE_URL key

(UnorderedKey)

🪛 GitHub Actions: Build and Package Agent Bot Service
requirements.txt

[error] 3-3: Invalid requirement: 'fastapi==0.109.0fastapi==0.109.0': Expected end or semicolon (after version specifier) fastapi==0.109.0fastapi==0.109.0 ~~~~~~~~~^ (from line 3 of requirements.txt)


[error] 1-1: Dependency installation failed due to invalid entry in requirements.txt.

🪛 markdownlint-cli2 (0.18.1)
SETUP_GUIDE.md

63-63: Bare URL used

(MD034, no-bare-urls)


64-64: Bare URL used

(MD034, no-bare-urls)


65-65: Bare URL used

(MD034, no-bare-urls)


66-66: Bare URL used

(MD034, no-bare-urls)


71-71: Bare URL used

(MD034, no-bare-urls)


76-76: Bare URL used

(MD034, no-bare-urls)

🪛 OSV Scanner (2.2.4)
requirements.txt

[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: undefined

(PYSEC-2021-100)


[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: undefined

(PYSEC-2024-38)


[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: Cross-Site Request Forgery (CSRF) in FastAPI

(GHSA-8h2j-cgx8-6xv7)


[CRITICAL] 15-15: httpx 0.26.0httpx==0.26.0: undefined

(PYSEC-2022-183)


[CRITICAL] 15-15: httpx 0.26.0httpx==0.26.0: Improper Input Validation in httpx

(GHSA-h8pj-cxx2-jfg2)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-109)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-110)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-138)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-145)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-146)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-147)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-151)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-162)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-18)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-205)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-91)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-92)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-98)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-115)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-118)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-43)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain arbitrary code execution vulnerability

(GHSA-2qmj-7962-cjq8)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain SQL Injection vulnerability

(GHSA-45pg-36p6-83v9)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to arbitrary code execution

(GHSA-57fc-8q82-gfp3)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain Server Side Request Forgery vulnerability

(GHSA-655w-fm8m-m478)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain vulnerable to arbitrary code execution

(GHSA-6643-h7h5-x9wh)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain Server-Side Request Forgery vulnerability

(GHSA-6h8p-4hx9-w66c)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to arbitrary code execution

(GHSA-7gfq-f96f-g85j)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain SQL Injection vulnerability

(GHSA-7q94-qpjr-xpgm)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain SQL Injection vulnerability

(GHSA-8h5w-f6q9-wg35)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-92j5-3459-qgp4)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain vulnerable to arbitrary code execution via the evaluate function in the numexpr library

(GHSA-f73w-4m7g-ch9x)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-fj32-q626-pjjc)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to code injection

(GHSA-fprp-p869-w6q2)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain Code Injection vulnerability

(GHSA-gwqq-6vq7-5j86)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain directory traversal vulnerability

(GHSA-h59x-p739-982c)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain Server-Side Request Forgery vulnerability

(GHSA-h9j7-5xvc-qhg5)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-prgp-w7vf-ch62)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to path traversal

(GHSA-rgp8-pm28-3759)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain OS Command Injection vulnerability

(GHSA-x32c-59v5-h7fg)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2017-1)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2018-33)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2018-34)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2019-108)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2021-856)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2021-857)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy arbitrary file write via symlink attack

(GHSA-2fc2-6r4j-p65h)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: NumPy NULL Pointer Dereference

(GHSA-5545-2q6w-2gh6)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy Deserialization of Untrusted Data

(GHSA-9fq2-x9r6-wfmf)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Arbitrary file write in NumPy

(GHSA-cw6w-4rcx-xphc)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Buffer Copy without Checking Size of Input in NumPy

(GHSA-f7c7-j99h-c22f)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Incorrect Comparison in NumPy

(GHSA-fpfv-jqm9-f5jm)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy missing input validation

(GHSA-frgw-fgh6-9g52)


[HIGH] 49-49: python-multipart 0.0.6python-multipart==0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 49-49: python-multipart 0.0.6python-multipart==0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2014-13)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2014-14)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2018-28)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Exposure of Sensitive Information to an Unauthorized Actor in Requests

(GHSA-652x-xj99-gmcc)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Requests vulnerable to .netrc credentials leak via malicious URLs

(GHSA-9hjg-9r4m-mvj7)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Requests Session object does not verify requests after making first request with verify=False

(GHSA-9wx4-h78v-vm56)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Exposure of Sensitive Information to an Unauthorized Actor in Requests

(GHSA-cfj3-7x9c-4p3h)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Insufficiently Protected Credentials in Requests

(GHSA-x84v-xcm2-53pg)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: undefined

(PYSEC-2020-150)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: undefined

(PYSEC-2020-151)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: Log injection in uvicorn

(GHSA-33c7-2mpw-hg34)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: HTTP response splitting in uvicorn

(GHSA-f97h-2pfx-f59f)

🪛 Ruff (0.14.4)
services/vector.py

41-41: Do not catch blind exception: Exception

(BLE001)

main.py

55-55: Possible binding to all interfaces

(S104)

🔇 Additional comments (8)
main.py (1)

54-55: LGTM! Production-ready uvicorn configuration.

Setting reload=False is appropriate for production deployments and containerized environments. This prevents file-watching overhead and potential issues in container runtimes.

Note: The static analysis warning about binding to 0.0.0.0 (S104) is a false positive in this context—binding to all interfaces is standard and necessary for containerized applications that need to accept external traffic.

routes/chatAgent.py (1)

9-9: LGTM! Type hint enhancement.

Adding typing imports improves code maintainability and enables better static analysis. The imports are used appropriately in the route signatures (e.g., line 76).

services/document.py (1)

217-226: Singleton pattern implemented consistently.

The singleton getter follows the same pattern used in other services. For single-worker deployments (the default FastAPI/uvicorn configuration), this implementation is sufficient.

Note: If you plan to run with multiple workers (--workers > 1), each worker process will create its own instance. This is typically acceptable for stateless services, but be aware that the "singleton" is per-process, not global across workers.

services/agent_core.py (1)

51-63: Using deprecated initialize_agent API.

The code correctly acknowledges that initialize_agent is deprecated (comment on line 52). While this approach works for LangChain 0.1.6 compatibility, be aware that:

  1. initialize_agent was deprecated even in LangChain 0.1.x
  2. The pinned LangChain version (0.1.6) has multiple CRITICAL security vulnerabilities
  3. Modern LangChain (0.2+/0.3+) uses create_react_agent or the newer agent constructors

This is acceptable as an interim solution for the current deployment, but should be prioritized for upgrade alongside the LangChain version bump to address the security vulnerabilities.

Do you want me to generate a modernized implementation using current LangChain APIs as a reference for the future upgrade?

services/vector.py (2)

38-46: Improved resilience for Pinecone initialization.

The added try/except block around _ensure_index_exists() provides graceful degradation when the vector store is unavailable (network issues, invalid credentials, etc.). Setting self.pc and self.index to None ensures that is_available() correctly reports the service status, preventing cascading failures.

Note: The static analysis warning about catching bare Exception (line 41) is acceptable in this initialization context where you want to handle any failure mode and degrade gracefully.


35-35: Good observability addition.

The initialization logging helps troubleshoot connection and configuration issues in production environments.

.env.example (1)

1-27: Well-structured environment template.

The .env.example file provides a clear template with logical grouping of related configuration. The placeholder values and comments make it easy for developers to configure the service.

Note: The static analysis warnings about key ordering can be safely ignored—the current grouping (API keys → model config → RAG settings → service URLs → server config) prioritizes readability and logical organization over alphabetical ordering.

SETUP_GUIDE.md (1)

1-136: Comprehensive setup documentation.

The guide clearly documents the current state, fixes applied, and next steps for deployment. It appropriately acknowledges the LangChain version constraints and deprecated API usage, setting clear expectations for future technical debt.

Note: The markdownlint warnings about bare URLs (lines 63-66, 71, 76) are low-priority style issues. If desired, wrap URLs in angle brackets (e.g., <http://localhost:8091>) to satisfy the linter, but this doesn't affect functionality.

requirements.txt Outdated
Comment on lines +1 to +50
# Core FastAPI and Web Framework# Core FastAPI and Web Framework

fastapi==0.109.0fastapi==0.109.0

uvicorn[standard]==0.27.0uvicorn[standard]==0.27.0

pydantic==2.5.3pydantic==2.5.3

python-dotenv==1.0.0python-dotenv==1.0.0



# HTTP Client# HTTP Client

httpx==0.26.0httpx==0.26.0

requests==2.31.0requests==2.31.0



# LangChain and AI/ML - Version 0.1.6 for AgentExecutor compatibility# LangChain and AI/ML

langchain==0.1.6langchain==0.1.6

langchain-core==0.1.23langchain-core==0.1.23

langchain-google-genai==0.0.9langchain-google-genai==0.0.9

google-generativeai==0.3.2google-generativeai==0.3.2



# Vector Database# Vector Database

pinecone-client==3.0.0pinecone-client==3.0.0



# Embeddings# Embeddings

sentence-transformers==2.3.1sentence-transformers==2.3.1

numpy==1.24.3numpy==1.24.3



# Logging and utilities# Logging and utilities

python-multipart==0.0.6python-multipart==0.0.6

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: Build failure due to duplicated package names.

The requirements.txt file has a syntax error where each package name is duplicated (e.g., fastapi==0.109.0fastapi==0.109.0 on line 3). This causes the build pipeline to fail with:

Invalid requirement: 'fastapi==0.109.0fastapi==0.109.0': Expected end or semicolon

Immediate fix required:

Apply this pattern to fix all entries:

-fastapi==0.109.0fastapi==0.109.0
+fastapi==0.109.0

-uvicorn[standard]==0.27.0uvicorn[standard]==0.27.0
+uvicorn[standard]==0.27.0

-pydantic==2.5.3pydantic==2.5.3
+pydantic==2.5.3

(Apply to all lines: 3, 5, 7, 9, 15, 17, 23, 25, 27, 29, 35, 41, 43, 49)

Additionally, as noted in the previous review, these pinned versions contain CRITICAL security vulnerabilities. After fixing the syntax, you must also upgrade:

  • python-multipart==0.0.6>=0.0.7 (CVE-2024-24762)
  • fastapi==0.109.0>=0.109.1 (CVE-2024-24762)
  • langchain==0.1.6>=0.2.0 or latest 0.3.x (multiple CVEs)

Without these fixes, the service cannot be built or deployed securely.

🧰 Tools
🪛 GitHub Actions: Build and Package Agent Bot Service

[error] 3-3: Invalid requirement: 'fastapi==0.109.0fastapi==0.109.0': Expected end or semicolon (after version specifier) fastapi==0.109.0fastapi==0.109.0 ~~~~~~~~~^ (from line 3 of requirements.txt)


[error] 1-1: Dependency installation failed due to invalid entry in requirements.txt.

🪛 OSV Scanner (2.2.4)

[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: undefined

(PYSEC-2021-100)


[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: undefined

(PYSEC-2024-38)


[HIGH] 1-1: fastapi 0.109.0fastapi==0.109.0: Cross-Site Request Forgery (CSRF) in FastAPI

(GHSA-8h2j-cgx8-6xv7)


[CRITICAL] 15-15: httpx 0.26.0httpx==0.26.0: undefined

(PYSEC-2022-183)


[CRITICAL] 15-15: httpx 0.26.0httpx==0.26.0: Improper Input Validation in httpx

(GHSA-h8pj-cxx2-jfg2)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-109)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-110)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-138)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-145)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-146)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-147)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-151)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-162)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-18)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-205)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-91)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-92)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2023-98)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-115)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-118)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: undefined

(PYSEC-2024-43)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain arbitrary code execution vulnerability

(GHSA-2qmj-7962-cjq8)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain SQL Injection vulnerability

(GHSA-45pg-36p6-83v9)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to arbitrary code execution

(GHSA-57fc-8q82-gfp3)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain Server Side Request Forgery vulnerability

(GHSA-655w-fm8m-m478)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain vulnerable to arbitrary code execution

(GHSA-6643-h7h5-x9wh)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain Server-Side Request Forgery vulnerability

(GHSA-6h8p-4hx9-w66c)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to arbitrary code execution

(GHSA-7gfq-f96f-g85j)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain SQL Injection vulnerability

(GHSA-7q94-qpjr-xpgm)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain SQL Injection vulnerability

(GHSA-8h5w-f6q9-wg35)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-92j5-3459-qgp4)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain vulnerable to arbitrary code execution via the evaluate function in the numexpr library

(GHSA-f73w-4m7g-ch9x)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-fj32-q626-pjjc)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to code injection

(GHSA-fprp-p869-w6q2)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain Code Injection vulnerability

(GHSA-gwqq-6vq7-5j86)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain directory traversal vulnerability

(GHSA-h59x-p739-982c)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain Server-Side Request Forgery vulnerability

(GHSA-h9j7-5xvc-qhg5)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: LangChain vulnerable to arbitrary code execution

(GHSA-prgp-w7vf-ch62)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: langchain vulnerable to path traversal

(GHSA-rgp8-pm28-3759)


[CRITICAL] 21-21: langchain 0.1.6langchain==0.1.6: Langchain OS Command Injection vulnerability

(GHSA-x32c-59v5-h7fg)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2017-1)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2018-33)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2018-34)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2019-108)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2021-856)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: undefined

(PYSEC-2021-857)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy arbitrary file write via symlink attack

(GHSA-2fc2-6r4j-p65h)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: NumPy NULL Pointer Dereference

(GHSA-5545-2q6w-2gh6)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy Deserialization of Untrusted Data

(GHSA-9fq2-x9r6-wfmf)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Arbitrary file write in NumPy

(GHSA-cw6w-4rcx-xphc)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Buffer Copy without Checking Size of Input in NumPy

(GHSA-f7c7-j99h-c22f)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Incorrect Comparison in NumPy

(GHSA-fpfv-jqm9-f5jm)


[CRITICAL] 43-43: numpy 1.24.3numpy==1.24.3: Numpy missing input validation

(GHSA-frgw-fgh6-9g52)


[HIGH] 49-49: python-multipart 0.0.6python-multipart==0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 49-49: python-multipart 0.0.6python-multipart==0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2014-13)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2014-14)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: undefined

(PYSEC-2018-28)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Exposure of Sensitive Information to an Unauthorized Actor in Requests

(GHSA-652x-xj99-gmcc)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Requests vulnerable to .netrc credentials leak via malicious URLs

(GHSA-9hjg-9r4m-mvj7)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Requests Session object does not verify requests after making first request with verify=False

(GHSA-9wx4-h78v-vm56)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Exposure of Sensitive Information to an Unauthorized Actor in Requests

(GHSA-cfj3-7x9c-4p3h)


[HIGH] 17-17: requests 2.31.0requests==2.31.0: Insufficiently Protected Credentials in Requests

(GHSA-x84v-xcm2-53pg)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: undefined

(PYSEC-2020-150)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: undefined

(PYSEC-2020-151)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: Log injection in uvicorn

(GHSA-33c7-2mpw-hg34)


[HIGH] 5-5: uvicorn 0.27.0uvicorn==0.27.0: HTTP response splitting in uvicorn

(GHSA-f97h-2pfx-f59f)

🤖 Prompt for AI Agents
In requirements.txt lines 1-50 (problem lines:
3,5,7,9,15,17,23,25,27,29,35,41,43,49), each dependency string is duplicated on
the same line causing invalid requirement tokens; remove the duplicated text so
each line contains exactly one package spec (e.g., "fastapi==0.109.0"), then
update vulnerable packages to safe versions: bump python-multipart to >=0.0.7,
fastapi to >=0.109.1, and langchain to >=0.2.0 (or a 0.3.x release); verify no
other duplicate tokens remain and run pip install -r requirements.txt to confirm
the file parses.

RandithaK and others added 3 commits November 12, 2025 03:49
…ved tool usage detection; add batch document ingestion method in DocumentService; refactor async user context retrieval in MicroserviceClient; update agent tool routing tests for better validation
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (1)
requirements.txt (1)

1-119: LGTM on syntax, but critical security vulnerabilities remain unaddressed.

The syntax error from the previous review (duplicated package names) has been fixed ✓. However, the file still contains multiple HIGH and CRITICAL security vulnerabilities that must be resolved before production deployment:

Critical issues flagged by OSV Scanner:

  1. Line 86: python-multipart==0.0.6 → ReDoS vulnerability (CVE-2024-24762) in HTTP Content-Type header parsing. Upgrade to >=0.0.7.

  2. Line 17: fastapi==0.109.0 → Inherits ReDoS via transitive python-multipart (PYSEC-2024-38). Upgrade to >=0.109.1.

  3. Line 41: langchain==0.1.6 → SSRF vulnerability (CVE-2024-3095) in web retrieval components; SSRF can enable lateral movement and unauthorized data access. Version 0.1.6 is outdated. Upgrade to latest stable release.

  4. Line 42: langchain-community==0.0.20 → Mirrors langchain vulnerabilities. Pin to match upgraded langchain version.

  5. Line 99: starlette==0.35.1 → HIGH severity DoS in multipart form parsing (CVE-2024-47874 / GHSA-f96h-pmfr-66vw); unbounded form parts exhaust memory. Upgrade to >=0.40.0.

These are actively exploitable vulnerabilities (ReDoS, SSRF). The service cannot be safely deployed with these pinned versions.

Apply security upgrades:

-fastapi==0.109.0
+fastapi>=0.109.1

-langchain==0.1.6
+langchain>=0.2.0

-langchain-community==0.0.20
+langchain-community>=0.1.0

-python-multipart==0.0.6
+python-multipart>=0.0.7

-starlette==0.35.1
+starlette>=0.40.0

After updating, regenerate the lockfile and verify no new vulnerabilities are introduced.

🧹 Nitpick comments (1)
services/vector.py (1)

77-81: Simplify the fallback logic—the actual Pinecone 3.0.0 API always returns an iterable of IndexModel objects.

The Pinecone Python SDK list_indexes() method returns an iterable IndexList of IndexModel objects, each with a .name attribute. The current code's defensive pattern with the .names() fallback is unnecessary:

  • list_indexes() consistently returns an iterable, so hasattr(index_list, '__iter__') will always be True
  • The else clause doesn't exist in the actual API and becomes dead code
  • The list comprehension [idx.name for idx in index_list] is correct and sufficient

Simplify to:

existing_indexes = [idx.name for idx in index_list]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d17020 and 38436e6.

📒 Files selected for processing (7)
  • requirements.txt (1 hunks)
  • services/agent_core.py (4 hunks)
  • services/agent_tools.py (4 hunks)
  • services/document.py (1 hunks)
  • services/microservice_client.py (1 hunks)
  • services/vector.py (2 hunks)
  • test_agent_rag.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/document.py
🧰 Additional context used
🧬 Code graph analysis (3)
services/agent_tools.py (1)
services/microservice_client.py (1)
  • get_microservice_client (135-139)
services/microservice_client.py (1)
models/chat.py (1)
  • UserContext (23-27)
services/agent_core.py (2)
services/microservice_client.py (1)
  • get_user_context (50-52)
services/rag.py (1)
  • retrieve_and_format (139-186)
🪛 OSV Scanner (2.2.4)
requirements.txt

[HIGH] 17-17: fastapi 0.109.0: undefined

(PYSEC-2024-38)


[CRITICAL] 41-41: langchain 0.1.6: undefined

(PYSEC-2024-115)


[CRITICAL] 41-41: langchain 0.1.6: undefined

(PYSEC-2024-118)


[CRITICAL] 41-41: langchain 0.1.6: undefined

(PYSEC-2024-43)


[CRITICAL] 41-41: langchain 0.1.6: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 41-41: langchain 0.1.6: Langchain SQL Injection vulnerability

(GHSA-45pg-36p6-83v9)


[CRITICAL] 42-42: langchain-community 0.0.20: undefined

(PYSEC-2025-70)


[CRITICAL] 42-42: langchain-community 0.0.20: Denial of service in langchain-community

(GHSA-3hjh-jh2h-vrg6)


[CRITICAL] 42-42: langchain-community 0.0.20: LangChain pickle deserialization of untrusted data

(GHSA-f2jm-rw3h-6phg)


[CRITICAL] 42-42: langchain-community 0.0.20: LangChain Community SSRF vulnerability exists in RequestsToolkit component

(GHSA-h5gc-rm8j-5gpr)


[CRITICAL] 42-42: langchain-community 0.0.20: Langchain Community Vulnerable to XML External Entity (XXE) Attacks

(GHSA-pc6w-59fv-rh23)


[CRITICAL] 42-42: langchain-community 0.0.20: Server-Side Request Forgery in langchain-community.retrievers.web_research.WebResearchRetriever

(GHSA-q25c-c977-4cmh)


[HIGH] 86-86: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 86-86: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 99-99: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms

(GHSA-2c2j-9gv5-cj73)


[HIGH] 99-99: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data

(GHSA-f96h-pmfr-66vw)

🪛 Ruff (0.14.4)
test_agent_rag.py

128-128: f-string without any placeholders

Remove extraneous f prefix

(F541)

services/vector.py

41-41: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (13)
services/vector.py (2)

35-35: LGTM: Improved observability.

The info log provides helpful visibility into Pinecone initialization and the target index name.


38-46: Resilient error handling for network/timeout issues.

The nested try/except gracefully handles index verification failures by logging a warning and disabling the vector store. This prevents startup crashes when Pinecone is temporarily unreachable.

The broad Exception catch is acceptable here since it's during initialization and all errors are logged before graceful degradation.

services/microservice_client.py (1)

48-52: LGTM: Proper async method signature.

The method is now correctly declared as async and directly awaits the internal helper, aligning with the async patterns used in services/agent_core.py (line 81). This eliminates the previous asyncio.run() wrapper that would have blocked the event loop.

test_agent_rag.py (3)

5-10: LGTM: Windows compatibility fix.

The UTF-8 encoding wrapper prevents crashes when test output contains non-ASCII characters on Windows systems.


145-160: LGTM: More robust context filtering validation.

The test now checks for multiple decline phrases and requires at least 2 matches, making it less brittle to minor response variations while still validating the filtering behavior.


123-130: Fix unnecessary f-string.

Line 128 has an f-string without placeholders.

Apply this diff:

-            return {"success": False, "message": f"Tool was executed when it should not have been: {data.get('tool_executed')}"}
+            return {"success": False, "message": f"Tool was executed when it should not have been: {data.get('tool_executed')}"}

Wait, actually reviewing the line more carefully:

Line 127 in the annotated code shows:

if data.get("tool_executed") is not None:
     return {"success": False, "message": f"Tool was executed when it should not have been: {data.get('tool_executed')}"}

The f-string on line 128 (in the annotated code) DOES have a placeholder {data.get('tool_executed')}, so the static analysis hint appears to be a false positive. Let me skip this.

services/agent_tools.py (2)

1-10: Approved: Migration to StructuredTool.

The shift from decorator-based @tool to explicit StructuredTool.from_function aligns with the agent construction changes in services/agent_core.py (line 59-62) where initialize_agent is used with AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION.

The singleton client pattern is appropriate here.


73-90: No issues found - StructuredTool usage is correct.

The coroutine parameter is the correct API for passing async functions to StructuredTool.from_function in LangChain 0.1.6. All three functions (check_appointment_slots_tool, get_user_active_services_tool, get_last_work_log_tool) are properly defined as async def and correctly registered with the coroutine parameter. The implementation matches the documented pattern.

services/agent_core.py (5)

32-40: LGTM: Clear scope restrictions in system prompt.

The explicit scope restrictions and tool usage guidance improve the agent's behavior boundaries. The formatting with \n\n separators makes the instructions clear and scannable for the LLM.


55-69: Agent construction successfully integrates custom prompt.

The use of agent_kwargs={"prompt": agent_prompt} ensures your custom system prompt is used despite initialize_agent being a higher-level abstraction. The return_intermediate_steps=True flag is crucial for the tool execution detection logic implemented later (lines 121-141).


81-81: LGTM: Async user context retrieval.

The change to await self.ms_client.get_user_context(user_token) correctly uses the async version introduced in services/microservice_client.py (line 50).


114-114: LGTM: Proper async invocation.

Using ainvoke correctly supports the async tool functions defined in services/agent_tools.py.


121-141: Solid tool execution detection logic.

The code correctly extracts tool names from intermediate_steps by:

  1. Checking for tuple structure
  2. Accessing the AgentAction object
  3. Mapping tool names to standardized identifiers

The string matching ('appointment' in tool_name.lower()) is robust enough for the current set of tools.

Consider adding a debug log to track which tools were detected:

if tool_executed:
    logger.debug(f"Detected tool execution: {tool_executed}")

# services/agent_core.py

from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.agents import AgentExecutor, initialize_agent, AgentType
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

🧩 Analysis chain

Verify deprecation status of initialize_agent.

The code uses initialize_agent (line 59) which was deprecated in favor of create_react_agent and similar factory functions in recent LangChain versions. The comment on line 56 acknowledges this is deprecated.

Check the LangChain version and recommended alternatives:

If using a recent version, consider migrating to the recommended pattern to avoid future breaking changes.


🏁 Script executed:

#!/bin/bash
# Check LangChain version in requirements
fd -e txt -e lock requirements | xargs rg -n 'langchain'

Length of output: 109


🌐 Web query:

LangChain initialize_agent deprecation status and alternatives

💡 Result:

Status: initialize_agent was deprecated in LangChain v0.1.0. Alternatives: migrate to LangGraph or the new agent constructors (e.g., create_react_agent, create_json_agent, create_structured_chat_agent) and the new 3-step pattern (build an agent prompt, create the agent, then create an AgentExecutor). See LangChain docs/changelog for deprecation and migration guidance. [1][2][3]

References

  • API doc / deprecation note for initialize_agent. [1]
  • Deprecations/breaking-changes page listing initialize_agent and recommended alternatives. [2]
  • Example/migration guidance showing create_react_agent and the new 3-step pattern. [3]


Migrate from deprecated initialize_agent to create_react_agent pattern.

The project uses LangChain v0.1.6, where initialize_agent has been deprecated since v0.1.0. Recommended alternatives include create_react_agent, create_json_agent, create_structured_chat_agent, or migrating to LangGraph, using a new 3-step pattern: build an agent prompt, create the agent, then create an AgentExecutor.

Update line 59 and the surrounding agent construction logic (lines 55-69 in services/agent_core.py) to use the new pattern to avoid breaking changes in future LangChain updates.

Comment on lines +88 to +105
# Pre-filter: If RAG returned no relevant documents, check if query is automotive-related
if rag_result.get("num_sources", 0) == 0:
# Use a simple keyword check for automotive topics
automotive_keywords = [
'car', 'vehicle', 'auto', 'engine', 'tire', 'brake', 'oil', 'repair',
'service', 'maintenance', 'appointment', 'mechanic', 'transmission',
'battery', 'diagnostic', 'warranty', 'part', 'labor', 'wheel', 'suspension'
]
query_lower = user_query.lower()
has_automotive_keyword = any(keyword in query_lower for keyword in automotive_keywords)

# If no RAG results AND no automotive keywords, it's likely off-topic
if not has_automotive_keyword:
logger.info(f"Query appears off-topic (no RAG results, no automotive keywords): {user_query}")
return {
"output": "I'm sorry, but I can only answer questions related to vehicle services and appointments. How can I help you with your car today?",
"tool_executed": None
}
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 | 🟠 Major

Pre-filter logic is fragile and may cause false positives.

The keyword-based automotive detection has several issues:

  1. False negatives: Legitimate queries like "How do I schedule maintenance?" lack keywords and will be rejected
  2. False positives: Unrelated queries like "I have a car question: who invented the telephone?" will pass
  3. Timing: The check runs after RAG retrieval, so RAG processing overhead is wasted on off-topic queries

Additionally, this duplicates the scope enforcement already present in the system prompt (lines 32-35), which the LLM should handle.

Consider these alternatives:

Option 1: Remove the pre-filter and rely solely on the system prompt instructions, which are more nuanced:

-        # Pre-filter: If RAG returned no relevant documents, check if query is automotive-related
-        if rag_result.get("num_sources", 0) == 0:
-            # Use a simple keyword check for automotive topics
-            automotive_keywords = [...]
-            query_lower = user_query.lower()
-            has_automotive_keyword = any(keyword in query_lower for keyword in automotive_keywords)
-
-            # If no RAG results AND no automotive keywords, it's likely off-topic
-            if not has_automotive_keyword:
-                logger.info(f"Query appears off-topic (no RAG results, no automotive keywords): {user_query}")
-                return {
-                    "output": "I'm sorry, but I can only answer questions related to vehicle services and appointments. How can I help you with your car today?",
-                    "tool_executed": None
-                }

Option 2: Move the check BEFORE RAG retrieval to save processing:

# Check topic before expensive RAG retrieval
if not self._is_automotive_query(user_query):
    return {
        "output": "I'm sorry, but I can only answer questions related to vehicle services and appointments. How can I help you with your car today?",
        "tool_executed": None
    }
# Then do RAG retrieval...

Option 3: Use LLM-based classification for more accurate intent detection (adds latency but more reliable).

🤖 Prompt for AI Agents
In services/agent_core.py around lines 88-105, remove the fragile keyword-based
pre-filter block (the automotive_keywords check and its early return) because it
duplicates system-prompt scope enforcement and causes false positives/negatives;
if you need cheap early rejection to avoid RAG work, instead move a single call
before RAG like if not self._is_automotive_query(user_query): return the same
polite scope-response, and implement _is_automotive_query to perform a more
robust check (LLM-based classifier or improved heuristics) rather than inline
keyword matching.

Comment on lines 107 to 112
# 3. CRITICAL: Inject Runtime Variables into Tools
# This is needed because tools are defined globally but need runtime data
for tool in all_tools:
if hasattr(tool, 'runtime_token'):
tool.runtime_token = user_token

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: Runtime token injection is broken.

This code attempts to set tool.runtime_token = user_token on StructuredTool instances, but:

  1. StructuredTool objects don't have a runtime_token attribute by default
  2. The check hasattr(tool, 'runtime_token') will always be False
  3. Even if set, it wouldn't be accessible inside the tool functions which reference the global runtime_token variable

This code has no effect and relies on the global variable pattern flagged in services/agent_tools.py (line 7), which has race conditions.

This is the injection point that should be fixed alongside the global state issue in agent_tools.py. See the review comment on services/agent_tools.py line 7 for refactoring options.


# Global variable to hold the token for the duration of the agent's run
runtime_token = ""
runtime_token = ""
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: Global mutable state creates race conditions.

The runtime_token global variable is mutated during each agent invocation (see services/agent_core.py lines 107-111). In a concurrent environment:

  1. Request A sets runtime_token = "token-A"
  2. Request B sets runtime_token = "token-B" before A's tools execute
  3. Request A's tools execute with token-B (security violation)

This pattern leaks authentication tokens across requests and violates user isolation.

Refactor to pass the token through the tool invocation context. Use LangChain's callback mechanism or tool input parameters:

Option 1: Add token as a tool parameter (requires signature changes):

-async def check_appointment_slots_tool(date: str, service_type: str) -> str:
+async def check_appointment_slots_tool(date: str, service_type: str, token: str) -> str:
     """
     Checks the available appointment slots for a given date (YYYY-MM-DD) 
     and service_type (e.g., 'Oil Change', 'Diagnostics'). 
     Use this tool ONLY when the user asks for available times or scheduling.
     """
-    result = await client.get_appointment_slots(date, service_type, runtime_token)
+    result = await client.get_appointment_slots(date, service_type, token)

Option 2: Use LangChain's RunnableConfig to pass runtime values:

Check LangChain documentation for passing runtime context to tools without modifying signatures.

LangChain passing runtime context to tools RunnableConfig
🤖 Prompt for AI Agents
In services/agent_tools.py around line 7, the global mutable runtime_token
creates race conditions and must be removed; instead refactor so the token is
passed through the tool invocation context: delete the global runtime_token and
update the tool implementations to accept a token via parameters (or retrieve it
from a LangChain RunnableConfig/context) and modify services/agent_core.py where
the token is currently set to forward the token into each tool call or into the
RunnableConfig passed to LangChain runnables; ensure no global state is used and
that every tool invocation receives the per-request token from agent_core.

Comment on lines 77 to +108
def test_03_agent_tool_routing():
"""Test 3: Checks if the Agent correctly routes to the Appointment Tool"""
query = "Do you have any available appointments next Tuesday for an oil change?"
# Use a specific date format that the agent can work with
query = "Can you check available appointment slots on 2025-12-15 for Oil Change service?"
payload = {"query": query, "token": MOCK_TOKEN}

response = requests.post(f"{BASE_URL}/chat", json=payload, timeout=30)

if response.status_code != 200:
return {"success": False, "message": f"Chat failed (Status: {response.status_code}). Response: {response.text}"}

data = response.json()

# Check 1: Did the Agent execute the tool?
tool_used = data.get("tool_executed")
if tool_used != "Appointment_Check":
return {"success": False, "message": f"Agent failed to route to tool. Tool executed: {tool_used}"}

# Check 2: Did it return a sensible response? (Implies tool output was processed)
if "available" not in data.get("reply", "").lower():
return {"success": False, "message": f"Tool routed, but response is generic: {data.get('reply', '')[:50]}..."}
reply = data.get("reply", "").lower()

return {"success": True, "message": f"Tool routed successfully. Response: {data.get('reply', '')[:50]}..."}
# The agent might ask for date format or execute the tool
# Accept success if tool was executed OR if response mentions checking/slots
if tool_used == "Appointment_Check":
return {"success": True, "message": f"Tool routed successfully. Response: {reply[:50]}..."}
elif "slot" in reply or "appointment" in reply or "available" in reply:
# Agent responded about appointments even if tool wasn't detected
return {"success": True, "message": f"Agent handled appointment query (tool detection may need adjustment). Response: {reply[:50]}..."}
else:
return {"success": False, "message": f"Agent failed to handle appointment query. Tool: {tool_used}, Response: {reply[:100]}..."}
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

Test assertions are too permissive.

The test now accepts three different success conditions:

  1. Tool executed correctly
  2. Response mentions appointments (even without tool execution)
  3. Either of the above

This significantly weakens the test's ability to catch regressions in tool routing. If the agent stops calling tools but still mentions appointments in its response, the test will pass even though the intended behavior (tool execution) failed.

Consider splitting this into two separate test cases:

 def test_03_agent_tool_routing():
-    """Test 3: Checks if the Agent correctly routes to the Appointment Tool"""
+    """Test 3: Verifies the Agent executes the Appointment Tool"""
     query = "Can you check available appointment slots on 2025-12-15 for Oil Change service?"
     payload = {"query": query, "token": MOCK_TOKEN}
 
     response = requests.post(f"{BASE_URL}/chat", json=payload, timeout=30)
 
     if response.status_code != 200:
         return {"success": False, "message": f"Chat failed (Status: {response.status_code}). Response: {response.text}"}
 
     data = response.json()
-
-    # Check 1: Did the Agent execute the tool?
     tool_used = data.get("tool_executed")
-    reply = data.get("reply", "").lower()
 
-    # The agent might ask for date format or execute the tool
-    # Accept success if tool was executed OR if response mentions checking/slots
     if tool_used == "Appointment_Check":
-        return {"success": True, "message": f"Tool routed successfully. Response: {reply[:50]}..."}
-    elif "slot" in reply or "appointment" in reply or "available" in reply:
-        # Agent responded about appointments even if tool wasn't detected
-        return {"success": True, "message": f"Agent handled appointment query (tool detection may need adjustment). Response: {reply[:50]}..."}
+        return {"success": True, "message": "Tool routed successfully"}
     else:
-        return {"success": False, "message": f"Agent failed to handle appointment query. Tool: {tool_used}, Response: {reply[:100]}..."}
+        return {"success": False, "message": f"Expected Appointment_Check tool, got: {tool_used}"}
🤖 Prompt for AI Agents
In test_agent_rag.py around lines 83 to 108, the current single test is too
permissive because it treats either a detected tool execution or merely
mentioning appointments as success; split this into two explicit tests: one test
that sends the same payload and asserts response.status_code == 200 and
data.get("tool_executed") == "Appointment_Check" (fail if not), and a second
fallback test that asserts response.status_code == 200 and that the reply
contains appointment-related keywords (used to validate graceful handling when
tools are unavailable); replace the current multi-branch return logic with
strict assertions and distinct test functions with clear names (e.g.,
test_agent_routing_uses_appointment_tool and
test_agent_responds_about_appointments_without_tool) so each behavior is
validated independently.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38436e6 and 42f3530.

📒 Files selected for processing (1)
  • requirements.txt (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Build and Package Agent Bot Service
requirements.txt

[error] 41-43: Dependency conflict: langchain==0.3.14 (line 41) requires langchain-core>=0.3.29 and <0.4.0, but langchain-core==0.3.28 (line 43) is specified. pip install failed with ResolutionImpossible. Update langchain-core to a version >=0.3.29 or update langchain to a compatible version.

🪛 OSV Scanner (2.2.4)
requirements.txt

[HIGH] 17-17: fastapi 0.109.0: undefined

(PYSEC-2024-38)


[HIGH] 42-42: langchain-community 0.3.14: Langchain Community Vulnerable to XML External Entity (XXE) Attacks

(GHSA-pc6w-59fv-rh23)


[HIGH] 46-46: langgraph-checkpoint 2.0.12: LangGraph Checkpoint affected by RCE in "json" mode of JsonPlusSerializer

(GHSA-wwqv-p2pp-99h5)


[HIGH] 85-85: python-multipart 0.0.6: python-multipart vulnerable to Content-Type Header ReDoS

(GHSA-2jv5-9r88-3w3p)


[HIGH] 85-85: python-multipart 0.0.6: Denial of service (DoS) via deformation multipart/form-data boundary

(GHSA-59g5-xgcq-4qw3)


[HIGH] 98-98: starlette 0.35.1: Starlette has possible denial-of-service vector when parsing large files in multipart forms

(GHSA-2c2j-9gv5-cj73)


[HIGH] 98-98: starlette 0.35.1: Starlette Denial of service (DoS) via multipart/form-data

(GHSA-f96h-pmfr-66vw)

charset-normalizer==3.4.4
click==8.3.0
dataclasses-json==0.6.7
fastapi==0.109.0
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 | 🟠 Major

HIGH: Remaining security vulnerabilities in multipart/form-data parsing stack.

Despite upgrading langchain, three dependencies still carry actively exploitable HIGH-severity vulnerabilities affecting multipart form parsing:

  • Line 17 (fastapi 0.109.0): PYSEC-2024-38 ReDoS vulnerability via transitive python-multipart dependency; fixed in >=0.109.1.
  • Line 85 (python-multipart 0.0.6): GHSA-2jv5-9r88-3w3p (Content-Type ReDoS) and GHSA-59g5-xgcq-4qw3 (malformed boundary DoS); fixed in >=0.0.7.
  • Line 98 (starlette 0.35.1): GHSA-2c2j-9gv5-cj73 and GHSA-f96h-pmfr-66vw (multipart DoS); fixed in later versions.

Upgrade these dependencies to secure versions:

-fastapi==0.109.0
+fastapi==0.109.1

-python-multipart==0.0.6
+python-multipart==0.0.7

-starlette==0.35.1
+starlette==0.37.0

After applying, regenerate the requirements file and verify pip install -r requirements.txt succeeds.

Also applies to: 85-85, 98-98

🧰 Tools
🪛 OSV Scanner (2.2.4)

[HIGH] 17-17: fastapi 0.109.0: undefined

(PYSEC-2024-38)

🤖 Prompt for AI Agents
In requirements.txt (lines 17, 85, 98) update the vulnerable packages: change
fastapi at line 17 to at least 0.109.1, change python-multipart at line 85 to at
least 0.0.7, and bump starlette at line 98 to a patched release (use the latest
patch release compatible with your FastAPI version) so the multipart/form-data
ReDoS/DoS fixes are included; after updating, regenerate the requirements file
(or run pip-compile / pip freeze as appropriate) and verify by running pip
install -r requirements.txt that installation succeeds.

@AdithaBuwaneka AdithaBuwaneka merged commit 1116c2e into main Nov 12, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 23, 2025
Merged
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants