383 lines
10 KiB
TypeScript
383 lines
10 KiB
TypeScript
'use server'
|
|
|
|
/**
|
|
* AI Server Actions Stub File
|
|
*
|
|
* This file provides a centralized location for all AI-related server action interfaces
|
|
* and serves as documentation for the AI server action architecture.
|
|
*
|
|
* IMPLEMENTATION STATUS:
|
|
* - Title Suggestions: ✅ Implemented (see app/actions/title-suggestions.ts)
|
|
* - Semantic Search: ✅ Implemented (see app/actions/semantic-search.ts)
|
|
* - Paragraph Reformulation: ✅ Implemented (see app/actions/paragraph-refactor.ts)
|
|
* - Memory Echo: ⏳ STUB - To be implemented in Epic 5 (Story 5-1)
|
|
* - Language Detection: ✅ Implemented (see app/actions/detect-language.ts)
|
|
* - AI Settings: ✅ Implemented (see app/actions/ai-settings.ts)
|
|
*
|
|
* NOTE: This file defines TypeScript interfaces and placeholder functions.
|
|
* Actual implementations are in separate action files (see references above).
|
|
*/
|
|
|
|
import { auth } from '@/auth'
|
|
import { prisma } from '@/lib/prisma'
|
|
import { revalidatePath } from 'next/cache'
|
|
|
|
// ============================================================================
|
|
// TYPESCRIPT INTERFACES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Title Suggestions Interfaces
|
|
* @see app/actions/title-suggestions.ts for implementation
|
|
*/
|
|
export interface GenerateTitlesRequest {
|
|
noteId: string
|
|
}
|
|
|
|
export interface GenerateTitlesResponse {
|
|
suggestions: Array<{
|
|
title: string
|
|
confidence: number
|
|
reasoning?: string
|
|
}>
|
|
noteId: string
|
|
}
|
|
|
|
/**
|
|
* Semantic Search Interfaces
|
|
* @see app/actions/semantic-search.ts for implementation
|
|
*/
|
|
export interface SearchResult {
|
|
noteId: string
|
|
title: string | null
|
|
content: string
|
|
similarity: number
|
|
matchType: 'exact' | 'related'
|
|
}
|
|
|
|
export interface SemanticSearchRequest {
|
|
query: string
|
|
options?: {
|
|
limit?: number
|
|
threshold?: number
|
|
notebookId?: string
|
|
}
|
|
}
|
|
|
|
export interface SemanticSearchResponse {
|
|
results: SearchResult[]
|
|
query: string
|
|
totalResults: number
|
|
}
|
|
|
|
/**
|
|
* Paragraph Reformulation Interfaces
|
|
* @see app/actions/paragraph-refactor.ts for implementation
|
|
*/
|
|
export type RefactorMode = 'clarify' | 'shorten' | 'improve'
|
|
|
|
export interface RefactorParagraphRequest {
|
|
noteId: string
|
|
selectedText: string
|
|
option: RefactorMode
|
|
}
|
|
|
|
export interface RefactorParagraphResponse {
|
|
originalText: string
|
|
refactoredText: string
|
|
}
|
|
|
|
/**
|
|
* Memory Echo Interfaces
|
|
* STUB - To be implemented in Epic 5 (Story 5-1)
|
|
*
|
|
* This feature will analyze all user notes with embeddings to find
|
|
* connections with cosine similarity > 0.75 and provide proactive insights.
|
|
*/
|
|
export interface GenerateMemoryEchoRequest {
|
|
// No params - uses current user session
|
|
}
|
|
|
|
export interface MemoryEchoInsight {
|
|
note1Id: string
|
|
note2Id: string
|
|
similarityScore: number
|
|
}
|
|
|
|
export interface GenerateMemoryEchoResponse {
|
|
success: boolean
|
|
insight: MemoryEchoInsight | null
|
|
}
|
|
|
|
/**
|
|
* Language Detection Interfaces
|
|
* @see app/actions/detect-language.ts for implementation
|
|
*/
|
|
export interface DetectLanguageRequest {
|
|
content: string
|
|
}
|
|
|
|
export interface DetectLanguageResponse {
|
|
language: string
|
|
confidence: number
|
|
method: 'tinyld' | 'ai'
|
|
}
|
|
|
|
/**
|
|
* AI Settings Interfaces
|
|
* @see app/actions/ai-settings.ts for implementation
|
|
*/
|
|
export interface AISettingsConfig {
|
|
titleSuggestions?: boolean
|
|
semanticSearch?: boolean
|
|
paragraphRefactor?: boolean
|
|
memoryEcho?: boolean
|
|
memoryEchoFrequency?: 'daily' | 'weekly' | 'custom'
|
|
aiProvider?: 'auto' | 'openai' | 'ollama'
|
|
preferredLanguage?: 'auto' | 'en' | 'fr' | 'es' | 'de' | 'fa' | 'it' | 'pt' | 'ru' | 'zh' | 'ja' | 'ko' | 'ar' | 'hi' | 'nl' | 'pl'
|
|
demoMode?: boolean
|
|
}
|
|
|
|
export interface UpdateAISettingsRequest {
|
|
settings: Partial<AISettingsConfig>
|
|
}
|
|
|
|
export interface UpdateAISettingsResponse {
|
|
success: boolean
|
|
}
|
|
|
|
// ============================================================================
|
|
// PLACEHOLDER FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Generate Title Suggestions
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/title-suggestions.ts
|
|
*
|
|
* This function generates 3 AI-powered title suggestions for a note when it
|
|
* reaches 50+ words without a title.
|
|
*
|
|
* @see generateTitleSuggestions in app/actions/title-suggestions.ts
|
|
*/
|
|
export async function generateTitles(
|
|
request: GenerateTitlesRequest
|
|
): Promise<GenerateTitlesResponse> {
|
|
// TODO: Import and use implementation from title-suggestions.ts
|
|
// import { generateTitleSuggestions } from './title-suggestions'
|
|
// return generateTitleSuggestions(request.noteId)
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/title-suggestions.ts')
|
|
}
|
|
|
|
/**
|
|
* Semantic Search
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/semantic-search.ts
|
|
*
|
|
* This function performs hybrid semantic + keyword search across user notes.
|
|
*
|
|
* @see semanticSearch in app/actions/semantic-search.ts
|
|
*/
|
|
export async function semanticSearch(
|
|
request: SemanticSearchRequest
|
|
): Promise<SemanticSearchResponse> {
|
|
// TODO: Import and use implementation from semantic-search.ts
|
|
// import { semanticSearch } from './semantic-search'
|
|
// return semanticSearch(request.query, request.options)
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/semantic-search.ts')
|
|
}
|
|
|
|
/**
|
|
* Refactor Paragraph
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/paragraph-refactor.ts
|
|
*
|
|
* This function refactors a paragraph using AI with specific mode (clarify/shorten/improve).
|
|
*
|
|
* @see refactorParagraph in app/actions/paragraph-refactor.ts
|
|
*/
|
|
export async function refactorParagraph(
|
|
request: RefactorParagraphRequest
|
|
): Promise<RefactorParagraphResponse> {
|
|
// TODO: Import and use implementation from paragraph-refactor.ts
|
|
// import { refactorParagraph } from './paragraph-refactor'
|
|
// return refactorParagraph(request.selectedText, request.option)
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/paragraph-refactor.ts')
|
|
}
|
|
|
|
/**
|
|
* Generate Memory Echo Insights
|
|
*
|
|
* STUB: To be implemented in Epic 5 (Story 5-1)
|
|
*
|
|
* This will analyze all user notes with embeddings to find
|
|
* connections with cosine similarity > 0.75.
|
|
*
|
|
* Implementation Plan:
|
|
* - Fetch all user notes with embeddings
|
|
* - Calculate pairwise cosine similarities
|
|
* - Find top connection with similarity > 0.75
|
|
* - Store in MemoryEchoInsight table
|
|
* - Return insight or null if none found
|
|
*
|
|
* @see Epic 5 Story 5-1 in planning/epics.md
|
|
*/
|
|
export async function generateMemoryEcho(): Promise<GenerateMemoryEchoResponse> {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
throw new Error('Unauthorized')
|
|
}
|
|
|
|
// TODO: Implement Memory Echo background processing
|
|
// - Fetch all user notes with embeddings from prisma.note
|
|
// - Calculate pairwise cosine similarities using embedding vectors
|
|
// - Filter for similarity > 0.75
|
|
// - Select top insight
|
|
// - Store in prisma.memoryEchoInsight table (if it exists)
|
|
// - Return { success: true, insight: {...} }
|
|
|
|
throw new Error('Not implemented: See Epic 5 Story 5-1')
|
|
}
|
|
|
|
/**
|
|
* Detect Language
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/detect-language.ts
|
|
*
|
|
* This function detects the language of user content.
|
|
*
|
|
* @see getInitialLanguage in app/actions/detect-language.ts
|
|
*/
|
|
export async function detectLanguage(
|
|
request: DetectLanguageRequest
|
|
): Promise<DetectLanguageResponse> {
|
|
// TODO: Import and use implementation from detect-language.ts
|
|
// import { detectUserLanguage } from '@/lib/i18n/detect-user-language'
|
|
// const language = await detectUserLanguage()
|
|
// return { language, confidence: 0.95, method: 'tinyld' }
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/detect-language.ts')
|
|
}
|
|
|
|
/**
|
|
* Update AI Settings
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/ai-settings.ts
|
|
*
|
|
* This function updates user AI preferences.
|
|
*
|
|
* @see updateAISettings in app/actions/ai-settings.ts
|
|
*/
|
|
export async function updateAISettings(
|
|
request: UpdateAISettingsRequest
|
|
): Promise<UpdateAISettingsResponse> {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
throw new Error('Unauthorized')
|
|
}
|
|
|
|
// TODO: Import and use implementation from ai-settings.ts
|
|
// import { updateAISettings } from './ai-settings'
|
|
// return updateAISettings(request.settings)
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/ai-settings.ts')
|
|
}
|
|
|
|
/**
|
|
* Get AI Settings
|
|
*
|
|
* ALREADY IMPLEMENTED: See app/actions/ai-settings.ts
|
|
*
|
|
* This function retrieves user AI preferences.
|
|
*
|
|
* @see getAISettings in app/actions/ai-settings.ts
|
|
*/
|
|
export async function getAISettings(): Promise<AISettingsConfig> {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
throw new Error('Unauthorized')
|
|
}
|
|
|
|
// TODO: Import and use implementation from ai-settings.ts
|
|
// import { getAISettings } from './ai-settings'
|
|
// return getAISettings()
|
|
|
|
throw new Error('Not implemented in stub: Use app/actions/ai-settings.ts')
|
|
}
|
|
|
|
// ============================================================================
|
|
// UTILITY FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Check if a specific AI feature is enabled for the user
|
|
*
|
|
* UTILITY: Helper function to check feature flags
|
|
*
|
|
* @param feature - The AI feature to check
|
|
* @returns Promise<boolean> - Whether the feature is enabled
|
|
*/
|
|
export async function isAIFeatureEnabled(
|
|
feature: keyof AISettingsConfig
|
|
): Promise<boolean> {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
return false
|
|
}
|
|
|
|
try {
|
|
const settings = await prisma.userAISettings.findUnique({
|
|
where: { userId: session.user.id }
|
|
})
|
|
|
|
if (!settings) {
|
|
// Default to enabled for new users
|
|
return true
|
|
}
|
|
|
|
switch (feature) {
|
|
case 'titleSuggestions':
|
|
return settings.titleSuggestions ?? true
|
|
case 'semanticSearch':
|
|
return settings.semanticSearch ?? true
|
|
case 'paragraphRefactor':
|
|
return settings.paragraphRefactor ?? true
|
|
case 'memoryEcho':
|
|
return settings.memoryEcho ?? true
|
|
default:
|
|
return true
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking AI feature enabled:', error)
|
|
return true
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get user's preferred AI provider
|
|
*
|
|
* UTILITY: Helper function to get provider preference
|
|
*
|
|
* @returns Promise<'auto' | 'openai' | 'ollama'> - The AI provider
|
|
*/
|
|
export async function getUserAIPreference(): Promise<'auto' | 'openai' | 'ollama'> {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
return 'auto'
|
|
}
|
|
|
|
try {
|
|
const settings = await prisma.userAISettings.findUnique({
|
|
where: { userId: session.user.id }
|
|
})
|
|
|
|
return (settings?.aiProvider || 'auto') as 'auto' | 'openai' | 'ollama'
|
|
} catch (error) {
|
|
console.error('Error getting user AI preference:', error)
|
|
return 'auto'
|
|
}
|
|
}
|