style: auto-format codebase with Prettier

Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
This commit is contained in:
Wuesteon 2025-11-27 18:33:16 +01:00
parent 0241f5554c
commit d36b321d9d
3952 changed files with 661498 additions and 739751 deletions

File diff suppressed because it is too large Load diff

View file

@ -2,300 +2,300 @@
* Conversation Service - CRUD operations via Backend API
*/
import {
conversationApi,
chatApi,
modelApi,
templateApi,
usageApi,
type Conversation as ApiConversation,
type Message as ApiMessage,
type ChatMessage,
type TokenUsage,
conversationApi,
chatApi,
modelApi,
templateApi,
usageApi,
type Conversation as ApiConversation,
type Message as ApiMessage,
type ChatMessage,
type TokenUsage,
} from './api';
// Re-export types with backwards-compatible naming (snake_case for mobile)
export type Conversation = {
id: string;
user_id: string;
model_id: string;
template_id?: string;
space_id?: string;
conversation_mode: 'free' | 'guided' | 'template';
document_mode: boolean;
title?: string;
is_archived: boolean;
created_at: string;
updated_at: string;
id: string;
user_id: string;
model_id: string;
template_id?: string;
space_id?: string;
conversation_mode: 'free' | 'guided' | 'template';
document_mode: boolean;
title?: string;
is_archived: boolean;
created_at: string;
updated_at: string;
};
export type Message = {
id: string;
conversation_id: string;
sender: 'user' | 'assistant' | 'system';
message_text: string;
created_at: string;
updated_at: string;
id: string;
conversation_id: string;
sender: 'user' | 'assistant' | 'system';
message_text: string;
created_at: string;
updated_at: string;
};
export type TokenUsageType = {
id: string;
conversation_id: string;
message_id: string;
user_id: string;
model_id: string;
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
estimated_cost: number;
created_at: string;
id: string;
conversation_id: string;
message_id: string;
user_id: string;
model_id: string;
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
estimated_cost: number;
created_at: string;
};
// Helper to convert API response to local format
function toLocalConversation(conv: ApiConversation): Conversation {
return {
id: conv.id,
user_id: conv.userId,
model_id: conv.modelId,
template_id: conv.templateId,
space_id: conv.spaceId,
conversation_mode: conv.conversationMode,
document_mode: conv.documentMode,
title: conv.title,
is_archived: conv.isArchived,
created_at: conv.createdAt,
updated_at: conv.updatedAt,
};
return {
id: conv.id,
user_id: conv.userId,
model_id: conv.modelId,
template_id: conv.templateId,
space_id: conv.spaceId,
conversation_mode: conv.conversationMode,
document_mode: conv.documentMode,
title: conv.title,
is_archived: conv.isArchived,
created_at: conv.createdAt,
updated_at: conv.updatedAt,
};
}
function toLocalMessage(msg: ApiMessage): Message {
return {
id: msg.id,
conversation_id: msg.conversationId,
sender: msg.sender,
message_text: msg.messageText,
created_at: msg.createdAt,
updated_at: msg.updatedAt,
};
return {
id: msg.id,
conversation_id: msg.conversationId,
sender: msg.sender,
message_text: msg.messageText,
created_at: msg.createdAt,
updated_at: msg.updatedAt,
};
}
/**
* Erstellt eine neue Konversation in der Datenbank
*/
export async function createConversation(
userId: string,
modelId: string,
mode: 'free' | 'guided' | 'template' = 'free',
templateId?: string,
documentMode: boolean = false,
spaceId?: string
userId: string,
modelId: string,
mode: 'free' | 'guided' | 'template' = 'free',
templateId?: string,
documentMode: boolean = false,
spaceId?: string
): Promise<string | null> {
try {
console.log('🔵 Erstelle Konversation mit Space ID:', spaceId || 'keine');
try {
console.log('🔵 Erstelle Konversation mit Space ID:', spaceId || 'keine');
const conversation = await conversationApi.createConversation({
modelId,
conversationMode: mode,
templateId,
documentMode,
spaceId,
});
const conversation = await conversationApi.createConversation({
modelId,
conversationMode: mode,
templateId,
documentMode,
spaceId,
});
if (!conversation) {
console.error('Fehler beim Erstellen der Konversation');
return null;
}
if (!conversation) {
console.error('Fehler beim Erstellen der Konversation');
return null;
}
return conversation.id;
} catch (error) {
console.error('Fehler beim Erstellen der Konversation:', error);
return null;
}
return conversation.id;
} catch (error) {
console.error('Fehler beim Erstellen der Konversation:', error);
return null;
}
}
/**
* Fügt eine neue Nachricht zur Konversation hinzu
*/
export async function addMessage(
conversationId: string,
sender: 'user' | 'assistant' | 'system',
messageText: string
conversationId: string,
sender: 'user' | 'assistant' | 'system',
messageText: string
): Promise<string | null> {
try {
// Validate sender
let validSender = sender;
if (!['user', 'assistant', 'system'].includes(validSender)) {
console.error('Ungültiger Sender-Wert:', sender);
validSender = 'user';
}
try {
// Validate sender
let validSender = sender;
if (!['user', 'assistant', 'system'].includes(validSender)) {
console.error('Ungültiger Sender-Wert:', sender);
validSender = 'user';
}
console.log('Füge Nachricht hinzu mit Sender:', validSender);
console.log('Füge Nachricht hinzu mit Sender:', validSender);
const message = await conversationApi.addMessage(conversationId, validSender, messageText);
const message = await conversationApi.addMessage(conversationId, validSender, messageText);
if (!message) {
console.error('Fehler beim Hinzufügen der Nachricht');
return null;
}
if (!message) {
console.error('Fehler beim Hinzufügen der Nachricht');
return null;
}
return message.id;
} catch (error) {
console.error('Fehler beim Hinzufügen der Nachricht:', error);
return null;
}
return message.id;
} catch (error) {
console.error('Fehler beim Hinzufügen der Nachricht:', error);
return null;
}
}
/**
* Lädt alle Nachrichten einer Konversation
*/
export async function getMessages(conversationId: string): Promise<Message[]> {
try {
const messages = await conversationApi.getMessages(conversationId);
return messages.map(toLocalMessage);
} catch (error) {
console.error('Fehler beim Laden der Nachrichten:', error);
return [];
}
try {
const messages = await conversationApi.getMessages(conversationId);
return messages.map(toLocalMessage);
} catch (error) {
console.error('Fehler beim Laden der Nachrichten:', error);
return [];
}
}
/**
* Generiert einen Titel für die Konversation basierend auf der ersten Benutzeranfrage
*/
export async function generateConversationTitle(userQuestion: string): Promise<string> {
try {
console.log(
'Generiere Titel für Konversation basierend auf:',
userQuestion.substring(0, 50) + (userQuestion.length > 50 ? '...' : '')
);
try {
console.log(
'Generiere Titel für Konversation basierend auf:',
userQuestion.substring(0, 50) + (userQuestion.length > 50 ? '...' : '')
);
const titlePrompt = `Schreibe eine kurze, prägnante Überschrift (maximal 5 Wörter) für unseren Chat mit dieser Frage: "${userQuestion}"`;
const titlePrompt = `Schreibe eine kurze, prägnante Überschrift (maximal 5 Wörter) für unseren Chat mit dieser Frage: "${userQuestion}"`;
const response = await chatApi.createCompletion({
messages: [{ role: 'user', content: titlePrompt }],
modelId: '550e8400-e29b-41d4-a716-446655440004', // GPT-4o-Mini
temperature: 0.3,
maxTokens: 50,
});
const response = await chatApi.createCompletion({
messages: [{ role: 'user', content: titlePrompt }],
modelId: '550e8400-e29b-41d4-a716-446655440004', // GPT-4o-Mini
temperature: 0.3,
maxTokens: 50,
});
if (!response) {
return 'Neue Konversation';
}
if (!response) {
return 'Neue Konversation';
}
// Clean up title
let cleanTitle = response.content
.trim()
.replace(/^["']|["']$/g, '')
.replace(/\.$/g, '');
// Clean up title
let cleanTitle = response.content
.trim()
.replace(/^["']|["']$/g, '')
.replace(/\.$/g, '');
if (cleanTitle.length > 100) {
cleanTitle = cleanTitle.substring(0, 97) + '...';
}
if (cleanTitle.length > 100) {
cleanTitle = cleanTitle.substring(0, 97) + '...';
}
console.log('Generierter Titel:', cleanTitle);
return cleanTitle;
} catch (error) {
console.error('Fehler bei der Titelgenerierung:', error);
return 'Neue Konversation';
}
console.log('Generierter Titel:', cleanTitle);
return cleanTitle;
} catch (error) {
console.error('Fehler bei der Titelgenerierung:', error);
return 'Neue Konversation';
}
}
/**
* Aktualisiert den Titel einer Konversation
*/
export async function updateConversationTitle(
conversationId: string,
title: string
conversationId: string,
title: string
): Promise<boolean> {
try {
const success = await conversationApi.updateTitle(conversationId, title);
try {
const success = await conversationApi.updateTitle(conversationId, title);
if (!success) {
console.error('Fehler beim Aktualisieren des Konversationstitels');
return false;
}
if (!success) {
console.error('Fehler beim Aktualisieren des Konversationstitels');
return false;
}
return true;
} catch (error) {
console.error('Fehler beim Aktualisieren des Konversationstitels:', error);
return false;
}
return true;
} catch (error) {
console.error('Fehler beim Aktualisieren des Konversationstitels:', error);
return false;
}
}
/**
* Lädt einen System-Prompt aus einer Vorlage
*/
export async function getSystemPromptFromTemplate(templateId: string): Promise<string | null> {
try {
const template = await templateApi.getTemplate(templateId);
try {
const template = await templateApi.getTemplate(templateId);
if (!template) {
console.error('Fehler beim Laden der Vorlage');
return null;
}
if (!template) {
console.error('Fehler beim Laden der Vorlage');
return null;
}
return template.systemPrompt;
} catch (error) {
console.error('Fehler beim Laden der Vorlage:', error);
return null;
}
return template.systemPrompt;
} catch (error) {
console.error('Fehler beim Laden der Vorlage:', error);
return null;
}
}
/**
* Sendet eine Benutzeranfrage an das LLM-Modell und speichert die Antwort
*/
export async function sendMessageAndGetResponse(
conversationId: string,
userMessage: string,
modelId: string,
templateId?: string,
documentMode: boolean = false
conversationId: string,
userMessage: string,
modelId: string,
templateId?: string,
documentMode: boolean = false
): Promise<{
userMessageId: string | null;
assistantMessageId: string | null;
assistantResponse: string;
title?: string;
documentContent?: string;
userMessageId: string | null;
assistantMessageId: string | null;
assistantResponse: string;
title?: string;
documentContent?: string;
}> {
try {
console.log('Starte sendMessageAndGetResponse mit:', {
conversationId,
userMessage: userMessage.substring(0, 50) + (userMessage.length > 50 ? '...' : ''),
modelId,
});
try {
console.log('Starte sendMessageAndGetResponse mit:', {
conversationId,
userMessage: userMessage.substring(0, 50) + (userMessage.length > 50 ? '...' : ''),
modelId,
});
// Load the model from API
const modelData = await modelApi.getModel(modelId);
// Load the model from API
const modelData = await modelApi.getModel(modelId);
if (!modelData) {
console.log('Verwende Standard-Parameter, da Modell nicht geladen werden konnte');
} else {
console.log('Modell geladen:', {
id: modelData.id,
name: modelData.name,
parameters: modelData.parameters,
deployment: modelData.parameters?.deployment,
});
}
if (!modelData) {
console.log('Verwende Standard-Parameter, da Modell nicht geladen werden konnte');
} else {
console.log('Modell geladen:', {
id: modelData.id,
name: modelData.name,
parameters: modelData.parameters,
deployment: modelData.parameters?.deployment,
});
}
// Save the user message
const userMessageId = await addMessage(conversationId, 'user', userMessage);
console.log('Benutzernachricht gespeichert mit ID:', userMessageId);
// Save the user message
const userMessageId = await addMessage(conversationId, 'user', userMessage);
console.log('Benutzernachricht gespeichert mit ID:', userMessageId);
// Load all messages for context
const messages = await getMessages(conversationId);
console.log(`${messages.length} Nachrichten für Kontext geladen`);
// Load all messages for context
const messages = await getMessages(conversationId);
console.log(`${messages.length} Nachrichten für Kontext geladen`);
// Build chat messages for API
const chatMessages: ChatMessage[] = [];
// Build chat messages for API
const chatMessages: ChatMessage[] = [];
// Load system prompt from template if available
let systemPrompt: string | null = null;
if (templateId) {
systemPrompt = await getSystemPromptFromTemplate(templateId);
if (systemPrompt) {
console.log('System-Prompt aus Vorlage geladen');
// Load system prompt from template if available
let systemPrompt: string | null = null;
if (templateId) {
systemPrompt = await getSystemPromptFromTemplate(templateId);
if (systemPrompt) {
console.log('System-Prompt aus Vorlage geladen');
if (documentMode) {
const documentModePrompt = `
if (documentMode) {
const documentModePrompt = `
${systemPrompt}
WICHTIG: Du befindest dich im Dokumentmodus. Deine Aufgabe ist es, dem Benutzer zu helfen, ein Dokument zu erstellen und zu verbessern.
@ -311,14 +311,14 @@ CHAT: Hier antwortest du auf die Frage oder das Feedback des Nutzers.
DOKUMENT:
Hier steht dein Vorschlag für das Dokument in Markdown-Format, ohne Codeblock-Markierungen.
`;
chatMessages.push({ role: 'system', content: documentModePrompt });
console.log('Dokumentmodus-Prompt hinzugefügt');
} else {
chatMessages.push({ role: 'system', content: systemPrompt });
}
}
} else if (documentMode) {
const documentModePrompt = `
chatMessages.push({ role: 'system', content: documentModePrompt });
console.log('Dokumentmodus-Prompt hinzugefügt');
} else {
chatMessages.push({ role: 'system', content: systemPrompt });
}
}
} else if (documentMode) {
const documentModePrompt = `
Du befindest dich im Dokumentmodus. Deine Aufgabe ist es, dem Benutzer zu helfen, ein Dokument zu erstellen und zu verbessern.
1. Das Dokument wird in einem separaten Bereich neben dem Chat angezeigt.
@ -332,219 +332,219 @@ CHAT: Hier antwortest du auf die Frage oder das Feedback des Nutzers.
DOKUMENT:
Hier steht dein Vorschlag für das Dokument in Markdown-Format, ohne Codeblock-Markierungen.
`;
chatMessages.push({ role: 'system', content: documentModePrompt });
console.log('Standard-Dokumentmodus-Prompt hinzugefügt');
}
chatMessages.push({ role: 'system', content: documentModePrompt });
console.log('Standard-Dokumentmodus-Prompt hinzugefügt');
}
// Add all conversation messages
chatMessages.push(
...messages.map((msg) => ({
role: msg.sender === 'user' ? 'user' : msg.sender === 'assistant' ? 'assistant' : 'system',
content: msg.message_text,
})) as ChatMessage[]
);
// Add all conversation messages
chatMessages.push(
...(messages.map((msg) => ({
role: msg.sender === 'user' ? 'user' : msg.sender === 'assistant' ? 'assistant' : 'system',
content: msg.message_text,
})) as ChatMessage[])
);
console.log('Nachrichten für OpenAI konvertiert:', chatMessages.length, 'Nachrichten');
console.log('Nachrichten für OpenAI konvertiert:', chatMessages.length, 'Nachrichten');
// Send request to AI
console.log('Sende Anfrage an LLM-Modell mit Parametern:', {
temperature: modelData?.parameters?.temperature || 0.7,
maxTokens: modelData?.parameters?.max_tokens || 800,
});
// Send request to AI
console.log('Sende Anfrage an LLM-Modell mit Parametern:', {
temperature: modelData?.parameters?.temperature || 0.7,
maxTokens: modelData?.parameters?.max_tokens || 800,
});
const result = await chatApi.createCompletion({
messages: chatMessages,
modelId,
temperature: modelData?.parameters?.temperature || 0.7,
maxTokens: modelData?.parameters?.max_tokens || 800,
});
const result = await chatApi.createCompletion({
messages: chatMessages,
modelId,
temperature: modelData?.parameters?.temperature || 0.7,
maxTokens: modelData?.parameters?.max_tokens || 800,
});
let assistantResponse: string;
let tokenUsage: TokenUsage | undefined;
let assistantResponse: string;
let tokenUsage: TokenUsage | undefined;
if (!result) {
assistantResponse =
'Es konnte keine Antwort generiert werden. Bitte stelle sicher, dass das Backend läuft.';
} else {
assistantResponse = result.content;
tokenUsage = result.usage;
if (!result) {
assistantResponse =
'Es konnte keine Antwort generiert werden. Bitte stelle sicher, dass das Backend läuft.';
} else {
assistantResponse = result.content;
tokenUsage = result.usage;
console.log('Antwort vom LLM-Modell erhalten:', {
length: assistantResponse.length,
preview: assistantResponse.substring(0, 50) + (assistantResponse.length > 50 ? '...' : ''),
tokenUsage,
});
}
console.log('Antwort vom LLM-Modell erhalten:', {
length: assistantResponse.length,
preview: assistantResponse.substring(0, 50) + (assistantResponse.length > 50 ? '...' : ''),
tokenUsage,
});
}
// Extract document content if in document mode
let documentContent: string | undefined;
let chatResponse = assistantResponse;
// Extract document content if in document mode
let documentContent: string | undefined;
let chatResponse = assistantResponse;
if (documentMode) {
console.log(
'Analysiere LLM-Antwort für Dokumentextraktion:',
assistantResponse.substring(0, 200) + '...'
);
if (documentMode) {
console.log(
'Analysiere LLM-Antwort für Dokumentextraktion:',
assistantResponse.substring(0, 200) + '...'
);
const chatMatch = assistantResponse.match(/CHAT:(.*?)(?=DOKUMENT:|$)/s);
const documentMatch = assistantResponse.match(
/DOKUMENT:[\s\n]*(```markdown|```|`markdown)?([^`].*?)(?:```|`+)?$/s
);
const chatMatch = assistantResponse.match(/CHAT:(.*?)(?=DOKUMENT:|$)/s);
const documentMatch = assistantResponse.match(
/DOKUMENT:[\s\n]*(```markdown|```|`markdown)?([^`].*?)(?:```|`+)?$/s
);
console.log('Dokument-Regex Match:', documentMatch ? 'Ja' : 'Nein');
console.log('Dokument-Regex Match:', documentMatch ? 'Ja' : 'Nein');
if (chatMatch && chatMatch[1]) {
chatResponse = chatMatch[1].trim();
console.log('Chat-Antwort extrahiert:', chatResponse.substring(0, 50) + '...');
}
if (chatMatch && chatMatch[1]) {
chatResponse = chatMatch[1].trim();
console.log('Chat-Antwort extrahiert:', chatResponse.substring(0, 50) + '...');
}
if (documentMatch && documentMatch[2]) {
documentContent = documentMatch[2].trim();
console.log(
'Dokument-Inhalt extrahiert:',
(documentContent?.substring(0, 50) || '') + '...'
);
}
}
if (documentMatch && documentMatch[2]) {
documentContent = documentMatch[2].trim();
console.log(
'Dokument-Inhalt extrahiert:',
(documentContent?.substring(0, 50) || '') + '...'
);
}
}
// Save assistant message
const assistantMessageId = await addMessage(conversationId, 'assistant', chatResponse);
console.log('Assistentenantwort gespeichert mit ID:', assistantMessageId);
// Save assistant message
const assistantMessageId = await addMessage(conversationId, 'assistant', chatResponse);
console.log('Assistentenantwort gespeichert mit ID:', assistantMessageId);
// Log token usage if available
if (tokenUsage && assistantMessageId && userMessageId) {
try {
const estimatedCost = calculateTokenCost(
tokenUsage.prompt_tokens,
tokenUsage.completion_tokens,
modelData?.costSettings
);
// Log token usage if available
if (tokenUsage && assistantMessageId && userMessageId) {
try {
const estimatedCost = calculateTokenCost(
tokenUsage.prompt_tokens,
tokenUsage.completion_tokens,
modelData?.costSettings
);
await usageApi.logTokenUsage({
conversationId,
messageId: assistantMessageId,
modelId,
promptTokens: tokenUsage.prompt_tokens,
completionTokens: tokenUsage.completion_tokens,
totalTokens: tokenUsage.total_tokens,
estimatedCost,
});
console.log('Token-Nutzung erfolgreich geloggt');
} catch (error) {
console.error('Fehler beim Loggen der Token-Nutzung:', error);
}
}
await usageApi.logTokenUsage({
conversationId,
messageId: assistantMessageId,
modelId,
promptTokens: tokenUsage.prompt_tokens,
completionTokens: tokenUsage.completion_tokens,
totalTokens: tokenUsage.total_tokens,
estimatedCost,
});
console.log('Token-Nutzung erfolgreich geloggt');
} catch (error) {
console.error('Fehler beim Loggen der Token-Nutzung:', error);
}
}
// Generate title for new conversations
const allMessages = await getMessages(conversationId);
let title: string | undefined;
// Generate title for new conversations
const allMessages = await getMessages(conversationId);
let title: string | undefined;
if (allMessages.length <= 2) {
title = await generateConversationTitle(userMessage);
if (allMessages.length <= 2) {
title = await generateConversationTitle(userMessage);
if (title) {
const success = await updateConversationTitle(conversationId, title);
console.log('Konversationstitel aktualisiert:', success ? 'erfolgreich' : 'fehlgeschlagen');
}
}
if (title) {
const success = await updateConversationTitle(conversationId, title);
console.log('Konversationstitel aktualisiert:', success ? 'erfolgreich' : 'fehlgeschlagen');
}
}
return {
userMessageId,
assistantMessageId,
assistantResponse: chatResponse,
title,
documentContent,
};
} catch (error) {
console.error('Fehler beim Senden der Nachricht:', error);
return {
userMessageId,
assistantMessageId,
assistantResponse: chatResponse,
title,
documentContent,
};
} catch (error) {
console.error('Fehler beim Senden der Nachricht:', error);
if (error instanceof Error) {
console.error('Fehlerdetails:', {
name: error.name,
message: error.message,
stack: error.stack,
});
}
if (error instanceof Error) {
console.error('Fehlerdetails:', {
name: error.name,
message: error.message,
stack: error.stack,
});
}
return {
userMessageId: null,
assistantMessageId: null,
assistantResponse: `Es ist ein Fehler aufgetreten: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}. Bitte versuche es später erneut.`,
};
}
return {
userMessageId: null,
assistantMessageId: null,
assistantResponse: `Es ist ein Fehler aufgetreten: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}. Bitte versuche es später erneut.`,
};
}
}
// Helper function to calculate token cost
function calculateTokenCost(
promptTokens: number,
completionTokens: number,
costSettings?: { prompt_per_1k_tokens?: number; completion_per_1k_tokens?: number }
promptTokens: number,
completionTokens: number,
costSettings?: { prompt_per_1k_tokens?: number; completion_per_1k_tokens?: number }
): number {
const promptCost = costSettings?.prompt_per_1k_tokens || 0.0001;
const completionCost = costSettings?.completion_per_1k_tokens || 0.0002;
const promptCost = costSettings?.prompt_per_1k_tokens || 0.0001;
const completionCost = costSettings?.completion_per_1k_tokens || 0.0002;
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
}
/**
* Lädt alle aktiven (nicht archivierten) Konversationen eines Benutzers
*/
export async function getConversations(userId: string, spaceId?: string): Promise<Conversation[]> {
try {
const conversations = await conversationApi.getConversations(spaceId);
return conversations.map(toLocalConversation);
} catch (error) {
console.error('Fehler beim Laden der Konversationen:', error);
return [];
}
try {
const conversations = await conversationApi.getConversations(spaceId);
return conversations.map(toLocalConversation);
} catch (error) {
console.error('Fehler beim Laden der Konversationen:', error);
return [];
}
}
/**
* Lädt alle archivierten Konversationen eines Benutzers
*/
export async function getArchivedConversations(userId: string): Promise<Conversation[]> {
try {
const conversations = await conversationApi.getArchivedConversations();
return conversations.map(toLocalConversation);
} catch (error) {
console.error('Fehler beim Laden der archivierten Konversationen:', error);
return [];
}
try {
const conversations = await conversationApi.getArchivedConversations();
return conversations.map(toLocalConversation);
} catch (error) {
console.error('Fehler beim Laden der archivierten Konversationen:', error);
return [];
}
}
/**
* Archiviert eine Konversation
*/
export async function archiveConversation(conversationId: string): Promise<boolean> {
try {
return await conversationApi.archiveConversation(conversationId);
} catch (error) {
console.error('Fehler beim Archivieren der Konversation:', error);
return false;
}
try {
return await conversationApi.archiveConversation(conversationId);
} catch (error) {
console.error('Fehler beim Archivieren der Konversation:', error);
return false;
}
}
/**
* Stellt eine archivierte Konversation wieder her
*/
export async function unarchiveConversation(conversationId: string): Promise<boolean> {
try {
return await conversationApi.unarchiveConversation(conversationId);
} catch (error) {
console.error('Fehler beim Wiederherstellen der Konversation:', error);
return false;
}
try {
return await conversationApi.unarchiveConversation(conversationId);
} catch (error) {
console.error('Fehler beim Wiederherstellen der Konversation:', error);
return false;
}
}
/**
* Löscht eine Konversation dauerhaft
*/
export async function deleteConversation(conversationId: string): Promise<boolean> {
try {
return await conversationApi.deleteConversation(conversationId);
} catch (error) {
console.error('Fehler beim Löschen der Konversation:', error);
return false;
}
try {
return await conversationApi.deleteConversation(conversationId);
} catch (error) {
console.error('Fehler beim Löschen der Konversation:', error);
return false;
}
}

View file

@ -5,157 +5,157 @@ import { documentApi, type Document as ApiDocument } from './api';
// Re-export type with backwards-compatible naming (snake_case for mobile)
export interface Document {
id: string;
conversation_id: string;
version: number;
content: string;
created_at: string;
updated_at: string;
id: string;
conversation_id: string;
version: number;
content: string;
created_at: string;
updated_at: string;
}
// Helper to convert API response to local format
function toLocalDocument(doc: ApiDocument): Document {
return {
id: doc.id,
conversation_id: doc.conversationId,
version: doc.version,
content: doc.content,
created_at: doc.createdAt,
updated_at: doc.updatedAt,
};
return {
id: doc.id,
conversation_id: doc.conversationId,
version: doc.version,
content: doc.content,
created_at: doc.createdAt,
updated_at: doc.updatedAt,
};
}
/**
* Erstellt ein neues Dokument in einer Konversation
*/
export async function createDocument(
conversationId: string,
content: string
conversationId: string,
content: string
): Promise<Document | null> {
try {
console.log(
`Erstelle Dokument für Konversation ${conversationId} mit Inhalt: ${content.substring(0, 50)}...`
);
try {
console.log(
`Erstelle Dokument für Konversation ${conversationId} mit Inhalt: ${content.substring(0, 50)}...`
);
const document = await documentApi.createDocument(conversationId, content);
const document = await documentApi.createDocument(conversationId, content);
if (!document) {
console.error('Fehler beim Erstellen des Dokuments');
return null;
}
if (!document) {
console.error('Fehler beim Erstellen des Dokuments');
return null;
}
console.log('Dokument erfolgreich erstellt:', document);
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Erstellen des Dokuments:', error);
if (error instanceof Error) {
console.error('Error details:', error.message, error.stack);
}
return null;
}
console.log('Dokument erfolgreich erstellt:', document);
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Erstellen des Dokuments:', error);
if (error instanceof Error) {
console.error('Error details:', error.message, error.stack);
}
return null;
}
}
/**
* Erstellt eine neue Version eines Dokuments
*/
export async function createDocumentVersion(
conversationId: string,
content: string
conversationId: string,
content: string
): Promise<Document | null> {
try {
const document = await documentApi.createDocumentVersion(conversationId, content);
try {
const document = await documentApi.createDocumentVersion(conversationId, content);
if (!document) {
console.error('Fehler beim Erstellen der neuen Dokumentversion');
return null;
}
if (!document) {
console.error('Fehler beim Erstellen der neuen Dokumentversion');
return null;
}
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Erstellen der neuen Dokumentversion:', error);
return null;
}
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Erstellen der neuen Dokumentversion:', error);
return null;
}
}
/**
* Holt die aktuellste Version eines Dokuments für eine Konversation
*/
export async function getLatestDocument(conversationId: string): Promise<Document | null> {
try {
console.log(`Lade neuestes Dokument für Konversation ${conversationId}`);
try {
console.log(`Lade neuestes Dokument für Konversation ${conversationId}`);
const document = await documentApi.getLatestDocument(conversationId);
const document = await documentApi.getLatestDocument(conversationId);
if (!document) {
console.log('Kein Dokument gefunden');
return null;
}
if (!document) {
console.log('Kein Dokument gefunden');
return null;
}
console.log(`Neuestes Dokument gefunden: Version ${document.version}, ID ${document.id}`);
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Laden des aktuellen Dokuments:', error);
return null;
}
console.log(`Neuestes Dokument gefunden: Version ${document.version}, ID ${document.id}`);
return toLocalDocument(document);
} catch (error) {
console.error('Fehler beim Laden des aktuellen Dokuments:', error);
return null;
}
}
/**
* Lädt alle Versionen eines Dokuments für eine Konversation
*/
export async function getAllDocumentVersions(conversationId: string): Promise<Document[]> {
try {
console.log(`Lade alle Dokumentversionen für Konversation ${conversationId}`);
try {
console.log(`Lade alle Dokumentversionen für Konversation ${conversationId}`);
const documents = await documentApi.getAllDocumentVersions(conversationId);
const documents = await documentApi.getAllDocumentVersions(conversationId);
console.log(`${documents.length} Dokumentversionen geladen`);
console.log(`${documents.length} Dokumentversionen geladen`);
if (documents.length > 0) {
console.log(`Erstes Dokument: ID=${documents[0].id}, Version=${documents[0].version}`);
} else {
console.log('Keine Dokumente gefunden');
}
if (documents.length > 0) {
console.log(`Erstes Dokument: ID=${documents[0].id}, Version=${documents[0].version}`);
} else {
console.log('Keine Dokumente gefunden');
}
return documents.map(toLocalDocument);
} catch (error) {
console.error('Fehler beim Laden der Dokumentversionen:', error);
return [];
}
return documents.map(toLocalDocument);
} catch (error) {
console.error('Fehler beim Laden der Dokumentversionen:', error);
return [];
}
}
/**
* Prüft, ob für eine Konversation ein Dokument existiert
*/
export async function hasDocument(conversationId: string): Promise<boolean> {
try {
return await documentApi.hasDocument(conversationId);
} catch (error) {
console.error('Fehler beim Prüfen auf Dokument:', error);
return false;
}
try {
return await documentApi.hasDocument(conversationId);
} catch (error) {
console.error('Fehler beim Prüfen auf Dokument:', error);
return false;
}
}
/**
* Löscht eine spezifische Dokumentversion
*/
export async function deleteDocumentVersion(documentId: string): Promise<boolean> {
try {
console.log(`=== LÖSCH-OPERATION GESTARTET FÜR DOKUMENT ID ${documentId} ===`);
try {
console.log(`=== LÖSCH-OPERATION GESTARTET FÜR DOKUMENT ID ${documentId} ===`);
const success = await documentApi.deleteDocumentVersion(documentId);
const success = await documentApi.deleteDocumentVersion(documentId);
if (success) {
console.log(`=== DOKUMENT ${documentId} ERFOLGREICH GELÖSCHT ===`);
} else {
console.error('Fehler beim Löschen der Dokumentversion');
}
if (success) {
console.log(`=== DOKUMENT ${documentId} ERFOLGREICH GELÖSCHT ===`);
} else {
console.error('Fehler beim Löschen der Dokumentversion');
}
return success;
} catch (error) {
console.error('Unerwarteter Fehler beim Löschen der Dokumentversion:', error);
if (error instanceof Error) {
console.error('Fehlerstack:', error.stack);
}
return false;
}
return success;
} catch (error) {
console.error('Unerwarteter Fehler beim Löschen der Dokumentversion:', error);
if (error instanceof Error) {
console.error('Fehlerstack:', error.stack);
}
return false;
}
}

View file

@ -5,17 +5,17 @@ import { availableModels } from '../config/azure';
// Typendefinition für ein KI-Modell
export interface Model {
id: string;
name: string;
description: string;
parameters?: {
temperature?: number;
max_tokens?: number;
provider?: string;
deployment?: string;
endpoint?: string;
api_version?: string;
};
id: string;
name: string;
description: string;
parameters?: {
temperature?: number;
max_tokens?: number;
provider?: string;
deployment?: string;
endpoint?: string;
api_version?: string;
};
}
/**
@ -23,14 +23,14 @@ export interface Model {
* @returns Eine Liste von verfügbaren Modellen
*/
export async function getModels(): Promise<Model[]> {
try {
// In einer echten Anwendung würde hier eine API-Anfrage erfolgen
// Für jetzt verwenden wir die Fallback-Modelle aus der Konfiguration
return availableModels;
} catch (error) {
console.error('Fehler beim Abrufen der Modelle:', error);
return availableModels; // Fallback auf lokale Modelle
}
try {
// In einer echten Anwendung würde hier eine API-Anfrage erfolgen
// Für jetzt verwenden wir die Fallback-Modelle aus der Konfiguration
return availableModels;
} catch (error) {
console.error('Fehler beim Abrufen der Modelle:', error);
return availableModels; // Fallback auf lokale Modelle
}
}
/**
@ -39,14 +39,14 @@ export async function getModels(): Promise<Model[]> {
* @returns Das Modell oder undefined, wenn nicht gefunden
*/
export async function getModelById(id: string): Promise<Model | undefined> {
try {
const models = await getModels();
return models.find(model => model.id === id);
} catch (error) {
console.error('Fehler beim Abrufen des Modells:', error);
// Fallback: Suche in lokalen Modellen
return availableModels.find(model => model.id === id);
}
try {
const models = await getModels();
return models.find((model) => model.id === id);
} catch (error) {
console.error('Fehler beim Abrufen des Modells:', error);
// Fallback: Suche in lokalen Modellen
return availableModels.find((model) => model.id === id);
}
}
/**
@ -54,11 +54,11 @@ export async function getModelById(id: string): Promise<Model | undefined> {
* @returns Das Standard-Modell
*/
export async function getDefaultModel(): Promise<Model> {
try {
const models = await getModels();
return models[0]; // Das erste Modell in der Liste als Standard
} catch (error) {
console.error('Fehler beim Abrufen des Standard-Modells:', error);
return availableModels[0]; // Fallback auf lokales Standard-Modell
}
}
try {
const models = await getModels();
return models[0]; // Das erste Modell in der Liste als Standard
} catch (error) {
console.error('Fehler beim Abrufen des Standard-Modells:', error);
return availableModels[0]; // Fallback auf lokales Standard-Modell
}
}

View file

@ -13,188 +13,188 @@ export type { TokenUsage };
// Chat response type (kept for compatibility)
export type ChatResponse = {
id: string;
choices: {
content_filter_results?: any;
finish_reason: string;
index: number;
logprobs: any;
message?: {
content: string;
refusal?: any;
role: string;
};
}[];
created: number;
model: string;
object: string;
prompt_filter_results?: any[];
system_fingerprint?: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
completion_tokens_details?: any;
prompt_tokens_details?: any;
};
id: string;
choices: {
content_filter_results?: any;
finish_reason: string;
index: number;
logprobs: any;
message?: {
content: string;
refusal?: any;
role: string;
};
}[];
created: number;
model: string;
object: string;
prompt_filter_results?: any[];
system_fingerprint?: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
completion_tokens_details?: any;
prompt_tokens_details?: any;
};
};
// Return type for chat request
export type ChatRequestResult = {
content: string;
usage: TokenUsage;
content: string;
usage: TokenUsage;
};
// Logging configuration
console.log('Chat Service Konfiguration:', {
backendUrl: process.env.EXPO_PUBLIC_BACKEND_URL || 'http://localhost:3001',
availableModels: availableModels.length,
backendUrl: process.env.EXPO_PUBLIC_BACKEND_URL || 'http://localhost:3001',
availableModels: availableModels.length,
});
/**
* Calculates estimated cost for an LLM request
*/
export async function calculateTokenCost(
promptTokens: number,
completionTokens: number,
modelId: string
promptTokens: number,
completionTokens: number,
modelId: string
): Promise<number> {
try {
// Get cost settings from model
const modelData = await modelApi.getModel(modelId);
try {
// Get cost settings from model
const modelData = await modelApi.getModel(modelId);
if (!modelData || !modelData.costSettings) {
console.warn('Fehler beim Laden der Kosteninformationen, verwende Standardwerte');
const promptCost = 0.0001;
const completionCost = 0.0002;
if (!modelData || !modelData.costSettings) {
console.warn('Fehler beim Laden der Kosteninformationen, verwende Standardwerte');
const promptCost = 0.0001;
const completionCost = 0.0002;
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
}
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
}
const promptCost = modelData.costSettings.prompt_per_1k_tokens || 0.0001;
const completionCost = modelData.costSettings.completion_per_1k_tokens || 0.0002;
const promptCost = modelData.costSettings.prompt_per_1k_tokens || 0.0001;
const completionCost = modelData.costSettings.completion_per_1k_tokens || 0.0002;
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
} catch (error) {
console.error('Fehler bei der Kostenberechnung:', error);
return Number(((promptTokens * 0.0001 + completionTokens * 0.0002) / 1000).toFixed(6));
}
const cost = (promptTokens * promptCost + completionTokens * completionCost) / 1000;
return Number(cost.toFixed(6));
} catch (error) {
console.error('Fehler bei der Kostenberechnung:', error);
return Number(((promptTokens * 0.0001 + completionTokens * 0.0002) / 1000).toFixed(6));
}
}
/**
* Logs token usage to the database
*/
export async function logTokenUsage(
usage: TokenUsage,
conversationId: string,
messageId: string,
userId: string,
modelId: string
usage: TokenUsage,
conversationId: string,
messageId: string,
userId: string,
modelId: string
): Promise<void> {
try {
const estimatedCost = await calculateTokenCost(
usage.prompt_tokens,
usage.completion_tokens,
modelId
);
try {
const estimatedCost = await calculateTokenCost(
usage.prompt_tokens,
usage.completion_tokens,
modelId
);
const success = await usageApi.logTokenUsage({
conversationId,
messageId,
modelId,
promptTokens: usage.prompt_tokens,
completionTokens: usage.completion_tokens,
totalTokens: usage.total_tokens,
estimatedCost,
});
const success = await usageApi.logTokenUsage({
conversationId,
messageId,
modelId,
promptTokens: usage.prompt_tokens,
completionTokens: usage.completion_tokens,
totalTokens: usage.total_tokens,
estimatedCost,
});
if (success) {
console.log('Token-Nutzung erfolgreich gespeichert:', {
conversationId,
messageId,
totalTokens: usage.total_tokens,
estimatedCost,
});
} else {
console.error('Fehler beim Speichern der Token-Nutzung');
}
} catch (error) {
console.error('Fehler beim Loggen der Token-Nutzung:', error);
}
if (success) {
console.log('Token-Nutzung erfolgreich gespeichert:', {
conversationId,
messageId,
totalTokens: usage.total_tokens,
estimatedCost,
});
} else {
console.error('Fehler beim Speichern der Token-Nutzung');
}
} catch (error) {
console.error('Fehler beim Loggen der Token-Nutzung:', error);
}
}
/**
* Sends a chat request via the backend
*/
export async function sendChatRequest(
messages: ChatMessage[],
temperature: number = 0.7,
maxTokens: number = 800
messages: ChatMessage[],
temperature: number = 0.7,
maxTokens: number = 800
): Promise<string | ChatRequestResult> {
console.log('sendChatRequest gestartet mit:', {
messagesCount: messages.length,
maxTokens,
});
console.log('sendChatRequest gestartet mit:', {
messagesCount: messages.length,
maxTokens,
});
try {
// Find model deployment from system message
let modelId = '550e8400-e29b-41d4-a716-446655440000'; // Default to GPT-O3-Mini
try {
// Find model deployment from system message
let modelId = '550e8400-e29b-41d4-a716-446655440000'; // Default to GPT-O3-Mini
const systemMessage = messages.find(
(msg) => msg.role === 'system' && msg.content.startsWith('MODEL:')
);
if (systemMessage) {
const deployment = systemMessage.content.split(':')[1].trim();
console.log('Modell in system Nachricht erkannt:', deployment);
const systemMessage = messages.find(
(msg) => msg.role === 'system' && msg.content.startsWith('MODEL:')
);
if (systemMessage) {
const deployment = systemMessage.content.split(':')[1].trim();
console.log('Modell in system Nachricht erkannt:', deployment);
// Map deployment to model ID
const deploymentToModelId: Record<string, string> = {
'gpt-o3-mini-se': '550e8400-e29b-41d4-a716-446655440000',
'gpt-4o-mini-se': '550e8400-e29b-41d4-a716-446655440004',
'gpt-4o-se': '550e8400-e29b-41d4-a716-446655440005',
};
// Map deployment to model ID
const deploymentToModelId: Record<string, string> = {
'gpt-o3-mini-se': '550e8400-e29b-41d4-a716-446655440000',
'gpt-4o-mini-se': '550e8400-e29b-41d4-a716-446655440004',
'gpt-4o-se': '550e8400-e29b-41d4-a716-446655440005',
};
modelId = deploymentToModelId[deployment] || modelId;
} else {
console.warn('Keine System-Nachricht mit MODEL-Präfix gefunden!');
}
modelId = deploymentToModelId[deployment] || modelId;
} else {
console.warn('Keine System-Nachricht mit MODEL-Präfix gefunden!');
}
console.log('Verwende Model ID:', modelId);
console.log('Verwende Model ID:', modelId);
// Filter out MODEL: system messages before sending to API
const filteredMessages = messages.filter(
(msg) => !(msg.role === 'system' && msg.content.startsWith('MODEL:'))
);
// Filter out MODEL: system messages before sending to API
const filteredMessages = messages.filter(
(msg) => !(msg.role === 'system' && msg.content.startsWith('MODEL:'))
);
// Send request to backend
const result = await chatApi.createCompletion({
messages: filteredMessages,
modelId,
temperature,
maxTokens,
});
// Send request to backend
const result = await chatApi.createCompletion({
messages: filteredMessages,
modelId,
temperature,
maxTokens,
});
if (!result) {
return 'Es tut mir leid, aber ich konnte keine Antwort generieren. Bitte stelle sicher, dass das Backend läuft.';
}
if (!result) {
return 'Es tut mir leid, aber ich konnte keine Antwort generieren. Bitte stelle sicher, dass das Backend läuft.';
}
return {
content: result.content,
usage: result.usage,
};
} catch (error) {
console.error('Fehler bei der Chat-Anfrage:', error);
return {
content: result.content,
usage: result.usage,
};
} catch (error) {
console.error('Fehler bei der Chat-Anfrage:', error);
if (error instanceof Error) {
console.error('Fehlerdetails:', {
name: error.name,
message: error.message,
stack: error.stack,
});
}
if (error instanceof Error) {
console.error('Fehlerdetails:', {
name: error.name,
message: error.message,
stack: error.stack,
});
}
return `Es tut mir leid, aber ich konnte keine Antwort generieren. Bitte stelle sicher, dass das Backend läuft. Fehlerdetails: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`;
}
return `Es tut mir leid, aber ich konnte keine Antwort generieren. Bitte stelle sicher, dass das Backend läuft. Fehlerdetails: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`;
}
}

