|
12 | 12 | SuccessResponse, |
13 | 13 | extract_chat_messages, |
14 | 14 | get_session_or_404, |
15 | | - normalize_record_id, |
16 | 15 | ) |
17 | 16 | from open_notebook.database.repository import ensure_record_id, repo_query |
18 | | -from open_notebook.domain.notebook import ( |
19 | | - ChatSession, |
20 | | - Note, |
21 | | - Notebook, |
22 | | - Source, |
23 | | - SourceInsight, |
24 | | -) |
| 17 | +from open_notebook.domain.notebook import ChatSession, Notebook |
25 | 18 | from open_notebook.exceptions import ( |
26 | 19 | NotFoundError, |
27 | 20 | OpenNotebookError, |
28 | 21 | ) |
29 | 22 | from open_notebook.graphs.chat import graph as chat_graph |
| 23 | +from open_notebook.utils import token_count |
| 24 | +from open_notebook.utils.context_builder import build_notebook_context |
30 | 25 | from open_notebook.utils.graph_utils import get_session_message_count |
31 | 26 |
|
32 | 27 | router = APIRouter() |
@@ -402,100 +397,12 @@ async def build_context(request: BuildContextRequest): |
402 | 397 | if not notebook: |
403 | 398 | raise HTTPException(status_code=404, detail="Notebook not found") |
404 | 399 |
|
405 | | - context_data: dict[str, list[dict[str, str]]] = {"sources": [], "notes": []} |
406 | | - total_content = "" |
407 | | - |
408 | | - # Process context configuration if provided |
409 | | - if request.context_config: |
410 | | - # Process sources |
411 | | - for source_id, status in request.context_config.get("sources", {}).items(): |
412 | | - if "not in" in status: |
413 | | - continue |
414 | | - |
415 | | - try: |
416 | | - # Add table prefix if not present |
417 | | - full_source_id = normalize_record_id("source", source_id) |
418 | | - |
419 | | - try: |
420 | | - source = await Source.get(full_source_id) |
421 | | - except Exception: |
422 | | - continue |
423 | | - |
424 | | - if "insights" in status: |
425 | | - source_context = await source.get_context(context_size="short") |
426 | | - context_data["sources"].append(source_context) |
427 | | - total_content += str(source_context) |
428 | | - elif "full content" in status: |
429 | | - source_context = await source.get_context(context_size="long") |
430 | | - context_data["sources"].append(source_context) |
431 | | - total_content += str(source_context) |
432 | | - except Exception as e: |
433 | | - logger.warning(f"Error processing source {source_id}: {str(e)}") |
434 | | - continue |
435 | | - |
436 | | - # Process notes |
437 | | - for note_id, status in request.context_config.get("notes", {}).items(): |
438 | | - if "not in" in status: |
439 | | - continue |
440 | | - |
441 | | - try: |
442 | | - # Add table prefix if not present |
443 | | - full_note_id = normalize_record_id("note", note_id) |
444 | | - note = await Note.get(full_note_id) |
445 | | - if not note: |
446 | | - continue |
447 | | - |
448 | | - if "full content" in status: |
449 | | - note_context = note.get_context(context_size="long") |
450 | | - context_data["notes"].append(note_context) |
451 | | - total_content += str(note_context) |
452 | | - except Exception as e: |
453 | | - logger.warning(f"Error processing note {note_id}: {str(e)}") |
454 | | - continue |
455 | | - else: |
456 | | - # Default behavior - include all sources and notes with short context |
457 | | - sources = await notebook.get_sources() |
458 | | - try: |
459 | | - insights_by_source = await SourceInsight.get_for_sources( |
460 | | - [source.id for source in sources if source.id] |
461 | | - ) |
462 | | - except Exception as e: |
463 | | - # Match the per-source fallback below: a hiccup fetching |
464 | | - # insights shouldn't fail the whole context request. |
465 | | - logger.warning(f"Error batch-fetching source insights: {str(e)}") |
466 | | - insights_by_source = {} |
467 | | - for source in sources: |
468 | | - try: |
469 | | - source_context = await source.get_context( |
470 | | - context_size="short", |
471 | | - insights=insights_by_source.get(source.id or "", []), |
472 | | - ) |
473 | | - context_data["sources"].append(source_context) |
474 | | - total_content += str(source_context) |
475 | | - except Exception as e: |
476 | | - logger.warning(f"Error processing source {source.id}: {str(e)}") |
477 | | - continue |
478 | | - |
479 | | - notes = await notebook.get_notes() |
480 | | - for note in notes: |
481 | | - try: |
482 | | - note_context = note.get_context(context_size="short") |
483 | | - context_data["notes"].append(note_context) |
484 | | - total_content += str(note_context) |
485 | | - except Exception as e: |
486 | | - logger.warning(f"Error processing note {note.id}: {str(e)}") |
487 | | - continue |
488 | | - |
489 | | - # Calculate character and token counts |
| 400 | + context_data, total_content = await build_notebook_context( |
| 401 | + notebook, request.context_config |
| 402 | + ) |
| 403 | + |
490 | 404 | char_count = len(total_content) |
491 | | - # Use token count utility if available |
492 | | - try: |
493 | | - from open_notebook.utils import token_count |
494 | | - |
495 | | - estimated_tokens = token_count(total_content) if total_content else 0 |
496 | | - except ImportError: |
497 | | - # Fallback to simple estimation |
498 | | - estimated_tokens = char_count // 4 |
| 405 | + estimated_tokens = token_count(total_content) if total_content else 0 |
499 | 406 |
|
500 | 407 | return BuildContextResponse( |
501 | 408 | context=context_data, token_count=estimated_tokens, char_count=char_count |
|
0 commit comments