Skip to content

Conversation

@ankush0511
Copy link

@ankush0511 ankush0511 commented Sep 16, 2025

added algomentor and the scholerlens into the advanced agents.
these projects are based on the AI and Agentic Ai .

Pull Request

Type of Change

  • Project Addition
  • Bug Fix
  • Feature Implementation
  • Documentation Update
  • Other (please describe)

Project Details

  • Project Name: AlgoMentor
  • Target Directory:advance_ai_agents

Description

AlgoMentor is an AI-powered coding mentor that guides learners through problem-solving. It simulates the journey from brute force to optimal solutions using intelligent agents, verifies code, and generates explanatory notes—helping developers not just solve problems but understand algorithms and improve coding skills effectively.

Technical Details

Python , Agno , Agentic Ai

  • Primary Language/Framework: Python
  • Key Dependencies:
  • API Requirements:Groq,Gemini
  • Changes to existing code:
  • New files added:
  • Dependencies added/removed:

Installation Steps (if applicable)

1. git clone https://github.com/ankush0511/AlgoMentor.git
2. cd AlgoMentor
3. pip install -r requirements.txt

Checklist

  • Project name follows naming convention (descriptive with underscores)
  • Added to the correct directory
  • Includes comprehensive README.md (if new project)
  • Code follows project structure and conventions
  • All dependencies are properly listed in requirements.txt
  • Added appropriate documentation
  • Code is properly formatted and linted
  • Added necessary tests (if applicable)
  • No breaking changes introduced
  • Documentation updated (if necessary)

Additional Notes

added algomentor and the scholerlens into the advanced agents.
these projects are based on the AI and Agentic Ai .
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Walkthrough

Adds two new advanced agents (AlgoMentor, ScholarLens) and two simple agents (Career_Guidence, Recruitify). Introduces multiple Streamlit apps, agents/teams, Pydantic schemas, RAG pipelines, resume analysis/interview flows, comparison utilities, documentation, examples, environment templates, and requirements with sqlite patchers and .gitignore files.

Changes