View file

@ -5,249 +5,249 @@ import { spaceApi, type Space as ApiSpace, type SpaceMember as ApiSpaceMember }
// Re-export types with backwards-compatible naming (snake_case for mobile)
export type Space = {
id: string;
name: string;
description?: string;
owner_id: string;
created_at: string;
updated_at: string;
is_archived: boolean;
id: string;
name: string;
description?: string;
owner_id: string;
created_at: string;
updated_at: string;
is_archived: boolean;
};
export type SpaceMember = {
id: string;
space_id: string;
user_id: string;
role: 'owner' | 'admin' | 'member' | 'viewer';
invitation_status: 'pending' | 'accepted' | 'declined';
invited_by?: string;
invited_at: string;
joined_at?: string;
created_at: string;
updated_at: string;
id: string;
space_id: string;
user_id: string;
role: 'owner' | 'admin' | 'member' | 'viewer';
invitation_status: 'pending' | 'accepted' | 'declined';
invited_by?: string;
invited_at: string;
joined_at?: string;
created_at: string;
updated_at: string;
};
// Helper to convert API response to local format
function toLocalSpace(space: ApiSpace): Space {
return {
id: space.id,
name: space.name,
description: space.description,
owner_id: space.ownerId,
created_at: space.createdAt,
updated_at: space.updatedAt,
is_archived: space.isArchived,
};
return {
id: space.id,
name: space.name,
description: space.description,
owner_id: space.ownerId,
created_at: space.createdAt,
updated_at: space.updatedAt,
is_archived: space.isArchived,
};
}
function toLocalSpaceMember(member: ApiSpaceMember): SpaceMember {
return {
id: member.id,
space_id: member.spaceId,
user_id: member.userId,
role: member.role,
invitation_status: member.invitationStatus,
invited_by: member.invitedBy,
invited_at: member.invitedAt,
joined_at: member.joinedAt,
created_at: member.createdAt,
updated_at: member.updatedAt,
};
return {
id: member.id,
space_id: member.spaceId,
user_id: member.userId,
role: member.role,
invitation_status: member.invitationStatus,
invited_by: member.invitedBy,
invited_at: member.invitedAt,
joined_at: member.joinedAt,
created_at: member.createdAt,
updated_at: member.updatedAt,
};
}
/**
* Get all spaces for a user (both owned and member of)
*/
export async function getUserSpaces(userId: string): Promise<Space[]> {
try {
const spaces = await spaceApi.getUserSpaces();
return spaces.map(toLocalSpace);
} catch (error) {
console.error('Error in getUserSpaces:', error);
return [];
}
try {
const spaces = await spaceApi.getUserSpaces();
return spaces.map(toLocalSpace);
} catch (error) {
console.error('Error in getUserSpaces:', error);
return [];
}
}
/**
* Get spaces the user owns
*/
export async function getOwnedSpaces(userId: string): Promise<Space[]> {
try {
const spaces = await spaceApi.getOwnedSpaces();
return spaces.map(toLocalSpace);
} catch (error) {
console.error('Error in getOwnedSpaces:', error);
return [];
}
try {
const spaces = await spaceApi.getOwnedSpaces();
return spaces.map(toLocalSpace);
} catch (error) {
console.error('Error in getOwnedSpaces:', error);
return [];
}
}
/**
* Get a single space by ID
*/
export async function getSpace(spaceId: string): Promise<Space | null> {
try {
const space = await spaceApi.getSpace(spaceId);
if (!space) {
return null;
}
return toLocalSpace(space);
} catch (error) {
console.error('Error in getSpace:', error);
return null;
}
try {
const space = await spaceApi.getSpace(spaceId);
if (!space) {
return null;
}
return toLocalSpace(space);
} catch (error) {
console.error('Error in getSpace:', error);
return null;
}
}
/**
* Create a new space
*/
export async function createSpace(
userId: string,
name: string,
description?: string
userId: string,
name: string,
description?: string
): Promise<string | null> {
try {
const space = await spaceApi.createSpace(name, description);
return space?.id || null;
} catch (error) {
console.error('Error in createSpace:', error);
return null;
}
try {
const space = await spaceApi.createSpace(name, description);
return space?.id || null;
} catch (error) {
console.error('Error in createSpace:', error);
return null;
}
}
/**
* Update a space
*/
export async function updateSpace(
spaceId: string,
updates: { name?: string; description?: string; is_archived?: boolean }
spaceId: string,
updates: { name?: string; description?: string; is_archived?: boolean }
): Promise<boolean> {
try {
return await spaceApi.updateSpace(spaceId, {
name: updates.name,
description: updates.description,
isArchived: updates.is_archived,
});
} catch (error) {
console.error('Error in updateSpace:', error);
return false;
}
try {
return await spaceApi.updateSpace(spaceId, {
name: updates.name,
description: updates.description,
isArchived: updates.is_archived,
});
} catch (error) {
console.error('Error in updateSpace:', error);
return false;
}
}
/**
* Delete a space
*/
export async function deleteSpace(spaceId: string): Promise<boolean> {
try {
return await spaceApi.deleteSpace(spaceId);
} catch (error) {
console.error('Error in deleteSpace:', error);
return false;
}
try {
return await spaceApi.deleteSpace(spaceId);
} catch (error) {
console.error('Error in deleteSpace:', error);
return false;
}
}
/**
* Get members of a space
*/
export async function getSpaceMembers(spaceId: string): Promise<SpaceMember[]> {
try {
const members = await spaceApi.getSpaceMembers(spaceId);
return members.map(toLocalSpaceMember);
} catch (error) {
console.error('Error in getSpaceMembers:', error);
return [];
}
try {
const members = await spaceApi.getSpaceMembers(spaceId);
return members.map(toLocalSpaceMember);
} catch (error) {
console.error('Error in getSpaceMembers:', error);
return [];
}
}
/**
* Add a member to a space (invite)
*/
export async function inviteUserToSpace(
spaceId: string,
userId: string,
invitedByUserId: string,
role: 'admin' | 'member' | 'viewer' = 'member'
spaceId: string,
userId: string,
invitedByUserId: string,
role: 'admin' | 'member' | 'viewer' = 'member'
): Promise<boolean> {
try {
return await spaceApi.inviteUser(spaceId, userId, role);
} catch (error) {
console.error('Error in inviteUserToSpace:', error);
return false;
}
try {
return await spaceApi.inviteUser(spaceId, userId, role);
} catch (error) {
console.error('Error in inviteUserToSpace:', error);
return false;
}
}
/**
* Accept or decline a space invitation
*/
export async function respondToInvitation(
spaceId: string,
userId: string,
status: 'accepted' | 'declined'
spaceId: string,
userId: string,
status: 'accepted' | 'declined'
): Promise<boolean> {
try {
return await spaceApi.respondToInvitation(spaceId, status);
} catch (error) {
console.error('Error in respondToInvitation:', error);
return false;
}
try {
return await spaceApi.respondToInvitation(spaceId, status);
} catch (error) {
console.error('Error in respondToInvitation:', error);
return false;
}
}
/**
* Remove a member from a space
*/
export async function removeMember(spaceId: string, userId: string): Promise<boolean> {
try {
return await spaceApi.removeMember(spaceId, userId);
} catch (error) {
console.error('Error in removeMember:', error);
return false;
}
try {
return await spaceApi.removeMember(spaceId, userId);
} catch (error) {
console.error('Error in removeMember:', error);
return false;
}
}
/**
* Change a member's role
*/
export async function changeMemberRole(
spaceId: string,
userId: string,
newRole: 'admin' | 'member' | 'viewer'
spaceId: string,
userId: string,
newRole: 'admin' | 'member' | 'viewer'
): Promise<boolean> {
try {
return await spaceApi.changeMemberRole(spaceId, userId, newRole);
} catch (error) {
console.error('Error in changeMemberRole:', error);
return false;
}
try {
return await spaceApi.changeMemberRole(spaceId, userId, newRole);
} catch (error) {
console.error('Error in changeMemberRole:', error);
return false;
}
}
/**
* Get user's role in a space
*/
export async function getUserRoleInSpace(
spaceId: string,
userId: string
spaceId: string,
userId: string
): Promise<'owner' | 'admin' | 'member' | 'viewer' | null> {
try {
return await spaceApi.getUserRoleInSpace(spaceId);
} catch (error) {
console.error('Error in getUserRoleInSpace:', error);
return null;
}
try {
return await spaceApi.getUserRoleInSpace(spaceId);
} catch (error) {
console.error('Error in getUserRoleInSpace:', error);
return null;
}
}
/**
* Get pending space invitations for a user
*/
export async function getPendingInvitations(
userId: string
userId: string
): Promise<Array<{ invitation: SpaceMember; space: Space }>> {
try {
const invitations = await spaceApi.getPendingInvitations();
return invitations.map((inv) => ({
invitation: toLocalSpaceMember(inv.invitation),
space: toLocalSpace(inv.space),
}));
} catch (error) {
console.error('Error in getPendingInvitations:', error);
return [];
}
try {
const invitations = await spaceApi.getPendingInvitations();
return invitations.map((inv) => ({
invitation: toLocalSpaceMember(inv.invitation),
space: toLocalSpace(inv.space),
}));
} catch (error) {
console.error('Error in getPendingInvitations:', error);
return [];
}
}

