Skip to content

Sprint2/prompt design v1 2.3#8

Open
usha-sj wants to merge 4 commits intomainfrom
sprint2/prompt-design-v1-2.3
Open

Sprint2/prompt design v1 2.3#8
usha-sj wants to merge 4 commits intomainfrom
sprint2/prompt-design-v1-2.3

Conversation

@usha-sj
Copy link
Collaborator

@usha-sj usha-sj commented Feb 8, 2026

Feature (PromptV1): Centralized study generation prompt system SOC-2.3

🎉 New feature (Extends backend architecture, non-breaking feature)


PR Summary

Adds a centralized, versioned prompt system for AI study generation.
The Gemini prompt is moved out of main.py into a dedicated module with strict JSON enforcement and few-shot examples to improve reliability without changing the API contract.


Overview

What feature/problem does this PR address?

  • Hardcoded prompt in main.py hard to maintain
  • AI output inconsistencies could break JSON parsing
  • No structure for prompt versioning or iteration

What approach was taken?

  • Created prompts/study_gen_v1.py as the single source of truth
  • Added build_study_generation_prompt() to construct prompts
  • Enforced strict JSON schema matching the API contract
  • Added few-shot examples to stabilize Gemini output
  • Wired endpoint to use the prompt builder

Important design decisions / trade-offs

  • Prompt is versioned (v1) to allow safe future upgrades
  • JSON schema is frozen to preserve frontend compatibility
  • Few-shot examples increase tokens but improve consistency (can be set to False when called in main.py)

Files Changed

File Action Description
backend/prompts/study_gen_v1.py Created Centralized prompt system (v1)
backend/main.py Modified Uses prompt builder instead of inline prompt
backend/README.md Modified Documents prompt architecture

Test Cases / Edge Cases

  • Empty notes rejected by request validator
  • Invalid AI JSON returns safe 500 error
  • Markdown-wrapped AI output cleaned and parsed
  • Quiz quality issues logged (non-blocking)

Checklist

  • Added a clear description
  • Documented edge cases
  • Updated backend documentation
  • Preserved API contract

Additional Notes

  • No frontend changes
  • No API schema changes
  • Future upgrades should create study_gen_v2.py instead of modifying v1
  • Hardcoded prompt is still there just in case, but I commented it out for now. Should probably delete.

Jira Ticket

Jira Ticket(s) - [SOC-2.3]

@usha-sj usha-sj requested review from Arhum2 and alextgu February 8, 2026 23:48
@usha-sj usha-sj self-assigned this Feb 8, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 8, 2026

Greptile Overview

Greptile Summary

This PR centralizes the Gemini study-generation prompt into a versioned module (backend/prompts/study_gen_v1.py) and updates the /api/v1/generate endpoint to build prompts via build_study_generation_prompt(...) (optionally with few-shot examples). It also adds a lightweight validate_quiz_quality pass that logs warnings after parsing model output, and documents the new prompt architecture in backend/README.md.

The main correctness concerns are around runtime importability and Python version compatibility: the new import in backend/main.py appears to assume prompts is a top-level module, and the new type annotations in study_gen_v1.py can be a syntax error on Python versions prior to 3.9/3.10 depending on your deployment target.

Confidence Score: 3/5

  • This PR is mergeable after fixing a couple of runtime compatibility issues.
  • Core change is straightforward (prompt moved to a module), but there are two likely runtime footguns: the prompts.* import may fail depending on how the app is launched, and list[dict] / list[str] annotations can be a hard syntax error on older Python runtimes. Once those are addressed, the change should be low risk.
  • backend/main.py; backend/prompts/study_gen_v1.py

Important Files Changed

Filename Overview
backend/README.md Documents the new centralized prompt module and how the /api/v1/generate endpoint uses it; no code-level issues found.
backend/main.py Switches endpoint to use build_study_generation_prompt and adds quiz quality warnings; current import path likely breaks when running backend as a package.
backend/prompts/study_gen_v1.py Adds centralized v1 prompt builders and quiz validation; validate_quiz_quality annotations may be incompatible with Python <3.9.

Sequence Diagram

sequenceDiagram
    autonumber
    participant Client
    participant API as backend/main.py
    participant Prompt as backend/prompts/study_gen_v1.py
    participant Gemini as Gemini Model

    Client->>API: POST /study (notes, options)
    API->>API: Validate request (reject empty notes)
    API->>Prompt: build_study_generation_prompt(notes, include_examples)
    Prompt-->>API: Prompt string (system + schema + examples)
    API->>Gemini: generate_content(prompt)
    Gemini-->>API: Model output (may be JSON / markdown-wrapped)
    API->>API: Clean output (strip markdown fences)
    API->>API: Parse JSON
    alt JSON valid
        API-->>Client: 200 Study JSON (API contract)
    else JSON invalid
        API-->>Client: 500 Safe error
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@Arhum2
Copy link
Contributor

Arhum2 commented Feb 9, 2026

@greptileai review this again and give me the updated confidence score

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 9, 2026

Greptile Overview

Greptile Summary

Refactors prompt logic from inline string in main.py into a versioned, centralized module (prompts/study_gen_v1.py) with few-shot examples and quality validation.

Key improvements:

  • Structured prompt system with system instructions, output format spec, and examples
  • build_study_generation_prompt() constructs prompts programmatically
  • validate_quiz_quality() detects common issues (duplicate options, invalid answers)
  • Comprehensive documentation in README.md with versioning strategy
  • Non-breaking API changes (preserves frontend compatibility)

Issues found:

  • Python 3.9+ type syntax (list[str], list[QuizQuestion]) in main.py breaks compatibility with Python 3.8
  • Missing __init__.py in prompts/ directory
  • Commented-out code should be removed before merge

Confidence Score: 3/5

  • Safe to merge after fixing Python 3.8 compatibility issues in main.py
  • The refactoring is well-structured and non-breaking, but Python 3.9+ type hints in main.py will cause syntax errors on Python 3.8 deployments. The commented code cleanup and missing init.py are minor style issues
  • backend/main.py requires type hint fixes for Python 3.8 compatibility (lines 54, 64-65)

Important Files Changed

Filename Overview
backend/prompts/study_gen_v1.py New centralized prompt module with versioning, few-shot examples, and validation. Minor: missing init.py for proper package structure
backend/main.py Integrates new prompt system. Issues: Python 3.9+ type syntax breaks 3.8 compatibility, commented code should be removed

Sequence Diagram

sequenceDiagram
    participant Client as Frontend
    participant API as /api/v1/generate
    participant Prompt as study_gen_v1.py
    participant Gemini as GeminiService
    participant Validator as validate_quiz_quality()

    Client->>API: POST /api/v1/generate<br/>{text: "user notes"}
    API->>API: Validate request.text<br/>(not empty)
    API->>Prompt: build_study_generation_prompt()<br/>(user_notes, include_examples=True)
    Prompt->>Prompt: Construct prompt with:<br/>SYSTEM_PROMPT + EXAMPLES +<br/>user_notes + OUTPUT_FORMAT
    Prompt-->>API: Complete prompt string
    API->>Gemini: call_gemini(prompt)
    Gemini-->>API: JSON response<br/>(may have markdown wrapping)
    API->>API: Clean markdown fences<br/>(remove ```json markers)
    API->>API: Parse JSON and validate<br/>(summary, quiz fields)
    API->>Validator: validate_quiz_quality(quiz_data)
    Validator-->>API: warnings list<br/>(logged, non-blocking)
    API-->>Client: GenerateResponse<br/>{summary: [], quiz: []}
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 9, 2026

Additional Comments (2)

backend/main.py
list[str] and list[QuizQuestion] use Python 3.9+ syntax. For Python 3.8 compatibility, import List from typing and use List[str] and List[QuizQuestion]

    options: List[str]
    answer: str
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/main.py
Line: 54:55

Comment:
`list[str]` and `list[QuizQuestion]` use Python 3.9+ syntax. For Python 3.8 compatibility, import `List` from typing and use `List[str]` and `List[QuizQuestion]`

```suggestion
    options: List[str]
    answer: str
```

How can I resolve this? If you propose a fix, please make it concise.

backend/main.py
Same Python 3.9+ syntax issue

    summary: List[str]
    quiz: List[QuizQuestion]
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/main.py
Line: 64:65

Comment:
Same Python 3.9+ syntax issue

```suggestion
    summary: List[str]
    quiz: List[QuizQuestion]
```

How can I resolve this? If you propose a fix, please make it concise.

@Arhum2
Copy link
Contributor

Arhum2 commented Feb 10, 2026

@greptileai review this again with the new version of main and give me the confidence score aswell

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 10, 2026

Greptile Overview

Greptile Summary

This PR centralizes the Gemini study-generation prompt into backend/prompts/study_gen_v1.py and wires /api/v1/generate to use build_study_generation_prompt() instead of an inline f-string prompt. It also adds a lightweight validate_quiz_quality() pass to emit warnings about quiz output structure.

Main issues to address before merge are around integration/robustness: the new import path in backend/main.py conflicts with the documented uvicorn main:app run mode (startup import failure), the few-shot example scaffolding includes non-JSON tokens that can prompt Gemini to emit non-JSON (breaking json.loads()), and the endpoint prints raw model output (which may contain user notes) directly to stdout.

Confidence Score: 2/5

  • Not safe to merge until startup/import and output-parsing risks are addressed.
  • The PR introduces a run-context import that will break the common uvicorn main:app invocation, and the prompt’s few-shot scaffolding can cause non-JSON model output that the endpoint can’t parse. Additionally, raw model output is printed to stdout, which can leak user-provided notes into logs.
  • backend/main.py, backend/prompts/study_gen_v1.py

Important Files Changed

Filename Overview
backend/README.md Documents the new centralized study prompt module and how it’s used by /api/v1/generate.
backend/main.py Switches generate endpoint to use the prompt builder and adds quiz quality warnings; introduces an import/run-context mismatch and logs raw AI output to stdout.
backend/prompts/study_gen_v1.py Adds centralized prompt builders and quiz-quality validation; few-shot examples include non-JSON scaffolding that can induce non-JSON model outputs.

Sequence Diagram

sequenceDiagram
  autonumber
  participant Client
  participant API as FastAPI (/api/v1/generate)
  participant Prompt as study_gen_v1.build_study_generation_prompt
  participant Gemini as GeminiService.call_gemini

  Client->>API: POST /api/v1/generate {text}
  API->>Prompt: build_study_generation_prompt(user_notes, include_examples)
  Prompt-->>API: prompt string
  API->>Gemini: call_gemini(prompt)
  Gemini-->>API: response.text (string)
  API->>API: strip markdown fences + json.loads
  API->>API: validate quiz items + validate_quiz_quality
  API-->>Client: 200 {summary, quiz}
  alt Gemini returns None
    API-->>Client: 500 Failed to generate
  else JSON decode / structure error
    API-->>Client: 500 Failed to parse / Invalid format
  end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +10 to +13
from backend.prompts.study_gen_v1 import (
build_study_generation_prompt,
validate_quiz_quality
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Broken import when run in backend/

from backend.prompts.study_gen_v1 import ... will fail when starting the app from within backend/ (as documented via uvicorn main:app --reload in backend/README.md), because backend won’t be a top-level package in that execution context. This makes the server crash on startup in the common local/dev invocation; use an import that works from backend/ (e.g. from prompts.study_gen_v1 ...) or adjust the run command to uvicorn backend.main:app so the package import is valid.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/main.py
Line: 10:13

Comment:
**Broken import when run in backend/**

`from backend.prompts.study_gen_v1 import ...` will fail when starting the app from within `backend/` (as documented via `uvicorn main:app --reload` in `backend/README.md`), because `backend` won’t be a top-level package in that execution context. This makes the server crash on startup in the common local/dev invocation; use an import that works from `backend/` (e.g. `from prompts.study_gen_v1 ...`) or adjust the run command to `uvicorn backend.main:app` so the package import is valid.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +176 to +180
# Optional: Run quality checks on the quiz
quality_warnings = validate_quiz_quality(data.get("quiz", []))
if quality_warnings:
print(f"[generate] Quality warnings: {quality_warnings}")
# Can log these or return them to the frontend in the future
Copy link
Contributor

Choose a reason for hiding this comment

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

Sensitive data logged to stdout

On invalid/failed responses, this endpoint prints Raw response: {response} and also prints quality_warnings unconditionally. Gemini output can contain user-provided notes verbatim, so this will leak user content into server logs. Since this PR adds additional logging paths, it should be gated/removed or switched to structured logging with redaction (and avoid printing raw model output).

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/main.py
Line: 176:180

Comment:
**Sensitive data logged to stdout**

On invalid/failed responses, this endpoint prints `Raw response: {response}` and also prints `quality_warnings` unconditionally. Gemini output can contain user-provided notes verbatim, so this will leak user content into server logs. Since this PR adds additional logging paths, it should be gated/removed or switched to structured logging with redaction (and avoid printing raw model output).

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +83 to +90
EXAMPLES = """Here are examples of correct output format:

--- EXAMPLE 1 ---

INPUT NOTES:
"Photosynthesis is the process by which plants convert sunlight into energy. It occurs in chloroplasts and requires carbon dioxide and water. The outputs are glucose and oxygen."

CORRECT OUTPUT:
Copy link
Contributor

Choose a reason for hiding this comment

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

Few-shot violates JSON-only rule

SYSTEM_PROMPT requires “ONLY valid JSON”, but EXAMPLES includes headers like --- EXAMPLE 1 ---, INPUT NOTES:, and CORRECT OUTPUT:. Because the final prompt contains these non-JSON tokens, the model may mirror that structure and prepend similar headers in its response, directly causing json.loads() to fail. If strict JSON output is required, keep the few-shot content itself purely JSON (or clearly isolate examples as non-output content and add an explicit anti-pattern warning).

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/prompts/study_gen_v1.py
Line: 83:90

Comment:
**Few-shot violates JSON-only rule**

`SYSTEM_PROMPT` requires “ONLY valid JSON”, but `EXAMPLES` includes headers like `--- EXAMPLE 1 ---`, `INPUT NOTES:`, and `CORRECT OUTPUT:`. Because the final prompt contains these non-JSON tokens, the model may mirror that structure and prepend similar headers in its response, directly causing `json.loads()` to fail. If strict JSON output is required, keep the few-shot content itself purely JSON (or clearly isolate examples as non-output content and add an explicit anti-pattern warning).

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants