added batching and buildgraph for fireflies

This commit is contained in:
Arjun 2026-01-07 20:20:30 +05:30 committed by Ramnique Singh
parent 6eb918f8d8
commit 85024dd69b
3 changed files with 46 additions and 36 deletions

View file

@ -9,24 +9,23 @@ import { bus } from '../runs/bus.js';
* and note creation agents sequentially on content files * and note creation agents sequentially on content files
*/ */
const KNOWLEDGE_SOURCE_DIR = path.join(WorkDir, 'gmail_sync');
const NOTES_OUTPUT_DIR = path.join(WorkDir, 'notes'); const NOTES_OUTPUT_DIR = path.join(WorkDir, 'notes');
const NOTE_CREATION_AGENT = 'note_creation'; const NOTE_CREATION_AGENT = 'note_creation';
/** /**
* Read all markdown files from the knowledge source directory * Read all markdown files from the specified source directory
*/ */
async function getContentFiles(): Promise<{ path: string; content: string }[]> { async function getContentFiles(sourceDir: string): Promise<{ path: string; content: string }[]> {
if (!fs.existsSync(KNOWLEDGE_SOURCE_DIR)) { if (!fs.existsSync(sourceDir)) {
console.log(`Knowledge source directory not found: ${KNOWLEDGE_SOURCE_DIR}`); console.log(`Knowledge source directory not found: ${sourceDir}`);
return []; return [];
} }
const files: { path: string; content: string }[] = []; const files: { path: string; content: string }[] = [];
const entries = fs.readdirSync(KNOWLEDGE_SOURCE_DIR); const entries = fs.readdirSync(sourceDir);
for (const entry of entries) { for (const entry of entries) {
const fullPath = path.join(KNOWLEDGE_SOURCE_DIR, entry); const fullPath = path.join(sourceDir, entry);
const stat = fs.statSync(fullPath); const stat = fs.statSync(fullPath);
if (stat.isFile() && entry.endsWith('.md')) { if (stat.isFile() && entry.endsWith('.md')) {
@ -53,9 +52,9 @@ async function waitForRunCompletion(runId: string): Promise<void> {
} }
/** /**
* Run note creation agent on content to extract entities and create/update notes * Run note creation agent on a batch of files to extract entities and create/update notes
*/ */
async function createNotes(content: string, sourceFile: string): Promise<string> { async function createNotesFromBatch(files: { path: string; content: string }[], batchNumber: number): Promise<string> {
// Ensure notes output directory exists // Ensure notes output directory exists
if (!fs.existsSync(NOTES_OUTPUT_DIR)) { if (!fs.existsSync(NOTES_OUTPUT_DIR)) {
fs.mkdirSync(NOTES_OUTPUT_DIR, { recursive: true }); fs.mkdirSync(NOTES_OUTPUT_DIR, { recursive: true });
@ -66,19 +65,22 @@ async function createNotes(content: string, sourceFile: string): Promise<string>
agentId: NOTE_CREATION_AGENT, agentId: NOTE_CREATION_AGENT,
}); });
// Pass the content and source file info to the agent // Build message with all files in the batch
const message = `Process the following source file and create/update obsidian notes. let message = `Process the following ${files.length} source files and create/update obsidian notes.\n\n`;
message += `**Instructions:**\n`;
message += `- Extract entities (people, organizations, projects, topics) from ALL files below\n`;
message += `- Create or update notes in "notes" directory (workspace-relative paths like "notes/People/Name.md")\n`;
message += `- If the same entity appears in multiple files, merge the information into a single note\n`;
message += `- Use workspace tools to read existing notes and write updates\n`;
message += `- Follow the note templates and guidelines in your instructions\n\n`;
message += `---\n\n`;
**Source file:** ${path.basename(sourceFile)} // Add each file's content
files.forEach((file, idx) => {
**Instructions:** message += `## Source File ${idx + 1}: ${path.basename(file.path)}\n\n`;
- Extract entities (people, organizations, projects, topics) message += file.content;
- Create or update notes in "notes" directory (workspace-relative paths like "notes/People/Name.md") message += `\n\n---\n\n`;
- Use workspace tools to read existing notes and write updates });
- Follow the note templates and guidelines in your instructions
**Content:**
${content}`;
await createMessage(run.id, message); await createMessage(run.id, message);
@ -89,26 +91,33 @@ ${content}`;
} }
/** /**
* Build the knowledge graph from all content files * Build the knowledge graph from all content files in the specified source directory
*/ */
export async function buildGraph(): Promise<void> { export async function buildGraph(sourceDir: string): Promise<void> {
const contentFiles = await getContentFiles(); const contentFiles = await getContentFiles(sourceDir);
if (contentFiles.length === 0) { if (contentFiles.length === 0) {
console.log(`No files found in ${sourceDir}`);
return; return;
} }
console.log(`Processing ${contentFiles.length} files for knowledge graph...`); const BATCH_SIZE = 10; // Process 10 emails per agent run
const totalBatches = Math.ceil(contentFiles.length / BATCH_SIZE);
console.log(`Processing ${contentFiles.length} files from ${path.basename(sourceDir)} in ${totalBatches} batches (${BATCH_SIZE} files per batch)...`);
// Process files in batches
for (let i = 0; i < contentFiles.length; i += BATCH_SIZE) {
const batch = contentFiles.slice(i, i + BATCH_SIZE);
const batchNumber = Math.floor(i / BATCH_SIZE) + 1;
// Process each file with the note creation agent
// The agent will extract entities and create/update notes
for (const file of contentFiles) {
try { try {
console.log(`Processing ${path.basename(file.path)}...`); console.log(`Processing batch ${batchNumber}/${totalBatches} (${batch.length} files)...`);
await createNotes(file.content, file.path); await createNotesFromBatch(batch, batchNumber);
console.log(`Batch ${batchNumber}/${totalBatches} complete`);
} catch (error) { } catch (error) {
console.error(`Error processing ${path.basename(file.path)}:`, error); console.error(`Error processing batch ${batchNumber}:`, error);
// Continue with next file // Continue with next batch
} }
} }
@ -116,8 +125,9 @@ export async function buildGraph(): Promise<void> {
} }
/** /**
* Main entry point * Main entry point - processes gmail_sync directory by default
*/ */
export async function init() { export async function init() {
await buildGraph(); const defaultSourceDir = path.join(WorkDir, 'gmail_sync');
await buildGraph(defaultSourceDir);
} }

View file

@ -438,7 +438,7 @@ async function syncMeetings() {
if (newCount > 0) { if (newCount > 0) {
console.log('\n[Fireflies] Starting knowledge graph build...'); console.log('\n[Fireflies] Starting knowledge graph build...');
try { try {
await buildGraph(); await buildGraph(SYNC_DIR);
} catch (error) { } catch (error) {
console.error('[Fireflies] Error building knowledge graph:', error); console.error('[Fireflies] Error building knowledge graph:', error);
} }

View file

@ -285,7 +285,7 @@ async function performSync() {
// Build knowledge graph after successful sync // Build knowledge graph after successful sync
console.log("\nStarting knowledge graph build..."); console.log("\nStarting knowledge graph build...");
try { try {
await buildGraph(); await buildGraph(SYNC_DIR);
} catch (error) { } catch (error) {
console.error("Error building knowledge graph:", error); console.error("Error building knowledge graph:", error);
} }