View file

@ -5,159 +5,159 @@ import { templateApi, type Template as ApiTemplate } from './api';
// Re-export type with backwards-compatible naming (snake_case for mobile)
export interface Template {
id: string;
user_id: string;
name: string;
description: string | null;
system_prompt: string;
initial_question: string | null;
model_id: string | null;
color: string;
is_default: boolean;
document_mode: boolean;
created_at: string;
updated_at: string;
id: string;
user_id: string;
name: string;
description: string | null;
system_prompt: string;
initial_question: string | null;
model_id: string | null;
color: string;
is_default: boolean;
document_mode: boolean;
created_at: string;
updated_at: string;
}
// Helper to convert API response to local format
function toLocalTemplate(template: ApiTemplate): Template {
return {
id: template.id,
user_id: template.userId,
name: template.name,
description: template.description || null,
system_prompt: template.systemPrompt,
initial_question: template.initialQuestion || null,
model_id: template.modelId || null,
color: template.color,
is_default: template.isDefault,
document_mode: template.documentMode,
created_at: template.createdAt,
updated_at: template.updatedAt,
};
return {
id: template.id,
user_id: template.userId,
name: template.name,
description: template.description || null,
system_prompt: template.systemPrompt,
initial_question: template.initialQuestion || null,
model_id: template.modelId || null,
color: template.color,
is_default: template.isDefault,
document_mode: template.documentMode,
created_at: template.createdAt,
updated_at: template.updatedAt,
};
}
/**
* Lädt alle Vorlagen eines Benutzers
*/
export async function getTemplates(userId: string): Promise<Template[]> {
try {
const templates = await templateApi.getTemplates();
return templates.map(toLocalTemplate);
} catch (error) {
console.error('Fehler beim Laden der Vorlagen:', error);
return [];
}
try {
const templates = await templateApi.getTemplates();
return templates.map(toLocalTemplate);
} catch (error) {
console.error('Fehler beim Laden der Vorlagen:', error);
return [];
}
}
/**
* Lädt eine bestimmte Vorlage anhand ihrer ID
*/
export async function getTemplateById(templateId: string): Promise<Template | null> {
try {
const template = await templateApi.getTemplate(templateId);
if (!template) {
return null;
}
return toLocalTemplate(template);
} catch (error) {
console.error('Fehler beim Laden der Vorlage:', error);
return null;
}
try {
const template = await templateApi.getTemplate(templateId);
if (!template) {
return null;
}
return toLocalTemplate(template);
} catch (error) {
console.error('Fehler beim Laden der Vorlage:', error);
return null;
}
}
/**
* Erstellt eine neue Vorlage
*/
export async function createTemplate(
template: Omit<Template, 'id' | 'created_at' | 'updated_at'>
template: Omit<Template, 'id' | 'created_at' | 'updated_at'>
): Promise<Template | null> {
try {
const result = await templateApi.createTemplate({
name: template.name,
description: template.description || undefined,
systemPrompt: template.system_prompt,
initialQuestion: template.initial_question || undefined,
modelId: template.model_id || undefined,
color: template.color,
documentMode: template.document_mode,
});
try {
const result = await templateApi.createTemplate({
name: template.name,
description: template.description || undefined,
systemPrompt: template.system_prompt,
initialQuestion: template.initial_question || undefined,
modelId: template.model_id || undefined,
color: template.color,
documentMode: template.document_mode,
});
if (!result) {
console.error('Fehler beim Erstellen der Vorlage');
return null;
}
if (!result) {
console.error('Fehler beim Erstellen der Vorlage');
return null;
}
return toLocalTemplate(result);
} catch (error) {
console.error('Fehler beim Erstellen der Vorlage:', error);
return null;
}
return toLocalTemplate(result);
} catch (error) {
console.error('Fehler beim Erstellen der Vorlage:', error);
return null;
}
}
/**
* Aktualisiert eine bestehende Vorlage
*/
export async function updateTemplate(
templateId: string,
updates: Partial<Omit<Template, 'id' | 'user_id' | 'created_at' | 'updated_at'>>
templateId: string,
updates: Partial<Omit<Template, 'id' | 'user_id' | 'created_at' | 'updated_at'>>
): Promise<boolean> {
try {
const apiUpdates: Parameters<typeof templateApi.updateTemplate>[1] = {};
try {
const apiUpdates: Parameters<typeof templateApi.updateTemplate>[1] = {};
if (updates.name !== undefined) apiUpdates.name = updates.name;
if (updates.description !== undefined)
apiUpdates.description = updates.description || undefined;
if (updates.system_prompt !== undefined) apiUpdates.systemPrompt = updates.system_prompt;
if (updates.initial_question !== undefined)
apiUpdates.initialQuestion = updates.initial_question || undefined;
if (updates.model_id !== undefined) apiUpdates.modelId = updates.model_id || undefined;
if (updates.color !== undefined) apiUpdates.color = updates.color;
if (updates.document_mode !== undefined) apiUpdates.documentMode = updates.document_mode;
if (updates.name !== undefined) apiUpdates.name = updates.name;
if (updates.description !== undefined)
apiUpdates.description = updates.description || undefined;
if (updates.system_prompt !== undefined) apiUpdates.systemPrompt = updates.system_prompt;
if (updates.initial_question !== undefined)
apiUpdates.initialQuestion = updates.initial_question || undefined;
if (updates.model_id !== undefined) apiUpdates.modelId = updates.model_id || undefined;
if (updates.color !== undefined) apiUpdates.color = updates.color;
if (updates.document_mode !== undefined) apiUpdates.documentMode = updates.document_mode;
return await templateApi.updateTemplate(templateId, apiUpdates);
} catch (error) {
console.error('Fehler beim Aktualisieren der Vorlage:', error);
return false;
}
return await templateApi.updateTemplate(templateId, apiUpdates);
} catch (error) {
console.error('Fehler beim Aktualisieren der Vorlage:', error);
return false;
}
}
/**
* Löscht eine Vorlage
*/
export async function deleteTemplate(templateId: string): Promise<boolean> {
try {
return await templateApi.deleteTemplate(templateId);
} catch (error) {
console.error('Fehler beim Löschen der Vorlage:', error);
return false;
}
try {
return await templateApi.deleteTemplate(templateId);
} catch (error) {
console.error('Fehler beim Löschen der Vorlage:', error);
return false;
}
}
/**
* Setzt eine Vorlage als Standard
*/
export async function setDefaultTemplate(templateId: string, userId: string): Promise<boolean> {
try {
return await templateApi.setDefaultTemplate(templateId);
} catch (error) {
console.error('Fehler beim Setzen der Standard-Vorlage:', error);
return false;
}
try {
return await templateApi.setDefaultTemplate(templateId);
} catch (error) {
console.error('Fehler beim Setzen der Standard-Vorlage:', error);
return false;
}
}
/**
* Holt die Standard-Vorlage des Benutzers
*/
export async function getDefaultTemplate(userId: string): Promise<Template | null> {
try {
const template = await templateApi.getDefaultTemplate();
if (!template) {
return null;
}
return toLocalTemplate(template);
} catch (error) {
console.error('Fehler beim Laden der Standard-Vorlage:', error);
return null;
}
try {
const template = await templateApi.getDefaultTemplate();
if (!template) {
return null;
}
return toLocalTemplate(template);
} catch (error) {
console.error('Fehler beim Laden der Standard-Vorlage:', error);
return null;
}
}