feat(ai): add AI chart suggestions in TipTap editor
Implement slash command "/suggest-charts" that analyzes note content and suggests 3 appropriate chart types with visual previews. Created: - chart-suggestion.tool.ts: AI tool for data extraction and chart recommendations - suggest-charts/route.ts: API endpoint for chart suggestions - chart-suggestion.service.ts: Frontend service layer - chart-suggestions-dialog.tsx: Modal with 3 chart proposals and thumbnails - tiptap-chart-extension.tsx: TipTap Node extension for rendering chart blocks Modified: - rich-text-editor.tsx: Added slash command, toolbar button, and dialog integration Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
80
memento-note/lib/ai/services/chart-suggestion.service.ts
Normal file
80
memento-note/lib/ai/services/chart-suggestion.service.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Chart Suggestion Service
|
||||
* Frontend service for calling the AI chart suggestions API
|
||||
*/
|
||||
|
||||
export interface ChartSuggestion {
|
||||
type: 'bar' | 'horizontal-bar' | 'line' | 'area' | 'pie' | 'radar' | 'funnel' | 'gauge'
|
||||
title: string
|
||||
data: { label: string; value: number }[]
|
||||
description: string
|
||||
rationale?: string
|
||||
}
|
||||
|
||||
export interface SuggestChartsResponse {
|
||||
suggestions: ChartSuggestion[]
|
||||
analyzedText: string
|
||||
detectedData: string
|
||||
hasData: boolean
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface SuggestChartsRequest {
|
||||
content: string
|
||||
selection?: string | null
|
||||
noteId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the AI chart suggestions API
|
||||
* @param request - The request parameters
|
||||
* @returns Promise with the chart suggestions
|
||||
*/
|
||||
export async function suggestCharts(request: SuggestChartsRequest): Promise<SuggestChartsResponse> {
|
||||
try {
|
||||
const response = await fetch('/api/ai/suggest-charts', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ error: 'Unknown error' }))
|
||||
return {
|
||||
suggestions: [],
|
||||
analyzedText: '',
|
||||
detectedData: '',
|
||||
hasData: false,
|
||||
error: errorData.error || `HTTP ${response.status}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data as SuggestChartsResponse
|
||||
} catch (error) {
|
||||
console.error('[suggestCharts] Network error:', error)
|
||||
return {
|
||||
suggestions: [],
|
||||
analyzedText: '',
|
||||
detectedData: '',
|
||||
hasData: false,
|
||||
error: error instanceof Error ? error.message : 'Network error',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chart suggestion to markdown code block format
|
||||
* @param suggestion - The chart suggestion to convert
|
||||
* @returns Markdown code block string
|
||||
*/
|
||||
export function chartSuggestionToMarkdown(suggestion: ChartSuggestion): string {
|
||||
const lines = [
|
||||
suggestion.type,
|
||||
suggestion.title,
|
||||
...suggestion.data.map(d => `${d.label}: ${d.value}`),
|
||||
]
|
||||
return `\`\`\`chart\n${lines.join('\n')}\n\`\`\``
|
||||
}
|
||||
Reference in New Issue
Block a user