Cohort / File(s) Summary
Root Docs
README.md
Lists four new agents with brief descriptions; minor spacing; noted label/path mismatch for ScholarLens link.
AlgoMentor • Setup/Config
advance_ai_agents/AlgoMentor/.env.example, .../.gitignore, .../requirements.txt, .../patch_sqlite.py, .../config/__init__.py, .../config/settings.py
Adds env template, gitignore, deps (agno, streamlit, groq, google-genai, pysqlite3-binary), sqlite shim, and app settings (secrets, models, UI, DEBUG/LOG_LEVEL).
AlgoMentor • Docs/Examples
advance_ai_agents/AlgoMentor/docs/examples/*
New problem walkthroughs: 4Sum, Edit Distance, Merge BSTs with approaches, complexity, examples.
AlgoMentor • Models
advance_ai_agents/AlgoMentor/src/models/__init__.py, .../schemas.py
Adds extensive Pydantic schemas for problem data, approaches, code, verification, explanations; contains duplicated class names overriding earlier ones.
AlgoMentor • Agents
advance_ai_agents/AlgoMentor/src/agents/*
Adds agents/teams: brute-force (analysis/code/team), code evaluator/verify, sub-optimal generators/implementers, optimal approach/code agents, question finder, problem analyzer team (leetcode_team).
AlgoMentor • Core App/UI
advance_ai_agents/AlgoMentor/src/core/app.py
Introduces DSAAssistantApp Streamlit UI with staged workflow (Basic → Sub-Optimal → Optimal) and a Notes Mentor tab orchestrating agents and verification.
AlgoMentor • Entry/Init
advance_ai_agents/AlgoMentor/main.py, .../src/__init__.py, .../src/agents/__init__.py, .../src/core/__init__.py
App bootstrap with page config and app.run(); package docstrings.
ScholarLens • App & Docs
advance_ai_agents/ScholarLens/main.py, .../README.md
New Streamlit app with ArXiv search, AI companion, RAG chatbot, paper comparison; README with features, stack, setup, usage.
ScholarLens • RAG & Compare
advance_ai_agents/ScholarLens/comparision/ComparePapers.py, .../rag/*, .../patch_sqlite.py
PDF compare chain (GROQ); RAG setup for Pinecone/Gemini and Chroma (some code disabled in strings); sqlite shim.
ScholarLens • Env/Ignore
advance_ai_agents/ScholarLens/requirements.txt, .../.gitignore
Adds dependencies (agno, pinecone, langchain, streamlit, PyMuPDF, etc.) and ignore patterns incl. research artifacts.
Career_Guidence • App & Docs
simple_ai_agents/Career_Guidence/README.md, .../app.py, .../career_chatbot.py, .../career_guidance_system.py, .../demo.ipynb, .../temp.py, .../requirements.txt, .../.gitignore
Streamlit career guidance app with tabs, RAG chat, analysis/roadmap/insights via Groq/Gemini/SerpAPI; notebook demo; temp alt implementation; deps and ignores.
Recruitify • App Suite
simple_ai_agents/Recruitify/README.md, .../app.py, .../agents.py, .../interview.py, .../ui.py, .../requirements.txt, .../patch_sqlite.py, .../temp/*, .../.gitignore
Full recruitment assistant: resume parsing/RAG scoring, Q&A, interview question gen, resume improvements, voice interview (Deepgram + Groq), UI utilities, deps, sqlite shim; temp prototypes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as Streamlit UI (DSAAssistantApp)
  participant TeamB as Basic Team (leetcode_team)
  participant SubA as Suboptimal Agents (suboptimal_agent, sub_agent)
  participant Ver as Verify (code_runner, code_verify_agent)
  participant OptA as Optimal Agents (optimal_agent_enhanced, optimal_code_agent)

  User->>UI: Enter DSA problem
  UI->>TeamB: run(query)
  TeamB-->>UI: Problem breakdown + brute-force
  UI-->>User: Show Basic results

  User->>UI: Proceed to Sub-Optimal
  UI->>SubA: Generate approach + code
  UI->>Ver: Run tests/verify
  Ver-->>UI: Verified sub-optimal result
  UI-->>User: Show Sub-Optimal results

  User->>UI: Proceed to Optimal
  UI->>OptA: Generate optimal approach + code
  UI->>Ver: Run tests/verify
  Ver-->>UI: Verified optimal result
  UI-->>User: Show Optimal results
Loading
sequenceDiagram
  autonumber
  actor User
  participant SL as ScholarLens App
  participant Src as ArXiv/Search
  participant Sum as Summarizer/Crew
  participant RAG as RAG (Embeddings + VectorDB)
  participant Comp as Comparison Chain

  User->>SL: Select page
  alt ArXiv Smart Search
    SL->>Src: Fetch papers
    Src-->>SL: Results
    SL-->>User: Papers list/details
  else AI Paper Companion
    User->>SL: Upload PDF
    SL->>Sum: Extract + summarize sections
    Sum-->>SL: Structured summaries
    SL-->>User: Glance/Guru outputs
  else RAG Chatbot
    User->>SL: Upload PDF / Ask
    SL->>RAG: Build KB / Query
    RAG-->>SL: Answer
    SL-->>User: Response
  else Paper Comparison
    User->>SL: Upload PDFs
    SL->>Comp: Compare texts
    Comp-->>SL: Markdown table
    SL-->>User: Comparative analysis
  end
Loading
sequenceDiagram
  autonumber
  actor User
  participant RUI as Recruitify UI
  participant RA as ResumeAnalysisAgent
  participant Vec as FAISS/Embeddings
  participant LLM as LLMs (Gemini/Groq)
  participant DG as Deepgram

  User->>RUI: Upload Resume / Select Role
  RUI->>RA: analyze_resume(file, role/JD)
  RA->>Vec: Build/Query vector store
  RA->>LLM: Extract/score skills, generate insights
  LLM-->>RA: Scores/Insights
  RA-->>RUI: Analysis result
  RUI-->>User: Score, strengths/weaknesses

  User->>RUI: Interview Assistant
  RUI->>DG: Transcribe speech
  RUI->>LLM: Evaluate response
  LLM-->>RUI: Feedback + scores
  RUI-->>User: Report and charts
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120+ minutes

Suggested labels

enhancement

Suggested reviewers

  • Arindam200
  • shivaylamba

Poem

hop-hop! I stitch new streams of thought,
tabs and teams where answers are taught.
Resumes whisper, papers confide,
Rabbity agents compare, verify, guide.
From brute to bright, we nudge the code—
carrots of insight on every road. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 refers to adding "career guidence" and "recruitify", which matches starter-agent additions in the changeset, so it is related to the PR; however it contains a spelling error ("guidence" → "guidance"), awkward punctuation/capitalization, and it omits major advanced-agent additions (AlgoMentor and ScholarLens) present in this PR, so it does not accurately summarize the full scope.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

@gitguardian
Copy link

gitguardian bot commented Sep 16, 2025

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
- - Generic High Entropy Secret d93a2a4 simple_ai_agents/Recruitify/temp/practise.py View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link
Contributor

@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: 46

🧹 Nitpick comments (94)
advance_ai_agents/AlgoMentor/src/__init__.py (3)

1-1: Add trailing newline at EOF.

PEP 8/tools expect a newline at end of file.

Apply this diff:

-"""DSA Assistant - AI-powered companion for mastering Data Structures & Algorithms"""
+"""DSA Assistant - AI-powered companion for mastering Data Structures & Algorithms"""
+

1-1: Optionally expose a small public API from the package.

If DSAAssistantApp (or similar) is the main entry, re-export it for cleaner imports.

Apply if symbol exists and is stable:

 """DSA Assistant - AI-powered companion for mastering Data Structures & Algorithms"""
+from .core.app import DSAAssistantApp  # noqa: F401
+__all__ = ["DSAAssistantApp"]

1-1: Consider avoiding “src” as an importable package.

Today this file makes ...AlgoMentor.src the import path. Prefer a real package name (e.g., algomentor) under a top-level src/ layout: src/algomentor/__init__.py, and configure packaging to find packages accordingly.

advance_ai_agents/AlgoMentor/src/agents/__init__.py (1)

1-1: Nit: polish wording for consistency with PEP 257 and grammar.
Prefer sentence case and hyphenation for “problem‑solving.”

Apply this diff:

-"""AI Agents for DSA problem solving"""
+"""AI agents for DSA problem-solving."""
simple_ai_agents/Recruitify/.gitignore (3)

2-7: Fix .gitignore patterns: remove ./ and backslash; correct pycache and mark dirs with trailing slash.

Current patterns may not match as intended. Use forward slashes and trailing slashes for directories; remove the mistaken ".pycache".

 .env
-./env
-.\env
-.__pycache__
-./__pycache__
-.venv
-./venv
+env/
+venv/
+.venv/
+__pycache__/

1-1: Optionally cover common .env variants (keep the template).

If you use .env.local, .env.prod, etc., ignore them while keeping .env.example tracked.

 .env
+.env.*
+!.env.example

1-7: Optional: add typical Python ignores for this app folder.

These are common and safe in a Streamlit/agent project.

+*.py[cod]
+.pytest_cache/
+.mypy_cache/
+.ruff_cache/
+.coverage
+htmlcov/
advance_ai_agents/AlgoMentor/src/core/__init__.py (1)

1-1: Nit: add trailing newline at EOF.

Minor POSIX/style nit; some linters flag missing newline.

-"""Core application logic"""
+"""Core application logic"""
+
advance_ai_agents/AlgoMentor/patch_sqlite.py (1)

2-2: Remove unused import.

os isn't used.

-import os
advance_ai_agents/AlgoMentor/.gitignore (1)

79-81: Optional: ignore a few common artifacts.

Add pytest cache, coverage files, and macOS metadata.

 # Cache
 .cache/
 *.cache
+.pytest_cache/
+.coverage
+.DS_Store
simple_ai_agents/Recruitify/patch_sqlite.py (1)

2-2: Remove unused import.

os isn't used.

-import os
advance_ai_agents/ScholarLens/.gitignore (1)

15-15: Limit the scope of research ignores.

*research* will ignore any path containing the substring “research” anywhere. That’s risky.

-*research*
+# Prefer explicit directories
+research/
+research/** 

Do you also want to ignore .streamlit/ and secrets.toml here (as in AlgoMentor)?

simple_ai_agents/Career_Guidence/requirements.txt (1)

1-13: Pin versions and review package choices; also fix “Guidence” naming.

  • Unpinned deps risk breakage; pin at least major.minor or exact where needed (Streamlit, LangChain ecosystem, FAISS).
  • Consider using langchain-core + provider-specific packages instead of the umbrella langchain to reduce footprint.
  • Directory name is misspelled (“Career_Guidence”); align to “Career_Guidance” for professionalism and discoverability.

Would you like a PR-ready constraints.txt with conservative pins and a migration checklist for renaming the directory without breaking imports?

advance_ai_agents/AlgoMentor/README.md (3)

19-25: Fix Quick Start for this monorepo path.

These commands clone a different repo. Update to this repository and subdirectory.

-# Clone the repository
-git clone https://github.com/ankush0511/AlgoMentor.git
-cd AlgoMentor
+# Clone the repository
+git clone https://github.com/Arindam200/awesome-ai-apps.git
+cd awesome-ai-apps/advance_ai_agents/AlgoMentor

Confirm the final run command matches the actual entrypoint path (streamlit run main.py from this directory).


34-37: Add language to fenced code block (markdownlint MD040).

Use ini for env-style blocks.

-```
+```ini
 GROQ_API_KEY=your_groq_api_key
 GOOGLE_API_KEY=your_google_api_key

---

`47-63`: **Add language to fenced code block (markdownlint MD040).**

Declare as text for tree output.

```diff
-```
+```text
 DSAAssistant/
 ├── 📁 src/                    # Source code
 │   ├── 📁 agents/             # AI agents for different optimization levels
 │   ├── 📁 models/             # Pydantic data models
 │   ├── 📁 utils/              # Utility functions
 │   ├── 📁 ui/                 # User interface components
 │   └── 📁 core/               # Core application logic
 ├── 📁 config/                 # Configuration files
 ├── 📁 tests/                  # Test files
 ├── 📁 docs/                   # Documentation
 ├── 📁 assets/                 # Static assets
 ├── 📄 main.py                 # Application entry point
 ├── 📄 requirements.txt        # Python dependencies
 ├── 📄 .env.example           # Environment variables template
 └── 📄 README.md              # Project documentation

</blockquote></details>
<details>
<summary>advance_ai_agents/ScholarLens/README.md (4)</summary><blockquote>

`118-124`: **Fix run command to match entry point.**

Project structure lists main.py as the entry point, but Usage shows streamlit run app.py. Update to avoid launch failures.

Apply this diff:

```diff
-```bash
-streamlit run app.py
-```
+```bash
+streamlit run main.py
+```

69-80: Specify code-fence language for structure block.

Add a language to satisfy markdownlint and enable syntax highlighting.

Apply this diff:

-```
+```text
 ...
-```
+```

134-134: Avoid bare URL; link it.

Prevents MD034 and renders cleaner.

Apply this diff:

-Check out the demo: https://scholarlens.streamlit.app/
+Check out the demo: [scholarlens.streamlit.app](https://scholarlens.streamlit.app/)

73-73: Optional: directory name typo ("comparision").

Consider renaming to comparison/ for correctness and consistency; if you keep the current name for now, ensure all imports and docs consistently use comparision/.

advance_ai_agents/AlgoMentor/docs/examples/MergeBst.md (2)

1-1: Remove outer code fence; the whole document is currently inside a code block.

The leading ```markdown causes the entire page to render as code. Drop it (and the trailing fence) so headings/sections render.

Apply this diff:

-```markdown

---

`63-76`: **Add languages to fenced code blocks.**

Label the small BST diagrams as text to satisfy MD040.

Apply this diff:

```diff
-```
+```text
 ...
-```
+```

Also applies to: 100-112

advance_ai_agents/ScholarLens/comparision/ComparePapers.py (1)

21-45: Reduce hallucinations in comparison output.

Prompt currently asks the model to “complete missing sections.” Prefer explicit “Unknown” for missing facts to avoid fabrications.

Apply this diff:

-Please use your understanding and reasoning abilities to compare and complete any missing sections if possible.
+Do not invent facts. If specific details are missing, write "Unknown" and base comparisons only on provided text.
@@
-Return the output as a **well-formatted Markdown table** for easy comparison.
+Return the output as a **well-formatted Markdown table**. Use "Unknown" when details are missing.
advance_ai_agents/ScholarLens/rag/Agentic_Rag.py (2)

9-9: Remove duplicate import.

Redefinition of os; keep only one import.

Apply this diff:

-import os

78-78: Tidy stray quote sequence.

Replace """" with """ for readability; current form is parsed but confusing.

Apply this diff:

-"""" 
+"""
advance_ai_agents/AlgoMentor/config/settings.py (2)

7-12: Use resilient secret loading with env fallbacks and clear errors.

Direct st.secrets indexing can crash and there’s no fallback. Align with other modules and .env usage.

Apply this diff:

-# GROQ_API_KEY = os.getenv("GROQ_API_KEY")
-# GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
-groq_api_key=st.secrets['GROQ_API_KEY']
-google_api_key=st.secrets['GOOGLE_API_KEY']
+groq_api_key = st.secrets.get('GROQ_API_KEY') or os.getenv('GROQ_API_KEY')
+google_api_key = st.secrets.get('GOOGLE_API_KEY') or os.getenv('GOOGLE_API_KEY')
+if not groq_api_key or not google_api_key:
+    # Prefer a clear failure early rather than latent runtime errors.
+    raise RuntimeError("Missing GROQ_API_KEY or GOOGLE_API_KEY. Configure via Streamlit secrets or environment.")

13-16: Model names as settings.

Consider moving GROQ_MODEL/GEMINI_MODEL to env-configurable values to avoid code edits for model switches.

simple_ai_agents/Recruitify/temp/practise.py (1)

299-301: Clean up stray triple-quote constructs in this temp file.

The odd """"" / """ sequences are confusing and trip linters. If you want to keep prototypes, wrap the entire file in a proper multi-line comment/docstring or delete the file.

Suggested minimal fix: convert the scaffold to a single docstring at top and remove trailing unmatched quotes.

Also applies to: 619-619

advance_ai_agents/AlgoMentor/docs/examples/4Sum.md (3)

1-1: Remove outer ```markdown fence.

Same issue as other docs: the page renders as one code block.

Apply this diff:

-```markdown

---

`104-104`: **Avoid bare URLs.**

Wrap in a link to satisfy MD034.

Example:

```diff
-... continues, skipping duplicate quadruplets
-33. Finally, the algorithm returns `result = [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]`
+... continues, skipping duplicate quadruplets
+33. Finally, the algorithm returns `result = [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]`

And wrap any bare links as link where present.


106-125: Label fenced blocks.

Add a language (text) to ASCII diagrams for MD040.

Apply this diff:

-```
+```text
 ...
-```
+```
advance_ai_agents/AlgoMentor/src/models/schemas.py (2)

4-14: Unify ‘constraints’ typing across models.

Inconsistent types: str (LeetCodeProblem, LeetCode) vs List[str] (QuestionFinderInput). Pick one (ideally List[str]) and align.

Example:

-class LeetCodeProblem(BaseModel):
-    constraints: str
-    examples: List[str]
+class LeetCodeProblem(BaseModel):
+    constraints: List[str]
+    examples: List[str]

Also applies to: 134-143, 145-151


1-3: Optional: enforce strict schema handling.

Consider forbidding extra fields on all models to catch typos early.

Add once and inherit:

from pydantic import BaseModel, ConfigDict

class StrictModel(BaseModel):
    model_config = ConfigDict(extra="forbid")

Then extend StrictModel instead of BaseModel.

advance_ai_agents/AlgoMentor/.env.example (1)

2-3: Satisfy dotenv lint and add final newline.

Alphabetize keys and end file with a newline.

-# API Keys
-GROQ_API_KEY=your_groq_api_key_here
-GOOGLE_API_KEY=your_google_api_key_here
+# API Keys
+GOOGLE_API_KEY=your_google_api_key_here
+GROQ_API_KEY=your_groq_api_key_here
@@
-LOG_LEVEL=INFO
+LOG_LEVEL=INFO
+

Also applies to: 7-7

advance_ai_agents/ScholarLens/rag/Chroma_Agentic_Rag.py (2)

11-15: Harden API key loading (avoid KeyError outside Streamlit).

Gracefully fallback to env var and validate presence.

-load_dotenv()
-GOOGLE_API_KEY = st.secrets['GOOGLE_API_KEY']
-# GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
+load_dotenv()
+try:
+    GOOGLE_API_KEY = st.secrets["GOOGLE_API_KEY"]  # Streamlit
+except Exception:
+    GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
+if not GOOGLE_API_KEY:
+    raise RuntimeError("GOOGLE_API_KEY not set in st.secrets or environment")

17-18: Use gemini-embedding-001 and parameterize the Chroma path

gemini-embedding-001 is the recommended production embedding model (text-embedding-004 is legacy). Make the model id and Chroma path configurable and ensure the DB directory exists.

-embeddings = GeminiEmbedder(api_key=GOOGLE_API_KEY, id='models/gemini-embedding-001')
-vector_db = ChromaDb(collection="arxiv_papers", path="./research", persistent_client=True, embedder=embeddings)
+import os
+embeddings = GeminiEmbedder(api_key=GOOGLE_API_KEY, id=os.getenv("GEMINI_EMBED_MODEL", "gemini-embedding-001"))
+collection = os.getenv("CHROMA_COLLECTION", "arxiv_papers")
+db_path = os.getenv("CHROMA_PATH", "./research")
+os.makedirs(db_path, exist_ok=True)
+vector_db = ChromaDb(collection=collection, path=db_path, persistent_client=True, embedder=embeddings)

Confirm whether your GeminiEmbedder wrapper/SDK expects the "models/" prefix; if required, set GEMINI_EMBED_MODEL default to "models/gemini-embedding-001".

advance_ai_agents/AlgoMentor/main.py (1)

8-13: Make page_icon path robust across working directories.

Avoid relative-path breakage when launching from repo root.

-import streamlit as st
+import streamlit as st
+from pathlib import Path
@@
-    st.set_page_config(
+    icon_path = Path(__file__).parent / "assets" / "logo.svg"
+    st.set_page_config(
         page_title=PAGE_TITLE,
         layout=PAGE_LAYOUT,
         initial_sidebar_state=SIDEBAR_STATE,
-        page_icon="assets/logo.svg"
+        page_icon=str(icon_path)
     )
simple_ai_agents/Recruitify/README.md (4)

94-97: Fix repo/dir instructions.

The clone path and cd should reflect this repository and subdirectory to prevent confusion.

-git clone https://github.com/yourusername/recruitment-agent.git
-cd recruitment-agent
+git clone https://github.com/Arindam200/awesome-ai-apps.git
+cd awesome-ai-apps/simple_ai_agents/Recruitify

132-136: Remove trailing punctuation in heading.

Comply with MD026.

-### Modes:
+### Modes

141-149: Specify language for fenced block.

Comply with MD040.

-```
+```text
 .
 ├── app.py               # Main Streamlit app entry point
 ├── agents.py            # Resume analysis agent (LLM, RAG, scoring, improvements)
 ├── interview.py         # AI-powered voice interview assistant
 ├── ui.py                # Streamlit UI components and styling
 ├── requirements.txt     # Dependencies
 └── README.md            # Project documentation

179-180: Remove non-doc prompt from README.

The “generate requirements.txt” sentence reads like an assistant prompt and should be dropped.

-Would you like me to also **generate a `requirements.txt`** file for you based on the imports in all four files? That way your repo will be fully ready to run.
README.md (2)

34-36: Fix typos/grammar in new Starter Agents entries.

Clear, professional descriptions improve discoverability.

Apply:

- [Career_Guidence](simple_ai_agents/Career_Guidence) - Gives the guidence and roadmap towards career based on the user selected options,it also supports Traditional Rag.
- [Recruitify](simple_ai_agents/Recruitify) - A web app that analyse the resume based on the JobDescription,Interview Question,Enhance Resume,Practise interview based on the question generated.
+ [Career_Guidence](simple_ai_agents/Career_Guidence) - Provides guidance and a roadmap for careers based on user-selected options; supports traditional RAG.
+ [Recruitify](simple_ai_agents/Recruitify) - An app that analyzes a resume against a job description, generates interview questions, suggests resume enhancements, and lets you practice interviews.

102-104: Correct label, spacing, and framework name for ScholarLens.

Avoid broken bullet and name mismatch.

--[ScholaeLens](advance_ai_agents/ScholarLens) - Agentic Workflow for Find Research Paper,Summarizer,Agentic Rag With Pinecone and Agnno, and Companion of papers.
+- [ScholarLens](advance_ai_agents/ScholarLens) - Agentic workflow to find research papers, summarize, and run agentic RAG with Pinecone and Agno; a companion for papers.
advance_ai_agents/AlgoMentor/src/agents/qution_finder.py (2)

14-22: Ensure response_model fields are producible; tighten instructions.

QuestionFinderInput requires user_input; current instructions don’t tell the model to produce it.

 question_finder=Agent(
@@
-    instructions = [
-        "Format the given content into the required structure with problem statement, difficulty, examples,constraints, and explanations."
-        ],
+    instructions = [
+        "Return JSON matching the QuestionFinderInput schema with fields: user_input, problem_statement, difficulty, examples[], constraints[], explanations[].",
+        "Populate user_input with the original prompt/description.",
+        "Keep examples, constraints, explanations as arrays of concise strings."
+    ],
     response_model=QuestionFinderInput
 )

1-22: Rename module qution_finder.py → question_finder.py and update imports

Filename has a typo (qution_finder); problem_analyzer.py imports .qution_finder (advance_ai_agents/AlgoMentor/src/agents/problem_analyzer.py:2), so imports are currently consistent but renaming will require updating all import sites.

simple_ai_agents/Career_Guidence/README.md (3)

43-51: Fix repo path and install steps for monorepo.

Current instructions point to a standalone repo and “Career_Guidence-main/”.

-```
-Career_Guidence-main/
+```
+simple_ai_agents/Career_Guidence/
@@
-1️⃣ **Clone the repository**
+1️⃣ **Clone the repository**
@@
-git clone https://github.com/your-username/Career_Guidence.git
-cd Career_Guidence-main
+git clone https://github.com/Arindam200/awesome-ai-apps.git
+cd awesome-ai-apps/simple_ai_agents/Career_Guidence

Also applies to: 59-66


103-105: Polish demo link.

Use a neutral label and standard phrasing.

-check this: https://careerguidencer.streamlit.app/
+Live demo: https://careerguidencer.streamlit.app/

113-116: License duplication risk.

Consider referencing the root MIT license to avoid divergence.

-MIT License © 2025 Career Guidance AI
+This project follows the repository’s MIT License (see /LICENSE).
advance_ai_agents/AlgoMentor/src/agents/code_evaluator_BForce.py (2)

30-37: Fix missing commas causing implicit string concatenation; clean typos.

Two adjacency issues merge instructions into fewer items; also minor typos.

-    instructions=[
-        "you will recive a json object that contains the python code and the test_cases."
-        "1. First, analyze and understand the code logic",
+    instructions=[
+        "You will receive a JSON object that contains the Python code and the test_cases.",
+        "1. First, analyze and understand the code logic",
         "2. Run the provided code with the given examples",
         "3. Compare the actual output with the expected output and show to the user",
         "4. Provide detailed results including whether the code works correctly",
-        "5. If there are any issues, explain what went wrong and suggest fixes"
-        "6. if the code working fine then update the code to `updated_code` section in pydantic. and save to the .py file "
+        "5. If there are any issues, explain what went wrong and suggest fixes",
+        "6. If the code works, update the `updated_code` field in the Pydantic model and save it to a .py file."
     ],

13-21: Temp dir lifecycle in Streamlit.

Streamlit reruns can create multiple temp dirs before atexit fires. Consider creating the temp dir per evaluation or using TemporaryDirectory context when the tool runs.

simple_ai_agents/Career_Guidence/app.py (6)

297-299: Narrow exception handling and use explicit conversion flags.

Prefer f"{e!s}" (or st.exception) and catch narrower exceptions where possible.

-                            except Exception as e:
-                                st.error(f"Error during analysis: {str(e)}")
+                            except Exception as e:
+                                st.error(f"Error during analysis: {e!s}")
@@
-                    except Exception as e:
-                        st.error(f"Error generating market analysis: {str(e)}")
+                    except Exception as e:
+                        st.error(f"Error generating market analysis: {e!s}")
@@
-                    except Exception as e:
-                        st.error(f"Error generating roadmap: {str(e)}")
+                    except Exception as e:
+                        st.error(f"Error generating roadmap: {e!s}")
@@
-                    except Exception as e:
-                        st.error(f"Error generating insights: {str(e)}")
+                    except Exception as e:
+                        st.error(f"Error generating insights: {e!s}")

Also applies to: 453-455, 560-562, 644-646


396-401: Drop unused loop variable.

Small cleanup.

-for i in range(1, 4):
-    salaries.append(salaries[-1] * (1 + np.random.uniform(0.2, 0.4)))
+for _ in range(1, 4):
+    salaries.append(salaries[-1] * (1 + np.random.uniform(0.2, 0.4)))

651-653: Consistent naming: Groq.

Use “Groq” consistently.

-        st.warning("Please enter your GROQ API key in the sidebar to get started.")
+        st.warning("Please enter your Groq API key in the sidebar to get started.")

1-10: Minor: remove unused imports.

pd, go, datetime, os aren’t used in this file.


436-446: Simplify career_analysis initialization.

The check for "career_analysis" in session_state is redundant; initialize to {} when first used.

-                            # Save to session state
-                            if "career_analysis" not in st.session_state:
-                                st.session_state.career_analysis = {}
-                            
-                            if isinstance(st.session_state.career_analysis, dict):
-                                st.session_state.career_analysis["market_analysis"] = market_analysis
-                            else:
-                                st.session_state.career_analysis = {
-                                    "career_name": st.session_state.selected_career,
-                                    "market_analysis": market_analysis
-                                }
+                            st.session_state.career_analysis = (st.session_state.career_analysis or {}) or {}
+                            st.session_state.career_analysis["career_name"] = st.session_state.selected_career
+                            st.session_state.career_analysis["market_analysis"] = market_analysis

340-389: Optional: deterministic visuals.

Seed np.random so charts don’t jump on every rerun.

-            growth_rate = np.random.uniform(0.05, 0.15)
+            rng = np.random.default_rng(42)
+            growth_rate = rng.uniform(0.05, 0.15)
@@
-            base_salary = np.random.randint(60000, 90000)
+            base_salary = rng.integers(60000, 90000)
@@
-            skills = {
-                "Technical": np.random.randint(70, 95),
-                "Problem-solving": np.random.randint(70, 95),
-                "Communication": np.random.randint(70, 95),
-                "Teamwork": np.random.randint(70, 95),
-                "Industry Knowledge": np.random.randint(70, 95)
-            }
+            skills = {k: int(v) for k, v in {
+                "Technical": rng.integers(70, 95),
+                "Problem-solving": rng.integers(70, 95),
+                "Communication": rng.integers(70, 95),
+                "Teamwork": rng.integers(70, 95),
+                "Industry Knowledge": rng.integers(70, 95),
+            }.items()}

Also applies to: 396-423, 587-615

advance_ai_agents/AlgoMentor/src/agents/problem_analyzer.py (1)

14-14: groq_api_key is defined but unused.

Remove or use it; unused secret handling may confuse readers.

-groq_api_key = st.secrets.get('GROQ_API_KEY') or os.getenv('GROQ_API_KEY')
advance_ai_agents/AlgoMentor/src/agents/notes.py (2)

12-12: Remove unused groq_api_key.

It’s not used in this module.

-groq_api_key = st.secrets.get('GROQ_API_KEY') or os.getenv('GROQ_API_KEY')

128-161: Consider logging hygiene for monitoring=True.

If monitoring logs inputs/outputs, ensure PII is scrubbed or disabled in prod.

advance_ai_agents/AlgoMentor/src/agents/optimal_agent.py (2)

17-17: Fix agent name typo.

“writter” → “writer”.

-    name="optimal code writter",
+    name="Optimal Code Writer",

22-35: Prompt mismatch: references sub_optimal_approach not provided.

Align inputs with OptimalCode schema to avoid confusion.

-        "- Carefully analyze the problem statement and the provided approaches.(sub_optimal_approach)",
+        "- Carefully analyze the problem statement and the provided optimal approach.",
simple_ai_agents/Recruitify/interview.py (7)

15-193: Don’t duplicate CSS; reuse existing apply_custom_css from ui.py.

Import and call the shared helper to avoid drift.

-from re import *
@@
-def apply_custom_css(accent_color="#d32f2f"):
-    st.markdown(f""" 
-    ... long CSS omitted ...
-    """, unsafe_allow_html=True)
+from .ui import apply_custom_css

(Then delete the local apply_custom_css definition.)


240-242: Narrow exception; use explicit conversion flag.

Avoid blanket Exception and prefer {e!s} per Ruff RUF010.

-            except Exception as e:
-                st.error(f"Error parsing file: {str(e)}")
+            except (ValueError, IndexError, re.error) as e:
+                st.error(f"Error parsing file: {e!s}")

226-226: Replace curly apostrophe with ASCII.

Fix RUF001.

-                st.error("Failed to decode file. Ensure it’s a valid .md or .txt file with UTF-8 encoding.")
+                st.error("Failed to decode file. Ensure it's a valid .md or .txt file with UTF-8 encoding.")

325-327: Narrow exception; use explicit conversion flag.

-                except Exception as e:
-                    st.error(f"Failed to generate or play audio: {str(e)}")
+                except (RuntimeError, OSError) as e:
+                    st.error(f"Failed to generate or play audio: {e!s}")

340-355: Ensure correct audio suffix and cleanup tmp file.

mic_recorder usually returns WAV/WEBM; using .mp3 can mislead tools. Also delete the temp file.

-            with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmpfile:
+            with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
                 tmpfile.write(audio['bytes'])
                 tmpfile_path = tmpfile.name
-            deepgram = DeepgramClient(api_key=self.DEEPGRAM_API_KEY)
-            with open(tmpfile_path, "rb") as file:
-                buffer_data = file.read()
-            payload: FileSource = {"buffer": buffer_data}
-            options = PrerecordedOptions(model="nova-3", smart_format=True)
-            response = deepgram.listen.rest.v("1").transcribe_file(payload, options)
+            try:
+                deepgram = DeepgramClient(api_key=self.DEEPGRAM_API_KEY)
+                with open(tmpfile_path, "rb") as file:
+                    buffer_data = file.read()
+                payload: FileSource = {"buffer": buffer_data}
+                options = PrerecordedOptions(model="nova-3", smart_format=True)
+                response = deepgram.listen.rest.v("1").transcribe_file(payload, options)
+            finally:
+                if os.path.exists(tmpfile_path):
+                    os.remove(tmpfile_path)

406-407: Narrow exception; use explicit conversion flag.

-            except Exception as e:
-                st.error(f"Failed to get AI feedback: {str(e)}")
+            except RuntimeError as e:
+                st.error(f"Failed to get AI feedback: {e!s}")

465-485: Fix unused timestamp, sanitize filename, and remove empty f‑string.

Use the timestamp, drop emoji for cross‑platform, and avoid f without placeholders.

-        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
@@
-        st.download_button(
+        safe_name = f"interview_feedback_{timestamp}.md"
+        st.download_button(
             label="📥 Download Feedback Report",
             data=markdown_report.encode("utf-8"),
-            file_name=f"interview_feedback_Requirement_Agent😎.md",
+            file_name=safe_name,
             mime="text/markdown",
             key="download_button",
             help="Download the interview report as a Markdown file"
         )
advance_ai_agents/AlgoMentor/src/agents/code_verify.py (1)

32-50: Optional: enforce structured output at the source.

If safe for your flow, consider adding response_model=CodeVerifyInput to code_runner to guarantee parseable output and reduce reformatting burden on code_verify_agent.

advance_ai_agents/ScholarLens/main.py (4)

24-25: Duplicate import.

import streamlit as st appears twice. Drop the second occurrence.

-import streamlit as st

471-473: Overbroad except Exception; include explicit conversion flag.

Catching Exception blindly hides actionable errors; at least log/re-raise known failures (IO/parsing). Also prefer f"{e!s}" over str(e).

-            except Exception as e:
-                st.error(f"❌ Failed to load knowledge base: {e}")
+            except (OSError, ValueError, RuntimeError) as e:
+                st.error(f"❌ Failed to load knowledge base: {e!s}")
+            except Exception as e:
+                st.error("❌ Unexpected error while loading knowledge base.")
+                raise
-                    except Exception as e:
-                        st.markdown(f"""
+                    except (ValueError, RuntimeError) as e:
+                        st.markdown(f"""
                             <div class='warning-message'>
-                                <strong>⚠️ Error:</strong> {str(e)}
+                                <strong>⚠️ Error:</strong> {e!s}
                             </div>
                         """, unsafe_allow_html=True)
+                    except Exception:
+                        st.markdown("""
+                            <div class='warning-message'>
+                                <strong>⚠️ Error:</strong> Unexpected failure. Check logs.
+                            </div>
+                        """, unsafe_allow_html=True)
+                        raise

Also applies to: 528-533


453-466: Nit: session id typo.

session_id="my_chat_sessioin""my_chat_session".

-                    session_id="my_chat_sessioin",
+                    session_id="my_chat_session",

360-364: Guard against missing arXiv index.

index[0] can raise if metadata extraction fails. Add a safe default.

-        arxiv_id = index[0].replace("arXiv:", "").strip()
+        arxiv_id = (index[0].replace("arXiv:", "").strip()) if index else ""
simple_ai_agents/Career_Guidence/temp.py (3)

82-127: Tighten error handling; avoid bare excepts.

The retry path catches Exception broadly and then uses a bare except. Return paths also benefit from an else branch for clarity.

         if self.search_agent:
@@
-            while retry_count < max_retries:
+            while retry_count < max_retries:
                 try:
                     result = self.search_agent.run(query)
@@
-                except Exception as e:
+                except (RuntimeError, ValueError, TimeoutError) as e:
                     last_error = str(e)
                     retry_count += 1
                     time.sleep(2)
@@
-            try:
+            try:
                 prompt = PromptTemplate(
@@
                 result = chain.run(query=query)
@@
-            except:
-                return f"Search failed after {max_retries} attempts. Last error: {last_error}"
+            except Exception:
+                return f"Search failed after {max_retries} attempts. Last error: {last_error}"
         else:
             return "Search unavailable. Please provide a SerpAPI key."

334-350: Remove dead/commented scaffolding and duplicate session init.

Stray comments (not @staticmethod) and duplicate session-state initializers add noise.

-# Initialize session state
-# if 'career_system' not @staticmethod
-# ...existing code...
-# Initialize session state
-if 'career_system' not in st.session_state:
-    st.session_state.career_system = None
@@
-if 'career_system' not in st.session_state:
-    st.session_state.career_system = None
+if 'career_system' not in st.session_state:
+    st.session_state.career_system = None
 if 'career_data' not in st.session_state:
     st.session_state.career_data = None
 if 'chat_history' not in st.session_state:
     st.session_state.chat_history = []

331-333: Use explicit conversion flag in f-string.

Minor lint fix.

-        return f"I encountered an error while processing your question: {str(e)}"
+        return f"I encountered an error while processing your question: {e!s}"
advance_ai_agents/AlgoMentor/src/agents/sub_optimized_agent.py (1)

63-99: Optional: sandbox PythonTools to a temp dir.

Running arbitrary code without a dedicated workspace can pollute CWD. Mirror the temp-dir approach used in code_verify.py.

+import tempfile, atexit, shutil
+_TMP = tempfile.mkdtemp()
+atexit.register(lambda: shutil.rmtree(_TMP, ignore_errors=True))
@@
-    tools=[PythonTools(run_code=True)],
+    tools=[PythonTools(run_code=True, base_dir=_TMP)],
simple_ai_agents/Recruitify/ui.py (6)

430-447: Drop unused loop index and prefer .get over key checks.

Minor cleanups to satisfy lint and simplify.

-            if 'suggestions' in weakness and weakness['suggestions']:
+            if weakness.get('suggestions'):
                 report_content += "\nImprovement suggestions:\n"
-                for i, sugg in enumerate(weakness['suggestions']):
+                for sugg in weakness['suggestions']:
                     report_content += f"- {sugg}\n"

381-393: Use .get for optional fields when rendering weaknesses.

Avoid in + direct index; simplifies and prevents KeyErrors.

-                if 'suggestions' in weakness and weakness['suggestions']:
+                if weakness.get('suggestions'):
@@
-                if 'example' in weakness and weakness['example']:
+                if weakness.get('example'):

519-539: Remove extraneous f‑prefix; string has no placeholders.

Also minor copy nit in the comment.

-                # Create content for download
-                download_content = f"# Recruitment Agent - Interview Questions\n\n"
+                # Create content for download
+                download_content = "# Recruitment Agent - Interview Questions\n\n"

258-303: Optional: close Matplotlib figure to free memory.

Avoid accumulating figures in long sessions.

     fig, ax = plt.subplots(figsize=(4, 4), facecolor='#111111')
@@
-    return fig
+    return fig  # caller should consider plt.close(fig) after st.pyplot(fig)

Or close here after rendering in the caller:

-        st.pyplot(fig)
+        st.pyplot(fig)
+        plt.close(fig)

221-237: Nit: wording.

“custom job description instead” → “Upload custom job description”.

-        upload_jd = st.checkbox("custom job description instead")
+        upload_jd = st.checkbox("Upload custom job description")

642-663: Minor: trim trailing spaces and double spaces in generated MD.

Polish the downloadable resume content.

-                    md_content = f"""# {target_role if target_role else 'Professional'} Resume
+                    md_content = f"""# {target_role if target_role else 'Professional'} Resume
 {improved_resume}
 ---
-Resume enhanced by  Recruitment Agent
+Resume enhanced by Recruitment Agent
 """
simple_ai_agents/Recruitify/app.py (2)

243-249: Fix sidebar key checks and typos; streamline warnings.

Current logic fires duplicate/misleading warnings and contains typos. Gate the Interview path until both keys are present and fix copy.

-        with st.sidebar:
-            groq_api_key=st.text_input("Enter your Groq Api Kyey Here",type='password')
-            deepgram_api_key=st.text_input("Enter your Deepgram Api Key Here",type='password')
-            if not groq_api_key:
-                if not deepgram_api_key:
-                    st.warning("please Enter your Groq  api key !")
-                st.warning("please Enter your Groq And Deepgram api key !")
+        with st.sidebar:
+            groq_api_key = st.text_input("Enter your Groq API Key", type="password")
+            deepgram_api_key = st.text_input("Enter your Deepgram API Key", type="password")
+            if not groq_api_key or not deepgram_api_key:
+                missing = []
+                if not groq_api_key:
+                    missing.append("Groq")
+                if not deepgram_api_key:
+                    missing.append("Deepgram")
+                st.warning(f"Please enter your {', '.join(missing)} API key(s) to continue.")
+                st.stop()

116-118: Narrow blanket except Exception in UI wrappers or at least log details.

Catching all exceptions hides actionable errors from users. Prefer specific exceptions (e.g., ValueError, RuntimeError) or show tracebacks via st.exception(e).

-    except Exception as e:
-        st.error(f"⚠️ Error analyzing resume: {e}")
+    except ValueError as e:
+        st.error(f"⚠️ Invalid input: {e}")
+        st.exception(e)
+    except RuntimeError as e:
+        st.error("⚠️ Runtime error while analyzing resume.")
+        st.exception(e)
+    except Exception as e:
+        st.error("⚠️ Unexpected error while analyzing resume.")
+        st.exception(e)

Apply the same pattern to ask/generate/improve/get calls.

Also applies to: 126-127, 135-137, 144-146, 153-155

simple_ai_agents/Career_Guidence/career_chatbot.py (1)

2-4: Remove unused imports.

numpy as np is unused.

-import numpy as np
advance_ai_agents/AlgoMentor/src/core/app.py (1)

497-499: Narrow blanket exception and surface details.

Show a traceback to aid debugging; keep UX-friendly hint.

-        except Exception as e:
-            st.error(f"❌ An error occurred: {str(e)}")
-            st.info("💡 Try refreshing the page or checking your internet connection.")
+        except ValueError as e:
+            st.error(f"❌ Invalid input: {e}")
+            st.exception(e)
+        except Exception as e:
+            st.error("❌ An unexpected error occurred while generating notes.")
+            st.exception(e)
+            st.info("💡 Try refreshing the page or checking your connection.")
simple_ai_agents/Career_Guidence/career_guidance_system.py (2)

162-164: Avoid bare except; preserve last error.

Bare except swallows real failures.

-            except:
-                return f"Search failed after {max_retries} attempts. Last error: {last_error}"
+            except Exception as e:
+                return f"Search failed after {max_retries} attempts. Last error: {last_error or str(e)}"

630-637: Narrow blanket exception and avoid leaking raw exception text as HTML.

Return a concise message; log details separately upstream if needed.

-        except Exception as e:
-            return f"""
-            <div style="color: #FF5252;">
-                <p>I'm sorry, but I encountered an error while processing your request:</p>
-                <p><code>{str(e)}</code></p>
-                <p>Please try again or contact support if the issue persists.</p>
-            </div>
-            """
+        except Exception as e:
+            return (
+                "<div style='color:#FF5252;'>"
+                "<p>I'm sorry, I ran into an error while processing your request.</p>"
+                "<p>Please try again or contact support if the issue persists.</p>"
+                "</div>"
+            )
simple_ai_agents/Recruitify/agents.py (5)

80-93: Avoid building FAISS index from empty text.

Creating a vector store with no content may error. Provide a minimal placeholder.

 def create_rag_vector_store(self, text):
     """Create a vector store for RAG"""
@@
-    chunks = text_splitter.split_text(text)
+    chunks = text_splitter.split_text(text or "")
+    if not chunks:
+        chunks = [""]
@@
-    vectorstore = FAISS.from_texts(chunks, embeddings)
+    vectorstore = FAISS.from_texts(chunks, embeddings)
     return vectorstore

379-397: Ensure last parsed question is not dropped in fallback parser.

Append trailing buffered question after loop.

         for line in lines:
@@
                 elif current_type and current_question:
                     questions.append((current_type, current_question))
                     current_type = None
                     current_question = ""
 
+        # Append any trailing question
+        if current_type and current_question:
+            questions.append((current_type, current_question))

463-467: Silence unused loop index and simplify dict access.

Minor cleanups.

-                    for i, weakness in enumerate(self.resume_weaknesses):
+                    for i, weakness in enumerate(self.resume_weaknesses):
                         weaknesses_text += f"{i+1}. {weakness['skill']}: {weakness['detail']}\n"
-                        if "suggestions" in weakness:
-                            for j, sugg in enumerate(weakness["suggestions"]):
-                                weaknesses_text += f"   - {sugg}\n"
+                        for _j, sugg in enumerate(weakness.get("suggestions", [])):
+                            weaknesses_text += f"   - {sugg}\n"

551-553: Narrow blanket exception and preserve context.

-        except Exception as e:
-            print(f"Error generating resume improvements: {e}")
+        except Exception as e:
+            print(f"Error generating resume improvements: {e}")
             return {area: {"description": "Error generating suggestions", "specific": []} for area in improvement_areas}

(Consider logging stack traces if available.)


662-664: Avoid blanket exceptions in cleanup paths.

Surface errors for debugging.

-        except Exception as e:
-            print(f"Error cleaning up temporary files: {e}")
+        except FileNotFoundError:
+            pass
+        except Exception as e:
+            print(f"Error cleaning up temporary files: {e}")

Also applies to: 674-675

@@ -0,0 +1,118 @@
```markdown
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

The entire document is inside a fenced code block; remove the outer “```markdown”.

Currently, nothing renders as prose.

-```markdown
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/docs/examples/Edit_distance.md around lines 1 to
1 the whole document is wrapped in a fenced code block labeled "markdown", which
prevents it rendering as prose; remove the opening "```markdown" and the
matching closing "```" (and any stray backticks) so the file is plain markdown
content, leaving the inner markdown intact for normal rendering.

**13. Final Result:**

The final result is the edit distance between the two input strings.
``` No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Close the unintended outer code fence.

Remove the trailing backticks that close the accidental wrapper.

-```
📝 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
```
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/docs/examples/Edit_distance.md around line 118,
there's an unintended closing outer code fence (a line with only triple
backticks) that closes the accidental wrapper; remove that trailing backticks
line so the intended code blocks and surrounding Markdown render correctly.

Comment on lines +21 to +26
* Inorder traversal of the first BST takes O(n) time.
* Inorder traversal of the second BST takes O(m) time.
* Merging the two sorted lists using a heap takes O((n+m)log(n+m)) time, since each insertion and deletion from the heap takes O(log(n+m)) time, and we perform n+m such operations.

Therefore, the overall time complexity is O(n) + O(m) + O((n+m)log(n+m)) which simplifies to O((n+m)log(n+m)).

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Algorithmic inefficiency: heap merge is not optimal here.

Given both inorder traversals yield sorted lists, you can merge in O(n+m) time with two pointers instead of a heap’s O((n+m) log(n+m)). Update the doc to recommend the linear merge and adjust complexity.

Suggested replacement text:

  • Approach Summary: “…perform inorder on both BSTs to get two sorted lists, then merge them via a two‑pointer linear pass.”
  • Time Complexity: “O(n + m).”
  • Space: unchanged for lists; no heap required.
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/docs/examples/MergeBst.md around lines 21 to 26,
the doc uses a heap to merge two sorted inorder lists which yields
O((n+m)log(n+m)) time; replace that with a two‑pointer linear merge and update
the description and complexity accordingly: change the approach summary to state
that after inorder traversals you merge the two sorted lists via a two‑pointer
linear pass, remove the heap-based merge text, and update time complexity to O(n
+ m) while leaving space usage for the two lists unchanged.

Comment on lines +4 to +5
__import__('pysqlite3')
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3') No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

❓ Verification inconclusive

Avoid popping pysqlite3; alias both sqlite3 and sqlite3.dbapi2 with ImportError fallback.

sys.modules.pop('pysqlite3') can break direct imports later; also sqlite3.dbapi2 remains unaliased. Add a safe, idempotent patch.

-__import__('pysqlite3')
-sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
+try:
+    import pysqlite3  # noqa: F401
+except ImportError:
+    # Fall back to stdlib sqlite3 if pysqlite3 isn't present
+    pass
+else:
+    # Alias both the top-level module and dbapi2 for full compatibility
+    sys.modules['sqlite3'] = pysqlite3
+    if hasattr(pysqlite3, 'dbapi2'):
+        sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2

If multiple apps import different patchers, consider centralizing this utility to avoid divergent behavior.


Don't pop pysqlite3 — alias sqlite3 and sqlite3.dbapi2 with ImportError fallback.

File: advance_ai_agents/AlgoMentor/patch_sqlite.py — lines 4–5

Popping pysqlite3 removes it from sys.modules and can break later imports; also alias sqlite3.dbapi2 for compatibility. Replace the snippet with:

-__import__('pysqlite3')
-sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
+try:
+    import pysqlite3  # noqa: F401
+except ImportError:
+    # Fall back to stdlib sqlite3 if pysqlite3 isn't present
+    pass
+else:
+    # Alias both the top-level module and dbapi2 for full compatibility
+    sys.modules['sqlite3'] = pysqlite3
+    if hasattr(pysqlite3, 'dbapi2'):
+        sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2
📝 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
__import__('pysqlite3')
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
try:
import pysqlite3 # noqa: F401
except ImportError:
# Fall back to stdlib sqlite3 if pysqlite3 isn't present
pass
else:
# Alias both the top-level module and dbapi2 for full compatibility
sys.modules['sqlite3'] = pysqlite3
if hasattr(pysqlite3, 'dbapi2'):
sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/patch_sqlite.py around lines 4 to 5, the current
code pops 'pysqlite3' from sys.modules which can break later imports; instead,
import pysqlite3 safely and alias it to 'sqlite3' without removing the original
entry, and also ensure the dbapi2 attribute is available for compatibility;
implement this by trying to import pysqlite3, on success assign it to
sys.modules['pysqlite3'] and set sys.modules['sqlite3'] =
sys.modules.get('sqlite3', pysqlite3_module) and set
sys.modules['sqlite3'].dbapi2 = getattr(pysqlite3_module, 'dbapi2',
pysqlite3_module), and on ImportError fall back to a normal import of the stdlib
sqlite3.

Comment on lines +13 to +17
groq_api_key=st.secrets['GROQ_API_KEY']
google_api_key=st.secrets['GOOGLE_API_KEY']
# groq_api_key=os.getenv('GROQ_API_KEY')
# google_api_key=os.getenv('GOOGLE_API_KEY')

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add secret fallback and clear error if missing.

-groq_api_key=st.secrets['GROQ_API_KEY']
-google_api_key=st.secrets['GOOGLE_API_KEY']
+groq_api_key = st.secrets.get('GROQ_API_KEY') or os.getenv('GROQ_API_KEY')
+google_api_key = st.secrets.get('GOOGLE_API_KEY') or os.getenv('GOOGLE_API_KEY')
+if not groq_api_key or not google_api_key:
+    raise RuntimeError("Missing GROQ_API_KEY or GOOGLE_API_KEY.")
📝 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
groq_api_key=st.secrets['GROQ_API_KEY']
google_api_key=st.secrets['GOOGLE_API_KEY']
# groq_api_key=os.getenv('GROQ_API_KEY')
# google_api_key=os.getenv('GOOGLE_API_KEY')
groq_api_key = st.secrets.get('GROQ_API_KEY') or os.getenv('GROQ_API_KEY')
google_api_key = st.secrets.get('GOOGLE_API_KEY') or os.getenv('GOOGLE_API_KEY')
if not groq_api_key or not google_api_key:
raise RuntimeError("Missing GROQ_API_KEY or GOOGLE_API_KEY.")
# groq_api_key=os.getenv('GROQ_API_KEY')
# google_api_key=os.getenv('GOOGLE_API_KEY')
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/src/agents/brute_force.py around lines 13 to 17,
the API keys are currently read only from Streamlit secrets; update the code to
fallback to environment variables when secrets keys are not present and
raise/exit with a clear error if neither source provides the required key.
Specifically, attempt to read st.secrets['GROQ_API_KEY'] and
st.secrets['GOOGLE_API_KEY'] first, then fall back to os.getenv('GROQ_API_KEY')
/ os.getenv('GOOGLE_API_KEY'); if either final value is missing, raise a
descriptive RuntimeError or call sys.exit with a message indicating which key is
missing so the failure is explicit.

Comment on lines +34 to +45
"from serpapi import GoogleSearch\n",
"\n",
"params = {\n",
" \"engine\": \"youtube\",\n",
" \"search_query\": \" transfer learning\",\n",
" \"api_key\": \"4e047a5fd074fad841b22448b42297f0a14ae6118f6e69aa17ec73199086483f\"\n",
"}\n",
"\n",
"search = GoogleSearch(params)\n",
"\n",
"results = search.get_dict()"
]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Hardcoded SerpAPI key committed; rotate and purge immediately.

A real-looking API key is in the notebook. This is a critical secret leak. Revoke/rotate the key now, purge the secret from git history, and switch to environment/secrets-based loading.

Immediate code fix for the cell:

-from serpapi import GoogleSearch
-
-params = {
-  "engine": "youtube",
-  "search_query": " transfer learning",
-  "api_key": "4e047a5fd074fad841b22448b42297f0a14ae6118f6e69aa17ec73199086483f"
-}
+from serpapi import GoogleSearch
+import os
+
+SERPAPI_API_KEY = os.getenv("SERPAPI_API_KEY")
+assert SERPAPI_API_KEY, "Missing SERPAPI_API_KEY"
+params = {
+  "engine": "youtube",
+  "search_query": "transfer learning",
+  "api_key": SERPAPI_API_KEY,
+}

Follow-up actions:

  • Revoke the exposed key in SerpAPI.
  • Purge history: use git filter-repo (preferred) or BFG to remove the secret from all commits/branches, then force-push.
  • Add a secrets scanning pre-commit (e.g., gitleaks) to prevent regressions.

🏁 Script executed:

#!/bin/bash
# Scan repo for suspicious key patterns (read-only)
rg -nPI --hidden --glob '!*node_modules/*' '(api_key\s*[:=]\s*["\'][A-Za-z0-9_\-]{20,}["\']|AIza[0-9A-Za-z_\-]{35}|sk-[A-Za-z0-9]{20,})' -C2

Length of output: 68


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Scanning repository for SerpAPI key / hardcoded api_key..."

# 1) Look for the known key prefix (safe fixed substring search)
KEY_PREFIX="4e047a5fd074fad8"
echo "Searching for literal prefix: $KEY_PREFIX"
rg -n --hidden -F "$KEY_PREFIX" -C2 || echo "No literal prefix matches found."

# 2) Search for common markers (api_key, serpapi, GoogleSearch) with context
echo "Searching for 'api_key', 'serpapi', 'SERPAPI', 'GoogleSearch' across repo (context=2)..."
rg -n --hidden -S -C2 'api_key|serpapi|SERPAPI|GoogleSearch' || echo "No matches for those keywords."

# 3) If the specific notebook exists, extract and print its code cells for confirmation
NOTEBOOK="simple_ai_agents/Career_Guidence/demo.ipynb"
if [ -f "$NOTEBOOK" ]; then
  echo "Found $NOTEBOOK — extracting code cells (joined)."
  jq -r '.cells | to_entries[] | select(.value.cell_type=="code") | ("==CELL "+(.key|tostring)+"==") , (.value.source | join(""))' "$NOTEBOOK" || true
else
  echo "$NOTEBOOK not found locally; listing all .ipynb files found:"
  rg --hidden --files -g '**/*.ipynb' || true
