frontend_nyla/src/api/teamsbotApi.ts
2026-02-16 00:16:03 +01:00

291 lines
8.1 KiB
TypeScript

import api from '../api';
// ============================================================================
// TYPES & INTERFACES
// ============================================================================
export interface TeamsbotSession {
id: string;
instanceId: string;
mandateId: string;
meetingLink: string;
botName: string;
backgroundImageUrl?: string;
status: 'pending' | 'joining' | 'active' | 'leaving' | 'ended' | 'error';
startedAt?: string;
endedAt?: string;
startedByUserId: string;
bridgeSessionId?: string;
meetingChatId?: string;
summary?: string;
errorMessage?: string;
transcriptSegmentCount: number;
botResponseCount: number;
creationDate?: string;
lastModified?: string;
}
export interface TeamsbotTranscript {
id: string;
sessionId: string;
speaker?: string;
text: string;
timestamp: string;
confidence: number;
language?: string;
isFinal: boolean;
}
export interface TeamsbotBotResponse {
id: string;
sessionId: string;
responseText: string;
responseType: 'audio' | 'chat' | 'both';
detectedIntent: 'addressed' | 'question' | 'proactive' | 'none';
reasoning?: string;
triggeredByTranscriptId?: string;
modelName?: string;
processingTime: number;
priceCHF: number;
timestamp?: string;
}
export type TeamsbotResponseChannel = 'voice' | 'chat' | 'both';
export type TeamsbotJoinMode = 'systemBot' | 'anonymous' | 'userAccount';
export interface TeamsbotConfig {
botName: string;
backgroundImageUrl?: string;
aiSystemPrompt: string;
responseMode: 'auto' | 'manual' | 'transcribeOnly';
responseChannel: TeamsbotResponseChannel;
language: string;
voiceId?: string;
browserBotUrl?: string;
botAccountEmail?: string;
botAccountPassword?: string;
triggerIntervalSeconds: number;
triggerCooldownSeconds: number;
contextWindowSegments: number;
}
export interface TeamsbotSessionStats {
transcriptSegments: number;
botResponses: number;
totalCostCHF: number;
totalProcessingTime: number;
speakers: string[];
}
export interface StartSessionRequest {
meetingLink: string;
botName?: string;
backgroundImageUrl?: string;
connectionId?: string;
joinMode?: TeamsbotJoinMode;
}
export interface ConfigUpdateRequest {
botName?: string;
backgroundImageUrl?: string;
aiSystemPrompt?: string;
responseMode?: 'auto' | 'manual' | 'transcribeOnly';
responseChannel?: TeamsbotResponseChannel;
language?: string;
voiceId?: string;
browserBotUrl?: string;
botAccountEmail?: string;
botAccountPassword?: string;
triggerIntervalSeconds?: number;
triggerCooldownSeconds?: number;
contextWindowSegments?: number;
}
// Voice/Language Types (from Google TTS API)
export interface VoiceLanguage {
code: string;
name: string;
}
export interface VoiceOption {
name: string;
languageCodes: string[];
ssmlGender: string;
naturalSampleRateHertz: number;
}
// SSE Event Types
export interface TeamsbotSSEEvent {
type: 'transcript' | 'botResponse' | 'analysis' | 'suggestedResponse' | 'statusChange' | 'error' | 'ping' | 'sessionState';
data: any;
timestamp?: string;
}
// ============================================================================
// API FUNCTIONS
// ============================================================================
/**
* Start a new Teams Bot session.
*/
export async function startSession(instanceId: string, request: StartSessionRequest): Promise<{ session: TeamsbotSession }> {
const response = await api.post(`/api/teamsbot/${instanceId}/sessions`, request);
return response.data;
}
/**
* List all sessions for a feature instance.
*/
export async function listSessions(instanceId: string, includeEnded = true): Promise<{ sessions: TeamsbotSession[] }> {
const response = await api.get(`/api/teamsbot/${instanceId}/sessions`, {
params: { includeEnded },
});
return response.data;
}
/**
* Get session details with transcripts and bot responses.
*/
export async function getSession(
instanceId: string,
sessionId: string,
includeTranscripts = true,
includeResponses = true,
): Promise<{
session: TeamsbotSession;
transcripts?: TeamsbotTranscript[];
botResponses?: TeamsbotBotResponse[];
stats?: TeamsbotSessionStats;
}> {
const response = await api.get(`/api/teamsbot/${instanceId}/sessions/${sessionId}`, {
params: { includeTranscripts, includeResponses },
});
return response.data;
}
/**
* Stop an active session.
*/
export async function stopSession(instanceId: string, sessionId: string): Promise<{ status: string; sessionId: string }> {
const response = await api.post(`/api/teamsbot/${instanceId}/sessions/${sessionId}/stop`);
return response.data;
}
/**
* Delete a session and all related data.
*/
export async function deleteSession(instanceId: string, sessionId: string): Promise<{ deleted: boolean }> {
const response = await api.delete(`/api/teamsbot/${instanceId}/sessions/${sessionId}`);
return response.data;
}
/**
* Get teamsbot configuration (instance-level defaults).
*/
export async function getConfig(instanceId: string): Promise<{ config: TeamsbotConfig }> {
const response = await api.get(`/api/teamsbot/${instanceId}/config`);
return response.data;
}
/**
* Update teamsbot configuration (instance-level defaults).
*/
export async function updateConfig(instanceId: string, updates: ConfigUpdateRequest): Promise<{ config: TeamsbotConfig }> {
const response = await api.put(`/api/teamsbot/${instanceId}/config`, updates);
return response.data;
}
/**
* Get per-user settings merged with instance defaults.
*/
export async function getUserSettings(instanceId: string): Promise<{ settings: any; effectiveConfig: TeamsbotConfig }> {
const response = await api.get(`/api/teamsbot/${instanceId}/settings`);
return response.data;
}
/**
* Update per-user settings.
*/
export async function updateUserSettings(instanceId: string, updates: ConfigUpdateRequest): Promise<{ settings: any; effectiveConfig: TeamsbotConfig }> {
const response = await api.put(`/api/teamsbot/${instanceId}/settings`, updates);
return response.data;
}
/**
* Reset per-user settings to instance defaults.
*/
export async function resetUserSettings(instanceId: string): Promise<{ settings: null; effectiveConfig: TeamsbotConfig }> {
const response = await api.delete(`/api/teamsbot/${instanceId}/settings`);
return response.data;
}
export interface SystemBot {
id: string;
mandateId: string;
name: string;
email: string;
isActive: boolean;
creationDate?: string;
}
/**
* List system bot accounts for this mandate.
*/
export async function listSystemBots(instanceId: string): Promise<{ bots: SystemBot[] }> {
const response = await api.get(`/api/teamsbot/${instanceId}/system-bots`);
return response.data;
}
/**
* Test TTS voice with AI-generated sample text. Returns base64-encoded audio.
*/
export async function testVoice(
instanceId: string,
botName: string,
language: string,
voiceId?: string,
): Promise<{ success: boolean; audio?: string; format?: string; text?: string; error?: string }> {
const response = await api.post(`/api/teamsbot/${instanceId}/voice/test`, {
botName,
language,
voiceId,
});
return response.data;
}
/**
* Fetch available TTS languages from Google Cloud.
* Returns array of language codes (e.g. ["de-DE", "en-US", ...])
*/
export async function fetchLanguages(): Promise<string[]> {
try {
const response = await api.get('/voice-google/languages');
return response.data?.languages || [];
} catch {
return [];
}
}
/**
* Fetch available TTS voices for a language from Google Cloud.
*/
export async function fetchVoices(languageCode: string): Promise<VoiceOption[]> {
try {
const response = await api.get('/voice-google/voices', {
params: { languageCode },
});
return response.data?.voices || [];
} catch {
return [];
}
}
/**
* Create an SSE EventSource for live session streaming.
* Returns the EventSource instance for the caller to manage.
*/
export function createSessionStream(instanceId: string, sessionId: string): EventSource {
const baseUrl = api.defaults.baseURL || '';
const url = `${baseUrl}/api/teamsbot/${instanceId}/sessions/${sessionId}/stream`;
return new EventSource(url, { withCredentials: true });
}