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
5 changes: 4 additions & 1 deletion backend/actions/bundle.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import json
import logging
import re
from pathlib import Path
from typing import List, Dict, Any

logger = logging.getLogger(__name__)


PROJECT_ROOT = Path(__file__).resolve().parent.parent
EMBEDDINGS_DIR = PROJECT_ROOT / "embeddings"
Expand Down Expand Up @@ -68,4 +71,4 @@ def main() -> Path:

if __name__ == "__main__":
bundle_path = main()
print(f"Bundled embeddings written to {bundle_path}")
logger.info(f"Bundled embeddings written to {bundle_path}")
29 changes: 16 additions & 13 deletions backend/actions/process_slides.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@

processor = SlideProcessor()
async for chunk in processor.stream_from_bytes(pdf_bytes, "slides.pdf", "Nov 2024 Meetup"):
print(chunk)
logger.info(chunk)
"""

import argparse
import asyncio
import base64
import json
import logging
import os
import time
from pathlib import Path
Expand All @@ -31,6 +32,8 @@

from clients import get_embedding

logger = logging.getLogger(__name__)

EMBEDDINGS_DIR = "embeddings"

# OpenAI model for vision analysis
Expand Down Expand Up @@ -119,10 +122,10 @@ async def _analyze_slide_image(self, base64_image: str, page_num: int) -> dict |
return json.loads(response_text.strip())

except json.JSONDecodeError as e:
print(f" Warning: Could not parse JSON for page {page_num}: {e}")
logger.warning(f" Warning: Could not parse JSON for page {page_num}: {e}")
return None
except Exception as e:
print(f" Warning: Vision analysis failed for page {page_num}: {e}")
logger.warning(f" Warning: Vision analysis failed for page {page_num}: {e}")
return None

def _extract_text_from_analysis(self, analysis: dict | None) -> str:
Expand Down Expand Up @@ -169,15 +172,15 @@ async def stream_from_bytes(
- page_num: current page number
- total_pages: total number of pages
"""
print(f"Processing: {filename}")
logger.info(f"Processing: {filename}")

with fitz.open(stream=pdf_bytes, filetype="pdf") as doc:
total_pages = len(doc)
print(f"Found {total_pages} pages")
logger.info(f"Found {total_pages} pages")

for page_num, page in enumerate(doc, start=1):
start_time = time.time()
print(f" Processing Page {page_num}/{total_pages}...", end=" ", flush=True)
logger.info(f" Processing Page {page_num}/{total_pages}...")

# Render page to image
base64_image = self._render_page_to_base64(page)
Expand All @@ -188,14 +191,14 @@ async def stream_from_bytes(

# Skip if no content extracted
if not text.strip():
print("Skipped (no content)")
logger.info("Skipped (no content)")
continue

# Create embedding
embedding = await self._get_embedding(text)

elapsed = time.time() - start_time
print(f"Done ({elapsed:.2f}s)")
logger.info(f"Done ({elapsed:.2f}s)")

yield {
"session_info": session_info,
Expand Down Expand Up @@ -271,9 +274,9 @@ async def process(
with open(output_path, "w", encoding="utf-8") as f:
json.dump(embedded_chunks, f, indent=2, ensure_ascii=False)

print(f"\nSaved to: {output_path}")
logger.info(f"\nSaved to: {output_path}")

print(f"Total slides processed: {len(embedded_chunks)}")
logger.info(f"Total slides processed: {len(embedded_chunks)}")

return embedded_chunks

Expand Down Expand Up @@ -349,12 +352,12 @@ async def async_main():
with open(output_path, "w", encoding="utf-8") as f:
json.dump(chunks, f, indent=2, ensure_ascii=False)

print(f"\nTotal slides processed: {len(chunks)}")
logger.info(f"\nTotal slides processed: {len(chunks)}")
if not args.no_save:
print(f"Saved to: {output_path}")
logger.info(f"Saved to: {output_path}")

except Exception as e:
print(f"Error: {e}")
logger.error(f"Error: {e}")
raise SystemExit(1)


Expand Down
21 changes: 12 additions & 9 deletions backend/actions/transcribe_youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import argparse
import asyncio
import json
import logging
import os
import re
from os.path import join, dirname
Expand All @@ -29,6 +30,8 @@

from clients import get_embedding

logger = logging.getLogger(__name__)

EMBEDDINGS_DIR = "embeddings"


Expand Down Expand Up @@ -131,12 +134,12 @@ async def transcribe(
if not video_id:
raise ValueError(f"Could not extract video ID from: {url}")

print(f"Fetching transcript for: {video_id}")
logger.info(f"Fetching transcript for: {video_id}")
transcript = self._fetch_transcript(video_id)
full_text, char_to_time = self._build_char_to_time_map(transcript)
sentences = self._split_into_sentences(full_text)

print(f"Processing {len(sentences)} sentences into chunks...")
logger.info(f"Processing {len(sentences)} sentences into chunks...")

# Process chunks and embed directly
embedded_chunks = []
Expand All @@ -155,7 +158,7 @@ async def transcribe(
start_time = self._get_time_for_char_position(chunk_start_char, char_to_time)
start_seconds = int(start_time)

print(f" Embedding chunk {chunk_index + 1}...", end=" ", flush=True)
logger.info(f" Embedding chunk {chunk_index + 1}...")
embedding = await self._get_embedding(chunk_text)

embedded_chunks.append({
Expand All @@ -164,7 +167,7 @@ async def transcribe(
"timestamp": f"https://www.youtube.com/watch?v={video_id}&t={start_seconds}s",
"embedding": embedding
})
print("Done")
logger.info("Done")

chunk_index += 1

Expand All @@ -186,7 +189,7 @@ async def transcribe(
start_time = self._get_time_for_char_position(chunk_start_char, char_to_time)
start_seconds = int(start_time)

print(f" Embedding chunk {chunk_index + 1}...", end=" ", flush=True)
logger.info(f" Embedding chunk {chunk_index + 1}...")
embedding = await self._get_embedding(chunk_text)

embedded_chunks.append({
Expand All @@ -195,7 +198,7 @@ async def transcribe(
"timestamp": f"https://www.youtube.com/watch?v={video_id}&t={start_seconds}s",
"embedding": embedding
})
print("Done")
logger.info("Done")

# Save to embeddings directory (optional)
if save_local:
Expand All @@ -211,9 +214,9 @@ async def transcribe(
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(embedded_chunks, f, indent=2, ensure_ascii=False)

print(f"\nSaved to: {output_path}")
logger.info(f"\nSaved to: {output_path}")

print(f"Total chunks: {len(embedded_chunks)}")
logger.info(f"Total chunks: {len(embedded_chunks)}")

return embedded_chunks

Expand Down Expand Up @@ -274,7 +277,7 @@ async def async_main():
)
await transcriber.transcribe(args.url, args.session, args.output, save_local=not args.no_save)
except Exception as e:
print(f"Error: {e}")
logger.error(f"Error: {e}")
raise SystemExit(1)


Expand Down
6 changes: 3 additions & 3 deletions backend/routes/voice_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ async def start_voice_trace(request: VoiceTraceStartRequest, req: Request):
Start a new voice trace session.
Called when voice mode connects.
"""
print(f"[VOICE TRACE] Start requested. LANGFUSE_ENABLED={LANGFUSE_ENABLED}")
logger.info(f"[VOICE TRACE] Start requested. LANGFUSE_ENABLED={LANGFUSE_ENABLED}")

if not LANGFUSE_ENABLED:
print("[VOICE TRACE] Langfuse disabled")
logger.info("[VOICE TRACE] Langfuse disabled")
return VoiceTraceStartResponse(trace_id="", enabled=False)

user_id = req.client.host if req.client else "unknown"
Expand All @@ -70,7 +70,7 @@ async def start_voice_trace(request: VoiceTraceStartRequest, req: Request):
user_id=user_id
)

print(f"[VOICE TRACE] Created trace: {trace_id}")
logger.info(f"[VOICE TRACE] Created trace: {trace_id}")
return VoiceTraceStartResponse(trace_id=trace_id, enabled=True)


Expand Down
26 changes: 13 additions & 13 deletions backend/services/langfuse_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ def init_langfuse():
"""
global _langfuse_client

print(f"[LANGFUSE] init_langfuse called. LANGFUSE_ENABLED={LANGFUSE_ENABLED}")
logger.info(f"[LANGFUSE] init_langfuse called. LANGFUSE_ENABLED={LANGFUSE_ENABLED}")

if not LANGFUSE_ENABLED:
print("[LANGFUSE] Tracing disabled")
logger.info("[LANGFUSE] Tracing disabled")
return

public_key = os.getenv("LANGFUSE_PUBLIC_KEY")
Expand All @@ -52,11 +52,11 @@ def init_langfuse():
)

if not _langfuse_client.auth_check():
print(f"[LANGFUSE] Authentication FAILED for {base_url}")
logger.error(f"[LANGFUSE] Authentication FAILED for {base_url}")
_langfuse_client = None
return

print(f"[LANGFUSE] Authentication successful for {base_url}")
logger.info(f"[LANGFUSE] Authentication successful for {base_url}")

# Set up OpenInference instrumentation to capture agent tool calls
# Configure OTLP exporter to send to Langfuse
Expand Down Expand Up @@ -98,10 +98,10 @@ def create_voice_trace(session_id: str, user_id: str) -> str:
Returns the session_id which is used to group traces.
"""
if not _langfuse_client:
print("[LANGFUSE] Client not initialized - voice trace skipped")
logger.warning("[LANGFUSE] Client not initialized - voice trace skipped")
return ""

print(f"[LANGFUSE] Initializing voice session: {session_id}")
logger.info(f"[LANGFUSE] Initializing voice session: {session_id}")

# Store session info for creating per-turn traces
_voice_sessions[session_id] = {
Expand All @@ -114,7 +114,7 @@ def create_voice_trace(session_id: str, user_id: str) -> str:
}
}

print(f"[LANGFUSE] Voice session initialized: {session_id}")
logger.info(f"[LANGFUSE] Voice session initialized: {session_id}")
return session_id


Expand All @@ -140,11 +140,11 @@ def add_voice_generation(
if turn["user_input"] and turn["assistant_output"]:
_flush_turn(session_id)
turn["user_input"] = content
print(f"[LANGFUSE] User transcript: {content[:50]}...")
logger.info(f"[LANGFUSE] User transcript: {content[:50]}...")

elif event_type == "assistant_response":
turn["assistant_output"] = content
print(f"[LANGFUSE] Assistant response: {content[:50]}...")
logger.info(f"[LANGFUSE] Assistant response: {content[:50]}...")
# Flush the turn now that we have both input and output
if turn["user_input"]:
_flush_turn(session_id)
Expand All @@ -155,7 +155,7 @@ def add_voice_generation(
"call": content,
"result": metadata.get("result", "") if metadata else ""
})
print(f"[LANGFUSE] Function call: {content[:50]}...")
logger.info(f"[LANGFUSE] Function call: {content[:50]}...")


def _flush_turn(session_id: str) -> None:
Expand Down Expand Up @@ -217,11 +217,11 @@ def _flush_turn(session_id: str) -> None:
metadata={"tool_index": i}
)
except Exception as e:
print(f"[LANGFUSE] Error creating tool span: {e}")
logger.error(f"[LANGFUSE] Error creating tool span: {e}")

span.update(output=assistant_output)

print(f"[LANGFUSE] Flushed turn {turn_num} for session {session_id}")
logger.info(f"[LANGFUSE] Flushed turn {turn_num} for session {session_id}")

# Reset current turn
session["current_turn"] = {
Expand Down Expand Up @@ -251,4 +251,4 @@ def end_voice_trace(trace_id: str, duration_ms: int, message_count: int) -> None
# Cleanup session
_voice_sessions.pop(session_id, None)
_langfuse_client.flush()
print(f"[LANGFUSE] Ended voice session: {session_id} ({session['turn_count']} turns, {duration_ms}ms)")
logger.info(f"[LANGFUSE] Ended voice session: {session_id} ({session['turn_count']} turns, {duration_ms}ms)")