fi

# 4) Repo-wide: scan every .ipynb code cell for 'api_key' or 'serpapi' hits
echo "Scanning all .ipynb code cells for 'api_key' / 'serpapi' occurrences:"
for f in $(rg --hidden --files -g '**/*.ipynb' || true); do
  echo "---- $f ----"
  jq -r '.cells | to_entries[] | select(.value.cell_type=="code") | .value.source | join("")' "$f" | nl -ba -v1 -w4 | rg -n 'api_key|SERPAPI|serpapi|GoogleSearch' -n -C2 || true
done

echo "Scan complete."

Length of output: 183535


Hardcoded SerpAPI key committed — revoke & purge immediately.

Confirmed plaintext SerpAPI API key in simple_ai_agents/Career_Guidence/demo.ipynb (code cell, ~line 39).

Immediate code fix for the cell:

-from serpapi import GoogleSearch
-
-params = {
-  "engine": "youtube",
-  "search_query": " transfer learning",
-  "api_key": "4e047a5fd074fad841b22448b42297f0a14ae6118f6e69aa17ec73199086483f"
-}
+from serpapi import GoogleSearch
+import os
+
+SERPAPI_API_KEY = os.getenv("SERPAPI_API_KEY")
+assert SERPAPI_API_KEY, "Missing SERPAPI_API_KEY"
+params = {
+  "engine": "youtube",
+  "search_query": "transfer learning",
+  "api_key": SERPAPI_API_KEY,
+}

