Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
873 changes: 5 additions & 868 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/app/api/builder/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export async function POST(req: Request) {
d.instructions,
request.stream ?? false,
distinctId,
'builder_edit_prompt',
);
case ApiAction.SummaryOfPrompt:
const summaryData = request.data as SummaryOfPromptData;
Expand All @@ -42,6 +43,7 @@ export async function POST(req: Request) {
summaryData.fullPrompt,
request.stream ?? false,
distinctId,
'builder_summary_prompt',
);

default:
Expand All @@ -59,6 +61,7 @@ async function createNewPrompt(data: SessionBuilderData, distinctId?: string) {
createTemplatePrompt,
createPromptContent(data),
distinctId,
'builder_create_prompt',
);

console.log('[i] Created new prompt:', fullPrompt);
Expand Down
38 changes: 35 additions & 3 deletions src/app/api/llamaUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
getHostSessionById,
updateUserSession,
increaseSessionsCount,
getSessionOwner,
} from '@/lib/db';
import { initializeCrossPollination } from '@/lib/crossPollination';
import { getLLM } from '@/lib/modelConfig';
Expand All @@ -22,6 +23,9 @@ export async function finishedResponse(
systemPrompt: string,
userPrompt: string,
distinctId?: string,
tag?: string,
sessionIds?: string[],
hostIds?: string[],
) {
console.log('[i] Generating finished response:', {
systemPrompt: systemPrompt?.substring(0, 100) + '...',
Expand All @@ -44,6 +48,9 @@ export async function finishedResponse(
},
],
distinctId,
tag,
sessionIds,
hostIds,
});

console.log('[i] Completion response:', JSON.stringify(response));
Expand Down Expand Up @@ -78,6 +85,9 @@ export async function finishedResponse(
},
],
distinctId,
tag,
sessionIds,
hostIds,
});

console.log('[i] Fallback to small model successful:', JSON.stringify(fallbackResponse));
Expand Down Expand Up @@ -178,6 +188,9 @@ export async function handleGenerateAnswer(
const sessionData = await getHostSessionById(messageData.sessionId);
console.log(`[i] Session data:`, sessionData);

// Get session owner (host) for analytics
const hostId = await getSessionOwner(messageData.sessionId);

const basicFacilitationPrompt = await getPromptInstructions(
'BASIC_FACILITATION_PROMPT',
);
Expand Down Expand Up @@ -208,6 +221,9 @@ ${sessionData?.critical ? `- Key Points: ${sessionData.critical}` : ''}`;
const message = await chatEngine.chat({
messages: formattedMessages as ChatMessage[],
distinctId,
tag: 'chat',
sessionIds: [messageData.sessionId],
hostIds: hostId ? [hostId] : undefined,
});
console.log('[i] Response:', message);

Expand Down Expand Up @@ -241,9 +257,12 @@ export async function handleResponse(
userPrompt: string,
stream: boolean,
distinctId?: string,
tag?: string,
sessionIds?: string[],
hostIds?: string[],
) {
if (stream) {
const streamData = streamResponse(systemPrompt, userPrompt, distinctId);
const streamData = streamResponse(systemPrompt, userPrompt, distinctId, tag, sessionIds, hostIds);
return new NextResponse(streamData, {
headers: {
'Content-Type': 'text/event-stream',
Expand All @@ -252,13 +271,20 @@ export async function handleResponse(
},
});
} else {
const response = await finishedResponse(systemPrompt, userPrompt, distinctId);
const response = await finishedResponse(systemPrompt, userPrompt, distinctId, tag, sessionIds, hostIds);
console.log('response from finishedResponse:', response);
return NextResponse.json({ fullPrompt: response });
}
}

function streamResponse(systemPrompt: string, userPrompt: string, distinctId?: string) {
function streamResponse(
systemPrompt: string,
userPrompt: string,
distinctId?: string,
tag?: string,
sessionIds?: string[],
hostIds?: string[],
) {
const encoder = new TextEncoder();

return new ReadableStream({
Expand All @@ -279,6 +305,9 @@ function streamResponse(systemPrompt: string, userPrompt: string, distinctId?: s
},
],
distinctId,
tag,
sessionIds,
hostIds,
});

if (response) {
Expand Down Expand Up @@ -317,6 +346,9 @@ function streamResponse(systemPrompt: string, userPrompt: string, distinctId?: s
},
],
distinctId,
tag,
sessionIds,
hostIds,
});

console.log('[i] Gemini fallback successful in stream');
Expand Down
7 changes: 7 additions & 0 deletions src/lib/characterGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getLLM } from '@/lib/modelConfig';
import * as db from '@/lib/db';
import { getSessionOwner } from '@/lib/db';

export async function generateCharacters(sessionId: string): Promise<string> {
// Get session context
Expand All @@ -15,6 +16,9 @@ export async function generateCharacters(sessionId: string): Promise<string> {
throw new Error('Session data not found');
}

// Get session owner (host) for analytics
const hostId = await getSessionOwner(sessionId);

// Set up LLM with SMALL model configuration
const llm = getLLM('SMALL', 0.8);

Expand Down Expand Up @@ -45,6 +49,9 @@ Create authentic characters with diverse perspectives while avoiding assumptions

const response = await llm.chat({
messages: [{ role: 'user', content: prompt }],
tag: 'character_generation',
sessionIds: [sessionId],
hostIds: hostId ? [hostId] : undefined,
});

return response || '';
Expand Down
17 changes: 17 additions & 0 deletions src/lib/crossPollinationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getAllChatMessagesInOrder,
getAllMessagesForSessionSorted,
getHostSessionById,
getSessionOwner,
} from '@/lib/db';
import { getPromptInstructions } from './promptsCache';
import { getSession } from '@auth0/nextjs-auth0';
Expand All @@ -30,6 +31,7 @@ export class CrossPollinationManager {
private lastCrossPollination: number | null = null;
private sessionData: any = null;
private distinctId: string | undefined;
private hostId: string | null = null;

constructor(config: CrossPollinationConfig) {
this.config = config;
Expand All @@ -38,6 +40,13 @@ export class CrossPollinationManager {
this.generateEngine = getLLM('LARGE', 0.3);
}

private async getHostId(): Promise<string | null> {
if (this.hostId === null) {
this.hostId = await getSessionOwner(this.config.sessionId);
}
return this.hostId;
}

private async getDistinctId() {
if (!this.distinctId) {
try {
Expand Down Expand Up @@ -97,6 +106,7 @@ export class CrossPollinationManager {
);

const distinctId = await this.getDistinctId();
const hostId = await this.getHostId();

// 4. Analyze the current thread to determine if cross-pollination is appropriate
const response = await this.analyzeEngine.chat({
Expand All @@ -119,6 +129,9 @@ Based on this information, should I introduce cross-pollination now? Answer with
},
],
distinctId,
tag: 'cross_pollination_analysis',
sessionIds: [this.config.sessionId],
hostIds: hostId ? [hostId] : undefined,
});

const responseText = response.trim().toUpperCase();
Expand Down Expand Up @@ -213,6 +226,7 @@ Based on this information, should I introduce cross-pollination now? Answer with
await getPromptInstructions('CROSS_POLLINATION');

const distinctId = await this.getDistinctId();
const hostId = await this.getHostId();

// Make a single LLM call to analyze and generate a question
const response = await this.generateEngine.chat({
Expand Down Expand Up @@ -252,6 +266,9 @@ Based on this information, should I introduce cross-pollination now? Answer with
},
],
distinctId,
tag: 'cross_pollination_question',
sessionIds: [this.config.sessionId],
hostIds: hostId ? [hostId] : undefined,
});

const responseText = response.trim();
Expand Down
70 changes: 70 additions & 0 deletions src/lib/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1755,3 +1755,73 @@ export async function updateThreadRating(
return null;
}
}

/**
* Get the owner (host) user ID for a session
* @param sessionId The session ID to look up
* @returns The user_id of the owner, or null if not found
*/
export async function getSessionOwner(
sessionId: string,
): Promise<string | null> {
console.log('[i] Database Operation: getSessionOwner');
try {
const db = await dbPromise;
const result = await db
.selectFrom(permissionsTableName)
.select('user_id')
.where('resource_id', '=', sessionId)
.where('resource_type', '=', 'SESSION')
.where('role', '=', 'owner')
.executeTakeFirst();

return result?.user_id || null;
} catch (error) {
console.error('Error getting session owner:', error);
return null;
}
}

/**
* Get owners for multiple sessions at once
* @param sessionIds Array of session IDs to look up
* @returns Map of sessionId -> owner user_id (null if not found)
*/
export async function getSessionOwners(
sessionIds: string[],
): Promise<Map<string, string | null>> {
console.log('[i] Database Operation: getSessionOwners');
const result = new Map<string, string | null>();

if (!sessionIds.length) return result;

try {
const db = await dbPromise;
const rows = await db
.selectFrom(permissionsTableName)
.select(['resource_id', 'user_id'])
.where('resource_id', 'in', sessionIds)
.where('resource_type', '=', 'SESSION')
.where('role', '=', 'owner')
.execute();

// Initialize all session IDs with null
for (const id of sessionIds) {
result.set(id, null);
}

// Fill in found owners
for (const row of rows) {
result.set(row.resource_id, row.user_id);
}

return result;
} catch (error) {
console.error('Error getting session owners:', error);
// Return map with all nulls on error
for (const id of sessionIds) {
result.set(id, null);
}
return result;
}
}
1 change: 1 addition & 0 deletions src/lib/export/llamaExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export async function extractDataWithLlama(
content: `Here are the conversations to extract data from:\n\n${formattedContext}\n\n${extractUserPrompt}`,
},
],
tag: 'data_export',
});

// Clean the response if it includes markdown code blocks
Expand Down
1 change: 1 addition & 0 deletions src/lib/formAnswerGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ ${attempts > 0 ? `Previous attempt failed with: ${lastError}\nIMPORTANT: Ensure
{ role: 'system', content: systemContent },
{ role: 'user', content: userContent },
],
tag: 'form_answer_generation',
});

console.log('\n=== LLM Response ===');
Expand Down
9 changes: 9 additions & 0 deletions src/lib/modelConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ export class LLM {
async chat(params: {
messages: ChatMessage[];
distinctId?: string;
tag?: string;
sessionIds?: string[];
hostIds?: string[];
}): Promise<string> {
const startTime = Date.now();
// All LLMs actually accept the same message format, even though they specify it differently.
Expand Down Expand Up @@ -189,6 +192,9 @@ export class LLM {
$ai_output_tokens: outputTokens,
$ai_status: 'success',
$ai_trace_id: crypto.randomUUID(),
tag: params.tag,
session_ids: params.sessionIds,
host_ids: params.hostIds,
},
});
}
Expand Down Expand Up @@ -237,6 +243,9 @@ export class LLM {
$ai_status: 'error',
$ai_error: error instanceof Error ? error.message : String(error),
$ai_trace_id: crypto.randomUUID(),
tag: params.tag,
session_ids: params.sessionIds,
host_ids: params.hostIds,
},
});
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/monica/analyzeQueryType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export async function analyzeQueryType(
content: classificationPrompt,
},
],
tag: 'query_type_analysis',
});

const queryClassification = JSON.parse(response) as QueryClassification;
Expand Down
1 change: 1 addition & 0 deletions src/lib/monica/fileAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ${content.substring(0, 4000)} // Limit content length to avoid token limits
content: analysisPrompt,
},
],
tag: 'file_analysis',
});

console.log('[i] Raw analysis response:', response);
Expand Down
8 changes: 8 additions & 0 deletions src/lib/monica/monicaMultiSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { OpenAIMessage } from '../types';
import { getPromptInstructions } from '../promptsCache';
import { getSessionContent } from './qdrantQuery';
import { getLLM } from '../modelConfig';
import { getSessionOwners } from '@/lib/db';

export async function generateMultiSessionAnswer(
sessionIds: string[],
Expand Down Expand Up @@ -149,6 +150,10 @@ ${contextData?.critical ? `Key Points: ${contextData?.critical}` : ''}`,

const chatEngine = getLLM("LARGE", 0.3);

// Get session owners (hosts) for analytics
const ownersMap = await getSessionOwners(sessionIds);
const hostIds = Array.from(ownersMap.values()).filter((id): id is string => id !== null);

const chatHistoryWithoutInitialWelcoming = chatHistory.slice(1);
const chatHistoryForPrompt =
chatHistoryWithoutInitialWelcoming.length > 0
Expand Down Expand Up @@ -201,6 +206,9 @@ ${qdrantContent?.KNOWLEDGE ? `### Relevant Knowledge Content:\n${qdrantContent.K
},
],
distinctId,
tag: 'monica_ai',
sessionIds,
hostIds: hostIds.length > 0 ? hostIds : undefined,
});

console.log('[i] Received response: ', response);
Expand Down
Loading