Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
5e7ecbe
rebase and bring all change before 0709 into main
Catrunaround Jul 9, 2025
7309fde
Test commit
Catrunaround Jul 11, 2025
aa72daa
deleted Test commit
Catrunaround Jul 11, 2025
271878b
add condition on video paragraph if less than 5
Catrunaround Jul 11, 2025
ee2a8a4
fixed video page for now
Catrunaround Jul 11, 2025
bddfdff
Merge branch 'augcog:main' into main
Catrunaround Jul 16, 2025
8f406e2
build a new paeg class
Catrunaround Jul 16, 2025
2f136c7
local change push
Catrunaround Jul 18, 2025
28c5744
merge
Catrunaround Jul 18, 2025
3031a80
fix problem for ## empty content
Catrunaround Jul 18, 2025
7ff74ae
title helper fixed for roar academt
Catrunaround Jul 22, 2025
dc8320f
update index helper
Catrunaround Jul 24, 2025
7cdb7c6
finish roar academy
Catrunaround Jul 25, 2025
6e2de2b
Merge branch 'second-week'
Catrunaround Jul 25, 2025
9e3cbad
Merge branch 'augcog:main' into main
Catrunaround Jul 25, 2025
b2f7aca
command change
Catrunaround Jul 25, 2025
3c8fefa
fixing pdf converter
Catrunaround Jul 29, 2025
8f9e63f
fixing (2)
Catrunaround Jul 29, 2025
4190115
fix video scraper
Catrunaround Aug 1, 2025
64cb755
fix cs61a added new chunk create
Catrunaround Aug 8, 2025
93fdac0
add conversion ignore, change chunk from save pkl file to data base, …
Catrunaround Aug 14, 2025
d6239f8
changed from pkl to data base and added extra information into db
Catrunaround Aug 22, 2025
8b8b375
merge from main
Catrunaround Aug 22, 2025
2506f03
merge from main
Catrunaround Aug 22, 2025
17dd425
Merge branch 'local_commit' into main
Catrunaround Aug 22, 2025
c0d1e3a
added Assessment question in video
Catrunaround Aug 26, 2025
fd301ba
Merge branch 'augcog:main' into main
Catrunaround Aug 26, 2025
37089e0
Merge branch 'local_commit' of https://github.com/Catrunaround/tai in…
Catrunaround Aug 26, 2025
98651a9
add assessment question and strict order for all kinds of file
Catrunaround Aug 26, 2025
d17f771
Merge branch 'augcog:main' into main
Catrunaround Aug 27, 2025
ff1310b
add speaker role into video
Catrunaround Aug 27, 2025
d96f855
create a fix function for problem table
Catrunaround Aug 28, 2025
4cba80b
create a fix function for problem table
Catrunaround Aug 28, 2025
aa55a27
merge
Catrunaround Aug 29, 2025
bea3407
create a fix function for problem table
Catrunaround Aug 28, 2025
a7de7fc
Merge remote-tracking branch 'origin/local_commit' into local_commit
Catrunaround Aug 29, 2025
7bfb8b1
fixed url, uuid and relative path in db
Catrunaround Aug 29, 2025
9d77db4
backup
Catrunaround Sep 5, 2025
e0ca09c
add guess speaker function
Catrunaround Sep 9, 2025
421099a
merge
Catrunaround Sep 9, 2025
6446322
temp change need to be clean
Catrunaround Sep 12, 2025
cf7e664
Merge main branch into feature branch
Catrunaround Sep 12, 2025
a539738
finalize data base next step is create update db function
Catrunaround Sep 16, 2025
078b6c0
Merge branch 'augcog:main' into main
Catrunaround Sep 17, 2025
250506b
add ssplit db for each course and colletive db for all course.
Catrunaround Sep 19, 2025
319a8e7
add Cladue code support for file_conversion_router and refector the a…
Catrunaround Sep 19, 2025
507541a
deleted old useless file, added data base mereger function
Catrunaround Sep 23, 2025
d9dcf9c
Merge branch 'augcog:main' into main
Catrunaround Sep 23, 2025
778979a
Merge branch 'local_commit'
Catrunaround Sep 23, 2025
09f3a0f
change database merger
Catrunaround Oct 2, 2025
f927130
Merge branch 'local_commit'
Catrunaround Oct 2, 2025
318c3b7
Merge branch 'augcog:main' into main
Catrunaround Oct 2, 2025
66056d3
code refactor fore title handle.py
Catrunaround Oct 2, 2025
556fb2b
add validator function for db.
Catrunaround Oct 2, 2025
262bb8f
add helper for title handle
Catrunaround Oct 3, 2025
ddc93bd
update scraper can try multi times
Catrunaround Oct 7, 2025
fa0be72
add helper for title handle
Catrunaround Oct 7, 2025
08d53db
add file_rearangement folder
Catrunaround Oct 10, 2025
850809a
mvp version of file rearangement
Catrunaround Oct 10, 2025
dbce0dc
update readme
Catrunaround Oct 15, 2025
9a51f35
Merge branch 'augcog:main' into main
Catrunaround Oct 28, 2025
62e4609
Merge branch 'augcog:main' into main
Catrunaround Oct 31, 2025
08b0fb1
add middle json
Catrunaround Oct 31, 2025
4dd8f03
Merge branch 'main' of https://github.com/Catrunaround/tai
Catrunaround Oct 31, 2025
0f9a19c
command change
Catrunaround Oct 31, 2025
7aa279b
add the pdf bbox and search structure
Catrunaround Oct 31, 2025
918f6a2
implemented sentence citation service function
Catrunaround Nov 6, 2025
85dbde5
remove test files
Catrunaround Nov 6, 2025
852dcff
add playlist information to metadata
Catrunaround Nov 6, 2025
e1fcfac
Merge branch 'accurate_position'
Catrunaround Nov 6, 2025
4f46649
fix scraper and implement conversion accurate reference
Catrunaround Nov 11, 2025
3c8756d
finalized new prompt and add file_discription and new key concept
Catrunaround Nov 13, 2025
0f57a15
added new json formate and streaming
Catrunaround Nov 21, 2025
c4622e3
streaming
Catrunaround Nov 21, 2025
ded9029
restore to origin
Catrunaround Nov 21, 2025
cf74ea4
back to depoly
Catrunaround Nov 21, 2025
21d8c12
json response
Catrunaround Nov 21, 2025
9515b6e
enable json
FranardoHuang Nov 21, 2025
3c0edcd
unadd audio
FranardoHuang Nov 21, 2025
c268d09
rewrite the prompt
FranardoHuang Dec 2, 2025
9de0958
remove unuse file
Catrunaround Dec 2, 2025
9c6515b
add new prompt
Catrunaround Dec 3, 2025
c296355
revert the change
FranardoHuang Dec 3, 2025
fa3b04f
add inline json
FranardoHuang Dec 4, 2025
3adae64
new json prompt
Catrunaround Dec 5, 2025
f232c1c
json streaming and prompt turning can be better
FranardoHuang Dec 5, 2025
3af9ecb
fuxk
FranardoHuang Dec 5, 2025
6ce3868
fix
FranardoHuang Dec 5, 2025
1bbfe1a
Removed redundant code
FranardoHuang Dec 5, 2025
8356628
fix
FranardoHuang Dec 5, 2025
68afc20
Removed redundant code
FranardoHuang Dec 5, 2025
416a814
Restore RAG prompt improvements after removing bad commit
Catrunaround Dec 12, 2025
69861fc
command change
Catrunaround Dec 13, 2025
eaec037
merge
FranardoHuang Dec 13, 2025
92be3c2
add web service for rag and modify rag_generation prompt
Catrunaround Dec 16, 2025
fe661d4
Merge branch 'final_develop' of https://github.com/Catrunaround/tai i…
Catrunaround Dec 16, 2025
14e8508
add code block
Catrunaround Dec 16, 2025
6ba5176
add code block and muti-level heading
Catrunaround Dec 16, 2025
1db1c9c
Merge branch 'final_develop' of https://github.com/Catrunaround/tai i…
Catrunaround Dec 16, 2025
94eee22
Merge branch 'final_develop' of https://github.com/Catrunaround/tai i…
Catrunaround Dec 16, 2025
2a556d6
Merge branch 'final_develop' of https://github.com/Catrunaround/tai i…
Catrunaround Dec 17, 2025
d813d17
Merge branch 'final_develop' of https://github.com/Catrunaround/tai i…
Catrunaround Dec 17, 2025
f349e4f
Merge branch 'final_develop' of github.com:Catrunaround/tai into fina…
FranardoHuang Dec 17, 2025
f439f15
add thinking in the json
Catrunaround Dec 17, 2025
ecdd60e
remove level info
Catrunaround Dec 17, 2025
10e81d7
remove limit
Catrunaround Dec 24, 2025
b48cc01
add openai model for testing
Catrunaround Jan 24, 2026
292afdd
fix some bugs on openai formate
FranardoHuang Jan 28, 2026
2290b05
add a timer and four mode
Catrunaround Jan 30, 2026
9313b42
prompt fixed
Catrunaround Jan 30, 2026
230a2c1
test for both local model and gpt5.2 model
FranardoHuang Jan 30, 2026
5931ae5
add many debug statments
FranardoHuang Jan 30, 2026
f480983
Merge main into final_develop: combine vLLM OpenAI API with 4-mode sy…
Catrunaround Jan 30, 2026
ad85ac6
delete unuse tests
Catrunaround Jan 30, 2026
4075670
remove some reduntent prompt
Catrunaround Feb 4, 2026
867fe8a
feat: 4-mode system, RAG improvements, file conversion enhancements
Catrunaround Feb 4, 2026
3842878
remove unuse functions
Catrunaround Feb 4, 2026
5e2340d
Merge branch '38428782c802ecf9ec5cf5b71a9dfb84a8b72379' into yk_fork_…
FranardoHuang Feb 5, 2026
5161c0f
fixed bug between openai format and vllm format.
FranardoHuang Feb 5, 2026
d601824
remove example in prompt
FranardoHuang Feb 6, 2026
64ab199
remove the load local env function
FranardoHuang Feb 8, 2026
7978ffa
refactor prompt
FranardoHuang Feb 8, 2026
34104dc
sync text tutor prompt source with approved export wording
Catrunaround Feb 9, 2026
3832064
refactor regular text prompt to template-based addendums
Catrunaround Feb 9, 2026
450f6cd
structure the prompt
Catrunaround Feb 9, 2026
91b48a1
remove unuse code
Catrunaround Feb 13, 2026
f4b7e93
remove unuse code
Catrunaround Feb 13, 2026
a4ec966
import error
Catrunaround Feb 13, 2026
3b6bcca
add citation show in frontend
Catrunaround Feb 13, 2026
3c6eae2
add citation show in frontend
Catrunaround Feb 13, 2026
06b0f3f
add citation show in frontend
Catrunaround Feb 13, 2026
de14aab
Merge branch 'main' of https://github.com/Catrunaround/tai
Catrunaround Feb 13, 2026
af44645
add prompt
Catrunaround Feb 13, 2026
d5f65a6
refactor and update openai prompt
Catrunaround Feb 22, 2026
46c6c2c
add file description
Catrunaround Feb 26, 2026
6e735c0
temp
Catrunaround Feb 27, 2026
fdde6a8
add purpose to outline
Catrunaround Mar 2, 2026
5c888d9
add local model to tutor mode
Catrunaround Mar 3, 2026
7b27a8b
remove .claude/settings.json and add .claude/ to .gitignore
Catrunaround Mar 3, 2026
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
15 changes: 1 addition & 14 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
{
"model": "sonnet",
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -title 'Claude Code' -subtitle 'Session Complete' -message \"Finished working in $(basename \"$PWD\")\" -sound default -timeout 10"
}
]
}
]
}
"model": "sonnet"
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"python-envs.defaultEnvManager": "ms-python.python:conda",
"python-envs.defaultPackageManager": "ms-python.python:conda",
"python-envs.pythonProjects": []
}
9 changes: 8 additions & 1 deletion ai_chatbot_backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,21 @@ admin_password=123
DATA_DIR=data

# LLM Configuration
# Options: local, remote, mock
# Options: local, remote, mock, openai
# local = connects to external vLLM servers (OpenAI-compatible API)
# remote = use legacy remote API endpoint
# mock = use mock responses for testing
# openai = use OpenAI API (requires OPENAI_API_KEY)
llm_mode=mock
# URL for remote model API (used when llm_mode=remote)
remote_model_url=https://tai.berkeley.edu/api/chat

# OpenAI Configuration (used when llm_mode=openai)
# API key for OpenAI - required when llm_mode=openai
OPENAI_API_KEY=sk-your-api-key-here
# Model to use (e.g., gpt-4o, gpt-4o-mini)
OPENAI_MODEL=gpt-4o

# vLLM Server Configuration (used when llm_mode=local)
# These settings configure connections to external vLLM servers running OpenAI-compatible APIs
# The backend server can run on a different machine from the vLLM servers
Expand Down
3 changes: 3 additions & 0 deletions ai_chatbot_backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,6 @@ data/
exports/
*.db

audio/*
# Claude Code settings
.claude/
119 changes: 90 additions & 29 deletions ai_chatbot_backend/app/api/routes/completions.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
# Consolidated completions router
import time
from typing import List
from app.api.deps import verify_api_token
from app.core.models.chat_completion import (
GeneralCompletionParams,
FileCompletionParams,
PracticeCompletionParams,
PageContentParams,
GeneratePagesParams,
Message,
ResponseDelta,
TextToSpeechParams,
VoiceTranscriptParams,
AudioTranscript,
)
from app.dependencies.model import get_model_engine, get_whisper_engine
from app.services.rag_retriever import top_k_selector
from app.services.rag_generation import (
format_chat_msg,
generate_chat_response
)
from app.dependencies.model import get_model_engine, get_whisper_engine, get_engine_for_mode
from app.services.query import top_k_selector
from app.services.generation.chat import run_chat_pipeline
from app.services.generation.tutor import run_tutor_pipeline
from app.services.generation.message_format import format_chat_msg
from app.services.request_timer import RequestTimer
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import JSONResponse, StreamingResponse
from sqlalchemy.orm import Session
from app.core.dbs.metadata_db import get_metadata_db
from app.services.file_service import file_service
from app.services.problem_service import ProblemService
from app.services.audio_service import audio_to_text, audio_stream_parser
from app.services.chat_service import (
chat_stream_parser,
from app.services.audio.stt import audio_to_text, audio_stream_parser
from app.services.audio.tts import (
format_audio_text_message,
audio_generator,
tts_parsor,
get_speaker_name
)
from app.services.memory_synopsis_service import MemorySynopsisService
from app.services.memory.service import MemorySynopsisService

router = APIRouter()

Expand All @@ -57,8 +59,27 @@ async def create_completion(
db: Session = Depends(get_metadata_db),
_: bool = Depends(verify_api_token)
):
# Get the pre-initialized pipeline
llm_engine = get_model_engine()
# Create timer for tracking request latency
timer = RequestTimer(request_id=str(time.time_ns()))
timer.mark("request_received")

# Dynamically select LLM mode based on tutor_mode flag
from app.config import settings
try:
llm_mode = settings.get_llm_mode_for_request(params.tutor_mode)
print(f"[INFO] Request mode: tutor_mode={params.tutor_mode}, selected LLM: {llm_mode.value}")
llm_engine = get_engine_for_mode(llm_mode.value)
except Exception as e:
# If tutor mode fails and fallback is enabled, use local model
if params.tutor_mode and settings.tutor_fallback_enabled:
print(f"[WARNING] Failed to initialize {llm_mode.value} for tutor mode: {e}")
print(f"[WARNING] Falling back to local model")
llm_engine = get_engine_for_mode("local")
else:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"LLM service unavailable: {str(e)}"
)
audio_text = None
if params.audio:
whisper_engine = get_whisper_engine()
Expand Down Expand Up @@ -91,34 +112,74 @@ async def create_completion(
elif isinstance(params, PracticeCompletionParams):
problem_content = _get_problem_content(params, db)

response, reference_list = await generate_chat_response(
params.messages,
# Dispatch to chat or tutor pipeline
pipeline_fn = run_tutor_pipeline if params.tutor_mode else run_chat_pipeline
result = await pipeline_fn(
messages=params.messages,
user_focus=getattr(params, 'user_focus', None),
answer_content=getattr(params, 'answer_content', None),
problem_content=problem_content,
stream=params.stream,
course=params.course_code,
engine=llm_engine,
audio_response=params.audio_response,
sid=sid
sid=sid,
timer=timer,
audio_text=audio_text,
)

if params.stream:
return StreamingResponse(
chat_stream_parser(
response,
reference_list,
params.audio_response,
audio_text=audio_text,
messages=format_chat_msg(params.messages),
engine=llm_engine,
old_sid=sid,
course_code=params.course_code
),
media_type="text/event-stream"
)
return StreamingResponse(result, media_type="text/event-stream")
else:
return JSONResponse(ResponseDelta(text=response).model_dump_json(exclude_unset=True))
return JSONResponse(ResponseDelta(text=result).model_dump_json(exclude_unset=True))

@router.post("/page-content")
async def generate_page_content(
params: PageContentParams,
_: bool = Depends(verify_api_token),
):
"""Generate content for a single outline page using the local vLLM model."""
from app.services.generation.tutor.page_content import run_page_content_pipeline

try:
llm_engine = get_engine_for_mode("local")
except Exception as e:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Local LLM service unavailable: {str(e)}"
)

result = run_page_content_pipeline(params, llm_engine)
return StreamingResponse(result, media_type="text/event-stream")


@router.post("/generate-pages")
async def generate_pages(
params: GeneratePagesParams,
_: bool = Depends(verify_api_token),
):
"""Combined pipeline: generate outline (OpenAI) + all page contents (local vLLM) in one SSE stream."""
from app.services.generation.tutor.generate_pages import run_generate_pages_pipeline

try:
openai_engine = get_engine_for_mode("openai")
except Exception as e:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"OpenAI service unavailable: {str(e)}"
)

try:
local_engine = get_engine_for_mode("local")
except Exception as e:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Local LLM service unavailable: {str(e)}"
)

result = run_generate_pages_pipeline(params, openai_engine, local_engine)
return StreamingResponse(result, media_type="text/event-stream")


@router.post("/tts")
async def text_to_speech(
Expand Down
47 changes: 47 additions & 0 deletions ai_chatbot_backend/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LLMModeEnum(str, Enum):
local = "local"
remote = "remote"
mock = "mock"
openai = "openai"


class Settings(BaseSettings):
Expand All @@ -37,6 +38,35 @@ class Settings(BaseSettings):
)
remote_model_url: str = Field(description="URL for remote model API")

# OpenAI Configuration (for llm_mode=openai)
openai_api_key: Optional[str] = Field(
default=None,
description="OpenAI API key for OpenAI mode",
alias="OPENAI_API_KEY"
)
openai_model: str = Field(
default="gpt-4o",
description="OpenAI model to use (e.g., gpt-4o, gpt-4o-mini)",
alias="OPENAI_MODEL"
)

# Conditional LLM Mode Configuration
tutor_llm_mode: Optional[LLMModeEnum] = Field(
default=None,
description="LLM mode for tutor modes (TEXT_CHAT_TUTOR, VOICE_TUTOR). Defaults to 'openai' if not set.",
alias="TUTOR_LLM_MODE"
)
regular_llm_mode: Optional[LLMModeEnum] = Field(
default=None,
description="LLM mode for regular modes (TEXT_CHAT_REG, VOICE_REGULAR). Defaults to 'local' if not set.",
alias="REGULAR_LLM_MODE"
)
tutor_fallback_enabled: bool = Field(
default=True,
description="Enable fallback to local model if OpenAI fails for tutor mode",
alias="TUTOR_FALLBACK_ENABLED"
)

# vLLM Server Configuration
vllm_chat_url: str = Field(
default="http://localhost:8001/v1",
Expand Down Expand Up @@ -153,6 +183,23 @@ def is_development(self) -> bool:
"""Check if running in development environment."""
return self.environment == EnvironmentEnum.dev

def get_llm_mode_for_request(self, tutor_mode: bool) -> LLMModeEnum:
"""
Determine the appropriate LLM mode based on tutor_mode flag.

Args:
tutor_mode: If True, returns tutor LLM mode; otherwise regular LLM mode

Returns:
LLMModeEnum for the appropriate model
"""
if tutor_mode:
# Tutor modes: prefer tutor_llm_mode, fallback to openai
return self.tutor_llm_mode or LLMModeEnum.openai
else:
# Regular modes: prefer regular_llm_mode, fallback to local
return self.regular_llm_mode or LLMModeEnum.local

@property
def admin_token(self) -> str:
return self.admin_token
Expand Down
Loading
Loading