Follow-up actions:

  • Revoke the exposed key in SerpAPI immediately and issue a new key.
  • Purge the secret from git history (git filter-repo preferred, or BFG), force-push all affected branches, and rotate any systems that used the key.
  • Add secrets scanning (e.g., gitleaks or pre-commit hooks) and CI checks to block future commits with secrets.
📝 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
"from serpapi import GoogleSearch\n",
"\n",
"params = {\n",
" \"engine\": \"youtube\",\n",
" \"search_query\": \" transfer learning\",\n",
" \"api_key\": \"4e047a5fd074fad841b22448b42297f0a14ae6118f6e69aa17ec73199086483f\"\n",
"}\n",
"\n",
"search = GoogleSearch(params)\n",
"\n",
"results = search.get_dict()"
]
from serpapi import GoogleSearch
import os
SERPAPI_API_KEY = os.getenv("SERPAPI_API_KEY")
assert SERPAPI_API_KEY, "Missing SERPAPI_API_KEY"
params = {
"engine": "youtube",
"search_query": "transfer learning",
"api_key": SERPAPI_API_KEY,
}
search = GoogleSearch(params)
results = search.get_dict()
🤖 Prompt for AI Agents
In simple_ai_agents/Career_Guidence/demo.ipynb around lines 34 to 45, a
plaintext SerpAPI key was committed; remove the hardcoded key from the notebook
and replace it with a runtime secret retrieval (e.g., read from an environment
variable or a secrets manager) so the params dict uses the env/secret value
instead of a literal string, then save and commit the cleaned notebook;
additionally, revoke the exposed SerpAPI key immediately, generate a new key,
purge the secret from git history using git-filter-repo or BFG and force-push
affected branches, and add secrets scanning (pre-commit hook like
detect-secrets/gitleaks or CI checks) to prevent future commits.

