fix: Analysis page now uses unified prompt executor (Issue #28)
BREAKING: Analysis page switched from old /insights/run to new /prompts/execute Changes: - Backend: Added save=true parameter to /prompts/execute - When enabled, saves final output to ai_insights table - Extracts content from pipeline output (last stage) - Frontend api.js: Added save parameter to executeUnifiedPrompt() - Frontend Analysis.jsx: Switched from api.runInsight() to api.executeUnifiedPrompt() - Transforms new result format to match InsightCard expectations - Pipeline outputs properly extracted and displayed Fixes: PIPELINE_MASTER responses (old template being sent to AI) The old /insights/run endpoint used raw template field, which for the legacy "pipeline" prompt was literally "PIPELINE_MASTER". The new executor properly handles stages and data processing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
811ba8b3dc
commit
97e57481f9
|
|
@ -700,6 +700,7 @@ async def execute_unified_prompt(
|
||||||
modules: Optional[dict] = None,
|
modules: Optional[dict] = None,
|
||||||
timeframes: Optional[dict] = None,
|
timeframes: Optional[dict] = None,
|
||||||
debug: bool = False,
|
debug: bool = False,
|
||||||
|
save: bool = False,
|
||||||
session: dict = Depends(require_auth)
|
session: dict = Depends(require_auth)
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|
@ -710,6 +711,7 @@ async def execute_unified_prompt(
|
||||||
modules: Dict of enabled modules (e.g., {"körper": true})
|
modules: Dict of enabled modules (e.g., {"körper": true})
|
||||||
timeframes: Dict of timeframes per module (e.g., {"körper": 30})
|
timeframes: Dict of timeframes per module (e.g., {"körper": 30})
|
||||||
debug: If true, include debug information (placeholders, final prompts, etc.)
|
debug: If true, include debug information (placeholders, final prompts, etc.)
|
||||||
|
save: If true, save result to ai_insights table
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Execution result with outputs (and debug info if debug=true)
|
Execution result with outputs (and debug info if debug=true)
|
||||||
|
|
@ -745,6 +747,33 @@ async def execute_unified_prompt(
|
||||||
enable_debug=debug
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,25 @@ export default function Analysis() {
|
||||||
const runPrompt = async (slug) => {
|
const runPrompt = async (slug) => {
|
||||||
setLoading(slug); setError(null); setNewResult(null)
|
setLoading(slug); setError(null); setNewResult(null)
|
||||||
try {
|
try {
|
||||||
const result = await api.runInsight(slug)
|
// Use new unified executor with save=true
|
||||||
setNewResult(result)
|
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()
|
await loadAll()
|
||||||
setTab('run')
|
setTab('run')
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
|
||||||
|
|
@ -307,9 +307,10 @@ export const api = {
|
||||||
executePipeline: (configId=null) => req('/insights/pipeline' + (configId ? `?config_id=${configId}` : ''), json({})),
|
executePipeline: (configId=null) => req('/insights/pipeline' + (configId ? `?config_id=${configId}` : ''), json({})),
|
||||||
|
|
||||||
// Unified Prompt System (Issue #28 Phase 2)
|
// 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 })
|
const params = new URLSearchParams({ prompt_slug: slug })
|
||||||
if (debug) params.append('debug', 'true')
|
if (debug) params.append('debug', 'true')
|
||||||
|
if (save) params.append('save', 'true')
|
||||||
const body = {}
|
const body = {}
|
||||||
if (modules) body.modules = modules
|
if (modules) body.modules = modules
|
||||||
if (timeframes) body.timeframes = timeframes
|
if (timeframes) body.timeframes = timeframes
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user