diff --git a/backend/routers/prompts.py b/backend/routers/prompts.py index e9fe0d2..da50aef 100644 --- a/backend/routers/prompts.py +++ b/backend/routers/prompts.py @@ -700,6 +700,7 @@ async def execute_unified_prompt( modules: Optional[dict] = None, timeframes: Optional[dict] = None, debug: bool = False, + save: bool = False, session: dict = Depends(require_auth) ): """ @@ -710,6 +711,7 @@ async def execute_unified_prompt( modules: Dict of enabled modules (e.g., {"körper": true}) timeframes: Dict of timeframes per module (e.g., {"körper": 30}) debug: If true, include debug information (placeholders, final prompts, etc.) + save: If true, save result to ai_insights table Returns: Execution result with outputs (and debug info if debug=true) @@ -745,6 +747,33 @@ async def execute_unified_prompt( enable_debug=debug ) + # Save to ai_insights if requested + if save: + # Extract final output text/markdown + if result['type'] == 'pipeline': + # For pipeline, get the last stage's output + final_output = result.get('output', {}) + # If output is dict with single key, use that value + if isinstance(final_output, dict) and len(final_output) == 1: + content = list(final_output.values())[0] + else: + content = json.dumps(final_output, ensure_ascii=False) + else: + # For base prompts, use output directly + content = result.get('output', '') + if isinstance(content, dict): + content = json.dumps(content, ensure_ascii=False) + + # Save to database + with get_db() as conn: + cur = get_cursor(conn) + cur.execute( + """INSERT INTO ai_insights (id, profile_id, scope, content, created) + VALUES (%s, %s, %s, %s, CURRENT_TIMESTAMP)""", + (str(uuid.uuid4()), profile_id, prompt_slug, content) + ) + conn.commit() + return result diff --git a/frontend/src/pages/Analysis.jsx b/frontend/src/pages/Analysis.jsx index 3f7d1b0..af3a630 100644 --- a/frontend/src/pages/Analysis.jsx +++ b/frontend/src/pages/Analysis.jsx @@ -75,8 +75,25 @@ export default function Analysis() { const runPrompt = async (slug) => { setLoading(slug); setError(null); setNewResult(null) try { - const result = await api.runInsight(slug) - setNewResult(result) + // Use new unified executor with save=true + const result = await api.executeUnifiedPrompt(slug, null, null, false, true) + + // Transform result to match old format for InsightCard + let content = '' + if (result.type === 'pipeline') { + // For pipeline, extract final output + const finalOutput = result.output || {} + if (typeof finalOutput === 'object' && Object.keys(finalOutput).length === 1) { + content = Object.values(finalOutput)[0] + } else { + content = JSON.stringify(finalOutput, null, 2) + } + } else { + // For base prompts, use output directly + content = typeof result.output === 'string' ? result.output : JSON.stringify(result.output, null, 2) + } + + setNewResult({ scope: slug, content }) await loadAll() setTab('run') } catch(e) { diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index a905a79..91919f6 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -307,9 +307,10 @@ export const api = { executePipeline: (configId=null) => req('/insights/pipeline' + (configId ? `?config_id=${configId}` : ''), json({})), // Unified Prompt System (Issue #28 Phase 2) - executeUnifiedPrompt: (slug, modules=null, timeframes=null, debug=false) => { + executeUnifiedPrompt: (slug, modules=null, timeframes=null, debug=false, save=false) => { const params = new URLSearchParams({ prompt_slug: slug }) if (debug) params.append('debug', 'true') + if (save) params.append('save', 'true') const body = {} if (modules) body.modules = modules if (timeframes) body.timeframes = timeframes