Comment on lines +226 to +235
def semantic_skill_analysis(self, resume_text, skills):
"""Analyze skills semantically"""
vectorstore = self.create_vector_store(resume_text)
retriever = vectorstore.as_retriever()
qa_chain = RetrievalQA.from_chain_type(
llm=ChatGoogleGenerativeAI(model='gemini-2.0-flash',google_api_key=self.api_key),
retriever=retriever,
return_source_documents=False
)

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle empty skills to avoid division by zero.

When JD parsing fails, skills may be empty.

     def semantic_skill_analysis(self, resume_text, skills):
         """Analyze skills semantically"""
+        if not skills:
+            return {
+                "overall_score": 0,
+                "skill_scores": {},
+                "skill_reasoning": {},
+                "selected": False,
+                "reasoning": "No skills extracted from JD/role requirements.",
+                "missing_skills": [],
+                "strengths": [],
+                "improvement_areas": []
+            }
📝 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 semantic_skill_analysis(self, resume_text, skills):
"""Analyze skills semantically"""
vectorstore = self.create_vector_store(resume_text)
retriever = vectorstore.as_retriever()
qa_chain = RetrievalQA.from_chain_type(
llm=ChatGoogleGenerativeAI(model='gemini-2.0-flash',google_api_key=self.api_key),
retriever=retriever,
return_source_documents=False
)
def semantic_skill_analysis(self, resume_text, skills):
"""Analyze skills semantically"""
if not skills:
return {
"overall_score": 0,
"skill_scores": {},
"skill_reasoning": {},
"selected": False,
"reasoning": "No skills extracted from JD/role requirements.",
"missing_skills": [],
"strengths": [],
"improvement_areas": []
}
vectorstore = self.create_vector_store(resume_text)
retriever = vectorstore.as_retriever()
qa_chain = RetrievalQA.from_chain_type(
llm=ChatGoogleGenerativeAI(model='gemini-2.0-flash',google_api_key=self.api_key),
retriever=retriever,
return_source_documents=False
)
🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/agents.py around lines 226 to 235, the method
semantic_skill_analysis can receive an empty skills list (e.g., when JD parsing
fails) which may lead to a division-by-zero or other downstream errors; add an
early guard that checks if not skills (or len(skills) == 0) and handle it by
returning a sensible default (e.g., an empty analysis result or None) before
creating the vector store or invoking the QA chain, or alternatively raise a
specific ValueError with a clear message; ensure callers of this method can
handle the chosen return/exception.

