Skip to content

Integrate AI shot analysis recommendations with profile editing pipeline #258

@hessius

Description

@hessius

Background

Shot analysis via POST /api/shots/analyze-llm already sends profile JSON + local analysis data to Gemini and returns structured markdown with 5 sections, including "Section 4: Profile Recommendations." However, these recommendations are currently text-only — users must manually interpret and apply them. This issue bridges the gap by extracting structured, actionable recommendations and letting users selectively apply them through the profile editing pipeline introduced in #257.

Current State

Backend

  • Analysis endpoint (POST /api/shots/analyze-llm in shots.py) sends profile structure (stages, variables, triggers) + local algorithmic analysis to Gemini
  • Prompt (prompt_builder.py) includes PROFILING_KNOWLEDGE with detailed OEPF specification knowledge
  • Response is parsed by parseStructuredAnalysis() on the frontend into 5 titled sections
  • No structured recommendation format exists — recommendations are embedded in natural language markdown

Frontend

  • ExpertAnalysisView.tsx renders the 5 analysis sections as styled cards — fully read-only
  • ShotHistoryView.tsx hosts the analysis tabs (Replay/Compare/Analyze)
  • No mechanism to extract or apply individual recommendations

Profile Format

Profiles follow OEPF format with patchable fields:

  • temperature (°C)
  • final_weight (grams)
  • variables[] (adjustable values referenced by $key in stage dynamics)
  • Info variables (info_* prefix) — grind, dose recommendations

Implementation Plan

Backend

  1. New endpoint: POST /api/shots/analyze-recommendations

    • Accepts same inputs as analyze-llm (profile name, shot date, shot filename)
    • Calls Gemini with a modified prompt requesting structured JSON recommendations
    • Returns:
      {
        "recommendations": [
          {
            "id": "rec_1",
            "category": "temperature" | "weight" | "variable" | "grind" | "dose" | "technique",
            "field_path": "temperature" | "final_weight" | "variables.pressure_1",
            "current_value": 93.0,
            "suggested_value": 91.5,
            "unit": "°C",
            "rationale": "Reducing temperature by 1.5°C will reduce bitterness...",
            "confidence": "high" | "medium" | "low",
            "patchable": true
          }
        ],
        "summary": "3 profile adjustments recommended to improve extraction balance"
      }
    • Non-patchable recommendations (technique changes like "grind 2 clicks finer") have patchable: false and display rationale only
  2. New endpoint: POST /api/profile/{name}/apply-recommendations

    • Accepts: { recommendation_ids: string[], recommendations: Recommendation[] }
    • Filters to only patchable: true items matching the provided IDs
    • Applies changes via the same path as Enable basic profile editing in profile details view #257's edit endpoint
    • Returns the updated profile and a summary of applied changes

AI Prompt Changes

  1. Extend the analysis prompt to request a RECOMMENDATIONS_JSON block alongside existing markdown:
    After your analysis, output a fenced block:
    ```recommendations_json
    [{ "category": "...", "field_path": "...", ... }]
    
    - Map each natural-language recommendation to a specific profile field path
    - Include confidence level based on how clearly the shot data supports the change
    - Mark as `patchable: false` for setup-only changes (grind, dose, technique)
    
    

Frontend

  1. New RecommendationSelectionDialog component:

    • Triggered by "Apply Recommendations" button in ExpertAnalysisView
    • Checkbox list of all recommendations, grouped by category
    • Patchable items: checkbox + current → suggested value preview
    • Non-patchable items: info icon + rationale (no checkbox)
    • Confidence badges (high/medium/low) with color coding
    • "Apply Selected" button → calls POST /api/profile/{name}/apply-recommendations
    • Success: toast with summary, link to view updated profile
  2. Update ExpertAnalysisView.tsx:

    • Add "Apply Recommendations" button after Section 4
    • Button disabled if no analysis has been run
    • Loading state while recommendations are being extracted

Dependencies

Acceptance Criteria

  • POST /api/shots/analyze-recommendations returns structured JSON recommendations with field paths, values, confidence, and rationale
  • POST /api/profile/{name}/apply-recommendations batch-applies selected patchable recommendations
  • RecommendationSelectionDialog shows grouped, checkable recommendations with current → suggested value previews
  • Non-patchable recommendations displayed as informational items (no checkbox)
  • Confidence badges (high/medium/low) rendered per recommendation
  • Success feedback with summary of applied changes
  • All labels use i18n keys
  • Unit tests for recommendation extraction and application endpoints
  • Frontend tests for the selection dialog

Key Files

File Change
apps/server/api/routes/shots.py New analyze-recommendations endpoint
apps/server/api/routes/profiles.py New apply-recommendations endpoint
apps/server/prompt_builder.py Extended prompt for structured recommendations
apps/web/src/components/ExpertAnalysisView.tsx "Apply Recommendations" button
apps/web/src/components/RecommendationSelectionDialog.tsx New component
apps/web/public/locales/*/translation.json New i18n keys

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions