Add context windows, web search, streamed answers, overlay move/resize; overhaul docs
- Context windows (contexts/*.yaml) scope answers to a defined domain - Optional DuckDuckGo web search behind ai.web_search.enabled (default off) - Stream partial answers into the overlay at first-token time - Default Whisper to local base.en (~9x faster); offline model loading - Priority-ordered loopback detection (BlackHole > Teams device) - Overlay: drag interior to move, edges to resize - Stop tracking model binaries (models/ is gitignored) - README/CLAUDE.md overhaul + tracked config.example.yaml Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
27
main.py
27
main.py
@@ -5,6 +5,7 @@ Meeting Assistant - Real-time AI Copilot for Meetings
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import yaml
|
||||
import threading
|
||||
import logging
|
||||
@@ -255,16 +256,29 @@ class MeetingAssistant:
|
||||
|
||||
try:
|
||||
context = self.context_manager.get_context()
|
||||
result = self.ai_engine.answer_question(question, context, source)
|
||||
|
||||
# Stream the answer into the overlay as it generates: first words
|
||||
# appear at first-token time instead of after the full generation.
|
||||
asked_by = speaker or ("You" if source == "microphone" else "Them")
|
||||
shown_q = f"({asked_by}) {question}"
|
||||
suggested_early = self.ai_engine.is_suggested(question)
|
||||
t_start = time.time()
|
||||
first_shown = [False]
|
||||
|
||||
def on_partial(text_so_far):
|
||||
if not first_shown[0]:
|
||||
first_shown[0] = True
|
||||
print(f" ⚡ first words on screen after {time.time() - t_start:.1f}s")
|
||||
self.overlay.show_answer(text_so_far + " ▌", shown_q, suggested_early)
|
||||
|
||||
result = self.ai_engine.answer_question(
|
||||
question, context, source, on_partial=on_partial)
|
||||
|
||||
if not result or not result.get("text"):
|
||||
return # interrupted or empty
|
||||
|
||||
answer = result["text"]
|
||||
suggested = result.get("suggested", False)
|
||||
|
||||
asked_by = speaker or ("You" if source == "microphone" else "Them")
|
||||
shown_q = f"({asked_by}) {question}"
|
||||
self.overlay.show_answer(answer, shown_q, suggested)
|
||||
self.logger.info(f"Q [{asked_by}]: {question}")
|
||||
self.logger.info(f"A: {answer}")
|
||||
@@ -305,7 +319,10 @@ class MeetingAssistant:
|
||||
self.ai_engine.interrupt()
|
||||
self.answering = True
|
||||
try:
|
||||
answer = self.ai_engine.answer_from_image(image_path)
|
||||
answer = self.ai_engine.answer_from_image(
|
||||
image_path,
|
||||
on_partial=lambda t: self.overlay.show_answer(
|
||||
t + " ▌", "Screen question", suggested=False))
|
||||
if not answer:
|
||||
return
|
||||
self.overlay.show_answer(answer, "Screen question", suggested=False)
|
||||
|
||||
Reference in New Issue
Block a user