Comment on lines +4 to +5
__import__('pysqlite3')
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3') No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Same patching concerns as AlgoMentor: don’t pop the module; alias dbapi2; handle ImportError.

Mirrors the earlier file. Apply the same safer pattern.

-__import__('pysqlite3')
-sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
+try:
+    import pysqlite3  # noqa: F401
+except ImportError:
+    pass
+else:
+    sys.modules['sqlite3'] = pysqlite3
+    if hasattr(pysqlite3, 'dbapi2'):
+        sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2

Ensure pysqlite3-binary is listed in this app’s requirements and that no module imports sqlite3 before this patch runs.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo

echo "1) Locate patch_sqlite.py files"
FILES=$(fd -HI -e py 'patch_sqlite.py' || true)
if [ -z "$FILES" ]; then
  echo "NO patch_sqlite.py files found"
else
  for f in $FILES; do
    echo "=== FILE: $f ==="
    sed -n '1,240p' "$f" || true
    echo
  done
fi

echo "2) Search for pysqlite3/pysqlite3-binary in repo"
rg -n --hidden -S "pysqlite3(-binary)?\b" -g '!**/node_modules/**' -C2 || true

echo "3) Check common packaging/requirements files for pysqlite3"
for f in requirements.txt pyproject.toml setup.cfg Pipfile poetry.lock; do
  if [ -f "$f" ]; then
    echo "=== $f ==="
    sed -n '1,240p' "$f"
    echo
  fi
done
if [ -d "requirements" ]; then
  for f in requirements/*.txt; do
    [ -f "$f" ] || continue
    echo "=== $f ==="
    sed -n '1,240p' "$f"
    echo
  done
fi

echo "4) Search for direct imports of sqlite3"
rg -n --hidden -S "^\s*(from\s+sqlite3\s+import|import\s+sqlite3\b)" -g '!**/node_modules/**' -C2 || true

echo "5) Search for any sqlite3 references"
rg -n --hidden -S "\bsqlite3\b" -g '!**/node_modules/**' -C2 || true

echo "6) Search for sys.modules sqlite3 patching elsewhere"
rg -n --hidden -S "sys\.modules\[['\"]sqlite3['\"]\]" -g '!**/node_modules/**' -C2 || true

echo "7) Search for patch_sqlite references/imports"
rg -n --hidden -S "patch_sqlite" -g '!**/node_modules/**' -C2 || true

echo "8) Show package __init__ files (first 200 lines) to see top-level imports"
INIT_FILES=$(fd -HI -e py '__init__.py' || true)
if [ -z "$INIT_FILES" ]; then
  echo "NO __init__.py files found"
else
  for f in $INIT_FILES; do
    echo "=== INIT: $f ==="
    sed -n '1,200p' "$f" || true
    echo
  done
fi

echo "9) Print python files that import sqlite3 at top-level (heuristic: import sqlite3 within first 20 lines)"
rg -n --hidden -S "^\s*(from\s+sqlite3\s+import|import\s+sqlite3\b)" -g '!**/node_modules/**' -C0 | awk -F: '{print $1}' | sort -u || true

Length of output: 5939


Don't pop pysqlite3 — alias safely, handle ImportError, and expose dbapi2.

Apply the safer pattern to these files:

  • advance_ai_agents/AlgoMentor/patch_sqlite.py
  • advance_ai_agents/ScholarLens/patch_sqlite.py
  • simple_ai_agents/Recruitify/patch_sqlite.py
-__import__('pysqlite3')
-sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
+try:
+    import pysqlite3  # noqa: F401
+except ImportError:
+    pass
+else:
+    sys.modules['sqlite3'] = pysqlite3
+    if hasattr(pysqlite3, 'dbapi2'):
+        sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2

Verify that pysqlite3-binary is declared in the project's dependencies (requirements/pyproject) and that no module imports sqlite3 before this patch runs.

📝 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
__import__('pysqlite3')
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
try:
import pysqlite3 # noqa: F401
except ImportError:
pass
else:
sys.modules['sqlite3'] = pysqlite3
if hasattr(pysqlite3, 'dbapi2'):
sys.modules['sqlite3.dbapi2'] = pysqlite3.dbapi2
🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/patch_sqlite.py around lines 4-5 (and apply same
change to advance_ai_agents/AlgoMentor/patch_sqlite.py and
advance_ai_agents/ScholarLens/patch_sqlite.py), replace the unsafe pop pattern
with a safe alias: try importing pysqlite3 and if successful assign it into
sys.modules['sqlite3'] and also expose its .dbapi2 as
sys.modules['sqlite3.dbapi2'] or set sqlite3 = pysqlite3.dbapi2 for callers;
catch ImportError and re-raise a clear error if pysqlite3 is missing; do not
remove or pop entries from sys.modules to avoid breaking other importers;
finally verify that pysqlite3-binary is declared in project dependencies
(requirements/pyproject) and ensure no module imports sqlite3 before these
patches run.

Comment on lines +33 to +34
# deepgram = DeepgramClient(api_key="37c16f3a101aad2918c257d802f21f1843a9f683")

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Hardcoded Deepgram API key in file (even if commented). Rotate and purge.

Secrets in comments still leak. Revoke/rotate the key, purge from git history, and load via env/secrets.

Apply this diff to remove the key immediately:

-#     deepgram = DeepgramClient(api_key="37c16f3a101aad2918c257d802f21f1843a9f683")
+#     deepgram = DeepgramClient(api_key=os.getenv("DEEPGRAM_API_KEY"))

Follow-up:

  • Purge with git filter-repo/BFG and force-push.
  • Add gitleaks pre-commit.

🏁 Script executed:

#!/bin/bash
# Confirm no remaining Deepgram/SerpAPI leaks
rg -nPI '(DEEPGRAM_API_KEY|SerpApi|serpapi|google-search-results|[A-Fa-f0-9]{32,})' -C2

Length of output: 39710


Hardcoded Deepgram API key found — rotate & purge immediately

Confirmed: simple_ai_agents/Recruitify/temp/practise.py contains a commented hardcoded Deepgram key (line ~33). Scan also revealed an exposed SerpAPI key in sample/notebook code (value starts with "4e047a5f..."). Remove hardcoded keys, rotate credentials, and purge history.

Apply this diff to remove the Deepgram key immediately:

-#     deepgram = DeepgramClient(api_key="37c16f3a101aad2918c257d802f21f1843a9f683")
+#     deepgram = DeepgramClient(api_key=os.getenv("DEEPGRAM_API_KEY"))

Actions:

  • Revoke/rotate the Deepgram and SerpAPI keys now.
  • Purge secrets from git history (git filter-repo or BFG) and force-push.
  • Add gitleaks (or equivalent) as a pre-commit check and run a full repo scan to confirm no remaining secrets.
📝 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
# deepgram = DeepgramClient(api_key="37c16f3a101aad2918c257d802f21f1843a9f683")
# deepgram = DeepgramClient(api_key=os.getenv("DEEPGRAM_API_KEY"))
🧰 Tools
🪛 Gitleaks (8.27.2)

[high] 33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/temp/practise.py around lines 33-34, there is a
commented hardcoded Deepgram API key that must be removed; delete the commented
key line, revoke/rotate the Deepgram key immediately, and purge any occurrence
from git history (use git filter-repo or BFG and force-push). Also locate and
remove the exposed SerpAPI key found in sample/notebook code, rotate/revoke that
key, and purge it from history as well. After purging, add a secrets scanner
(gitleaks or equivalent) as a pre-commit hook and run a full repo scan to
confirm no remaining secrets before pushing.

Comment on lines +39 to +41
# # Deepgram API Key (replace with env variable for security)
# DEEPGRAM_API_KEY = "37c16f3a101aad2918c257d802f21f1843a9f683"

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Remove hardcoded API key (even if commented); rotate if real.

Secrets must not appear in source control. Load from env or Streamlit secrets.

-# # Deepgram API Key (replace with env variable for security)
-# DEEPGRAM_API_KEY = "37c16f3a101aad2918c257d802f21f1843a9f683"
+# # Deepgram API Key
+# DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY")  # or: st.secrets["DEEPGRAM_API_KEY"]

🏁 Script executed:

#!/bin/bash
# Find any leaked keys or tokens across the repo (adjust patterns as needed)
rg -nPI '(apikey|api_key|authorization|secret|token)\s*[:=]\s*["\'][A-Za-z0-9_\-]{20,}["\']' -g '!**/node_modules/**' -g '!**/.git/**'

Length of output: 68


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Searching for exact Deepgram key, explicit DEEPGRAM_API_KEY occurrences, and other likely hardcoded secrets..."
# 1) exact key search (from review)
rg -n --hidden -S -g '!**/node_modules/**' -g '!**/.git/**' '37c16f3a101aad2918c257d802f21f1843a9f683' || true
# 2) variable name occurrences
rg -n --hidden -S -g '!**/node_modules/**' -g '!**/.git/**' '\b(DEEPGRAM_API_KEY|DEEPGRAM_KEY|DEEPGRAM)\b' || true
# 3) broad scan for common secret variable names (may produce false positives)
rg -n --hidden -S -g '!**/node_modules/**' -g '!**/.git/**' '\b(api[_-]?key|apikey|api_key|authorization|bearer|token|secret|password|passwd)\b' || true
# 4) fallback Python scan for assignments to quoted long strings (>=20 chars)
python - <<'PY'
import re, os
root='.'
skip_dirs={'.git','node_modules'}
assign_re=re.compile(r'\b(?:DEEPGRAM_API_KEY|DEEPGRAM_KEY|api[_-]?key|apikey|api_key|authorization|bearer|token|secret|password|passwd)\b\s*[:=]\s*["\']([A-Za-z0-9_\-]{10,})["\']', re.I)
longq_re=re.compile(r'["\']([A-Za-z0-9_\-]{20,})["\']')
for dirpath, dirs, files in os.walk(root):
    dirs[:] = [d for d in dirs if d not in skip_dirs]
    for fname in files:
        path = os.path.join(dirpath, fname)
        try:
            with open(path, 'r', errors='ignore') as fh:
                for i, line in enumerate(fh, 1):
                    if assign_re.search(line):
                        print(f'{path}:{i}:ASSIGN:{line.strip()}')
                    elif longq_re.search(line):
                        print(f'{path}:{i}:LONG_QUOTED:{line.strip()}')
        except Exception:
            continue
PY

Length of output: 43137


Remove hardcoded Deepgram API key(s); rotate if real.

Commented Deepgram key present in the repo — remove the literal, load from env / st.secrets, and rotate the key if it was active.

Locations:

  • simple_ai_agents/Recruitify/temp/stt.py: line 40
  • simple_ai_agents/Recruitify/temp/practise.py: line 33
-# # Deepgram API Key (replace with env variable for security)
-# DEEPGRAM_API_KEY = "37c16f3a101aad2918c257d802f21f1843a9f683"
+# # Deepgram API Key
+# DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY")  # or: st.secrets["DEEPGRAM_API_KEY"]
📝 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
# # Deepgram API Key (replace with env variable for security)
# DEEPGRAM_API_KEY = "37c16f3a101aad2918c257d802f21f1843a9f683"
# # Deepgram API Key
# DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY") # or: st.secrets["DEEPGRAM_API_KEY"]
🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/temp/stt.py around line 39-41 and
simple_ai_agents/Recruitify/temp/practise.py around line 33, there are commented
hardcoded Deepgram API keys that must be removed and rotated if active; delete
the literal keys from the files, replace usage to read the API key from a secure
source (e.g., environment variable or streamlit secrets like
os.environ['DEEPGRAM_API_KEY'] or st.secrets['DEEPGRAM_API_KEY']), and ensure
any running/committed key is rotated in the Deepgram dashboard and credentials
updated accordingly.

Copy link
Contributor

@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.

Review continued from previous batch...

Comment on lines +476 to +481
# api_key = os.getenv('GOOGLE_API_KEY')
api_key = st.secrets['GOOGLE_API_KEY']
if not api_key:
st.error("🔑 Google API key not found. Please check your .env file.")
return

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Prevent KeyError for secrets; allow env fallback.

st.secrets['GOOGLE_API_KEY'] will raise if missing. Use .get(...) or os.getenv(...).

-# api_key = os.getenv('GOOGLE_API_KEY')
-api_key = st.secrets['GOOGLE_API_KEY']
-if not api_key:
+api_key = st.secrets.get('GOOGLE_API_KEY') or os.getenv('GOOGLE_API_KEY')
+if not api_key:
     st.error("🔑 Google API key not found. Please check your .env file.")
     return
📝 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
# api_key = os.getenv('GOOGLE_API_KEY')
api_key = st.secrets['GOOGLE_API_KEY']
if not api_key:
st.error("🔑 Google API key not found. Please check your .env file.")
return
api_key = st.secrets.get('GOOGLE_API_KEY') or os.getenv('GOOGLE_API_KEY')
if not api_key:
st.error("🔑 Google API key not found. Please check your .env file.")
return
🤖 Prompt for AI Agents
In advance_ai_agents/AlgoMentor/src/core/app.py around lines 476 to 481, using
st.secrets['GOOGLE_API_KEY'] can raise a KeyError if the secret is missing;
change to safely read the key using st.secrets.get('GOOGLE_API_KEY') with a
fallback to os.getenv('GOOGLE_API_KEY') (or vice versa), assign the result to
api_key, then check if api_key is falsy and call st.error and return as before
so missing keys are handled without exceptions.

Comment on lines +51 to +52
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Pass API key to embeddings to prevent runtime failure.

Without this, embedding calls will fail with “No API key found”.

-embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
+embeddings = GoogleGenerativeAIEmbeddings(
+    model="models/embedding-001",
+    google_api_key=GOOGLE_API_KEY
+)
📝 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
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
embeddings = GoogleGenerativeAIEmbeddings(
model="models/embedding-001",
google_api_key=GOOGLE_API_KEY
)
🤖 Prompt for AI Agents
In simple_ai_agents/Career_Guidence/career_chatbot.py around lines 51-52,
embeddings are instantiated without passing the required API key which causes
runtime failures; obtain the Google Generative AI API key (e.g., from
environment variable or your config) and pass it into
GoogleGenerativeAIEmbeddings (or set the provider-specific key via the library's
expected parameter) when constructing embeddings so the library can authenticate
successfully.

Comment on lines +614 to +629
response = self.llm.chat(
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_query}
]
)

answer = response.content

# Ensure the response is properly formatted as HTML
if "<" not in answer:
# If no HTML tags are present, add basic formatting
answer = f"<div><p>{answer}</p></div>"

return answer

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use LangChain call style; ChatGroq.chat(...) is not a standard API.

Switch to invoke or an LLMChain. This prevents runtime AttributeError.

-            response = self.llm.chat(
-                messages=[
-                    {"role": "system", "content": system_prompt},
-                    {"role": "user", "content": user_query}
-                ]
-            )
-            
-            answer = response.content
+            prompt = f"{system_prompt}\n\nUser Question:\n{user_query}"
+            response = self.llm.invoke(prompt)
+            answer = getattr(response, "content", str(response))
📝 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
response = self.llm.chat(
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_query}
]
)
answer = response.content
# Ensure the response is properly formatted as HTML
if "<" not in answer:
# If no HTML tags are present, add basic formatting
answer = f"<div><p>{answer}</p></div>"
return answer
prompt = f"{system_prompt}\n\nUser Question:\n{user_query}"
response = self.llm.invoke(prompt)
answer = getattr(response, "content", str(response))
# Ensure the response is properly formatted as HTML
if "<" not in answer:
# If no HTML tags are present, add basic formatting
answer = f"<div><p>{answer}</p></div>"
return answer
🧰 Tools
🪛 Ruff (0.12.2)

628-628: Consider moving this statement to an else block

(TRY300)

🤖 Prompt for AI Agents
In simple_ai_agents/Career_Guidence/career_guidance_system.py around lines
614-629, replace the non-standard self.llm.chat(...) call with a
LangChain-compatible call (either use the LLM.invoke({ "input": user_query })
API or create an LLMChain/PromptTemplate and call chain.run(user_query));
extract the returned text from the LangChain response object (e.g., the returned
text field or chain.run result) into answer, then perform the existing
HTML-wrapping check and return answer. Ensure you remove any references to
ChatGroq.chat to avoid AttributeError.

Comment on lines +44 to +49
text = ""
for page in reader.pages:
text += page.extract_text()

return text
except Exception as e:
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Guard against None from PyPDF2 extract_text().

page.extract_text() can return None, causing TypeError on concatenation.

-            text = ""
-            for page in reader.pages:
-                text += page.extract_text()
+            text = ""
+            for page in reader.pages:
+                page_text = page.extract_text() or ""
+                text += page_text
📝 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
text = ""
for page in reader.pages:
text += page.extract_text()
return text
except Exception as e:
text = ""
for page in reader.pages:
page_text = page.extract_text() or ""
text += page_text
return text
except Exception as e:
🧰 Tools
🪛 Ruff (0.12.2)

48-48: Consider moving this statement to an else block

(TRY300)


49-49: Do not catch blind exception: Exception

(BLE001)

🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/agents.py around lines 44 to 49, the code
concatenates page.extract_text() directly which can be None and cause a
TypeError; change the loop to treat None as an empty string (e.g., use a
conditional or coalescing to default to ""), or accumulate using a list and join
only non-None strings so concatenation never receives None; ensure any
whitespace or page breaks are handled as needed before returning the final text.

Comment on lines +201 to +206
try:
skills_list = eval(skills_text)
if isinstance(skills_list, list):
return skills_list
except:
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace eval with ast.literal_eval for safety.

eval on model output is unsafe. Use ast.literal_eval.

+import ast
@@
-            try:
-                skills_list = eval(skills_text)
+            try:
+                skills_list = ast.literal_eval(skills_text)
                 if isinstance(skills_list, list):
                     return skills_list
-            except:
-                pass
+            except (ValueError, SyntaxError):
+                pass
🧰 Tools
🪛 Ruff (0.12.2)

202-202: Use of possibly insecure function; consider using ast.literal_eval

(S307)


205-205: Do not use bare except

(E722)


205-206: try-except-pass detected, consider logging the exception

(S110)

🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/agents.py around lines 201 to 206, the code uses
eval(skills_text) which is unsafe; replace it with ast.literal_eval(skills_text)
to safely parse only Python literals, add "import ast" at the top of the file,
and replace the bare except with explicit exception handling (catch ValueError
and SyntaxError) so malformed model output is handled without swallowing
unrelated errors; keep the existing check for isinstance(skills_list, list) and
return it when valid.

Comment on lines +251 to +253
if groq_api_key and deepgram_api_key:
interviewAssistant=Interview(groq_api_key,deepgram_api_key)
interviewAssistant.run()
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Validate ChatGroq API kwarg usage in Interview class.

In simple_ai_agents/Recruitify/interview.py, ChatGroq(..., api_key=...) is likely incorrect; LangChain ChatGroq expects groq_api_key=.... Please confirm and fix downstream to avoid auth failures.


🏁 Script executed:

#!/bin/bash
# Find ChatGroq initializations and show keyword args
rg -n -C2 '\bChatGroq\s*\(' --type=py

Length of output: 3205


Fix ChatGroq kwarg: use groq_api_key (Python) not api_key.

LangChain's Python ChatGroq uses the GROQ_API_KEY env var or the groq_api_key kwarg — passing api_key will not set the Groq credential and can cause auth failures. (python.langchain.com)

  • simple_ai_agents/Recruitify/interview.py (≈line 200): change ChatGroq(..., api_key=self.GROQ_API_KEY) → ChatGroq(..., groq_api_key=self.GROQ_API_KEY)
  • advance_ai_agents/ScholarLens/comparision/ComparePapers.py (≈line 19): change ChatGroq(..., api_key=GROQ_API_KEY) → ChatGroq(..., groq_api_key=GROQ_API_KEY)
  • (Optional) update commented examples in simple_ai_agents/Recruitify/temp/practise.py to avoid confusion.
🤖 Prompt for AI Agents
In simple_ai_agents/Recruitify/app.py around lines 251-253 and in
simple_ai_agents/Recruitify/interview.py around line ~200 (and
advance_ai_agents/ScholarLens/comparision/ComparePapers.py around line ~19), the
ChatGroq client is being instantiated with the wrong kwarg name (api_key) which
doesn't set the Groq credential; change the instantiations to use
groq_api_key=self.GROQ_API_KEY (or groq_api_key=GROQ_API_KEY) respectively so
LangChain picks up the correct credential; also update any commented examples in
simple_ai_agents/Recruitify/temp/practise.py to use groq_api_key to avoid
confusion.

@Arindam200
Copy link
Owner

Hey @ankush0511,

Could you please create separate PRs for each project?
Also, stick to the folder naming convention: use algo_mentor_agent instead of AlgoMentor.
Starter_agents are for framework starters. You can add your projects under simple_ai_agents.

One more thing: can you try using Nebius AI models?

Thanks!

@shivaycb
Copy link
Contributor

Please accept what @Arindam200 is asking for

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants