Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SECRET_KEY=bN3hZ6LbHG7nH9YXWULCr-crcS3GAaRELbNBdAyHBuiHH5TRctd0Zbd6OuLRHHa4Fbs
SENDER_PASSWORD=TXVU2unpCAE2EtEX
KIMI_API_KEY=sk-icdiHIiv6x8XjJCaN6J6Un7uoVxm6df5WPhflq10ZVFo03D9
KIMI_API_KEY=sk-WFAukbN3TVJKhkGLF55a5aF702Ec435b8c36A580E8E4D92d
FERNET_SECRET_KEY=6WssEkvinI_YqwKXdokii2yI6iBiLO_Cjoyq0bBBC5o=
84 changes: 82 additions & 2 deletions app/api/v1/endpoints/aichat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from fastapi import Depends, Request
from fastapi.responses import StreamingResponse
from app.utils.aichat import kimi_chat_stream
from app.utils.aichat import kimi_chat_stream, kimi_chat
from app.utils.redis import get_redis_client
from app.utils.auth import get_current_user
import json
from fastapi import APIRouter
from app.schemas.aichat import NoteInput
from sqlalchemy.ext.asyncio import AsyncSession
from app.utils.get_db import get_db
from app.utils.readPDF import read_pdf
from fastapi import HTTPException


router = APIRouter()
Expand Down Expand Up @@ -47,4 +51,80 @@ async def clear_notes(
user_id = current_user["id"]
redis_key = f"aichat:{user_id}"
redis_client.delete(redis_key)
return {"msg": "clear successfully"}
return {"msg": "clear successfully"}

@router.get("/review", response_model=dict)
async def review_notes(
article_id: int,
):
path = f"/lhcos-data/{article_id}.pdf"
text = await read_pdf(path)
text += "\n\n请根据以上内容生成文章综述。"
async def ai_stream():
full_reply = ""
try:
async for content in kimi_chat_stream([{"role": "user", "content": text}]):
full_reply += content
yield f"data: {json.dumps({'content': content}, ensure_ascii=False)}\n\n"
except Exception as e:
error_str = str(e)
if "exceeded model token limit" in error_str:
raise HTTPException(
status_code=413,
detail="输入内容过长,超出了模型的token限制"
)
# 其他类型的错误重新抛出
raise
return StreamingResponse(ai_stream(), media_type="text/event-stream")

@router.get("/graph", response_model=dict)
async def generate_graph(
note_id: int,
db : AsyncSession = Depends(get_db),
):
# 读取数据库获取笔记内容
from app.curd.note import get_note_by_id
note = await get_note_by_id(db, note_id)
if not note:
raise HTTPException(status_code=404, detail="Note not found")
text = note.content
text += """
我需要你对于上面的内容生成思维导图,请仅给我返回mermaid代码,不要有其他内容,下面是生成样例,
graph TD
A[Natural Language Navigation for Service Robots] --> B[Task Definition]
A --> C[Challenges]
A --> D[Proposed Solution]
A --> E[Experimental Results]

B --> B1["- Predict action sequence from NL instructions"]
B --> B2["- Example: 'Walk out of bathroom to right stairs'"]

C --> C1["- Environment exploration"]
C --> C2["- Accurate path following"]
C --> C3["- Language-vision relationship modeling"]

D --> D1[CrossMap Transformer Network]
D --> D2[Transformer-based Speaker]
D --> D3[Double Back-Translation Model]

D1 --> D11["- Encodes linguistic/visual features"]
D1 --> D12["- Sequentially generates paths"]

D2 --> D21["- Generates navigation instructions"]

D3 --> D31["- Paths → Instructions"]
D3 --> D32["- Instructions → Paths"]
D3 --> D33["- Shared latent features"]

E --> E1["- Improved instruction understanding"]
E --> E2["- Enhanced instruction generation"
"""
try:
ans = await kimi_chat([{"role": "user", "content": text}], model="moonshot-v1-32k")
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"AI服务异常: {str(e)}"
)
return {"mermaid_code": ans.strip().replace("```mermaid", "").replace("```", "").strip()}

10 changes: 9 additions & 1 deletion app/curd/note.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,12 @@ async def find_self_notes_count_in_db(db: AsyncSession, user_id: int):
)
result = await db.execute(stmt)
count = result.scalar_one_or_none()
return count
return count

async def get_note_by_id(db: AsyncSession, note_id: int):
"""
根据 ID 获取笔记
"""
stmt = select(Note).where(Note.id == note_id, Note.visible == True)
result = await db.execute(stmt)
return result.scalar_one_or_none() # 返回单个笔记或 None
18 changes: 15 additions & 3 deletions app/utils/aichat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

client = AsyncOpenAI(
api_key=settings.KIMI_API_KEY,
base_url="https://api.moonshot.cn/v1",
base_url="http://47.93.172.156:3001/v1",
)

async def kimi_chat_stream(messages, model="moonshot-v1-8k", temperature=0.3):
async def kimi_chat_stream(messages, model="moonshot-v1-32k", temperature=0.3):
"""
异步AI流式对话工具方法,传入消息列表,流式返回AI回复内容。
:param messages: List[dict]
Expand All @@ -21,4 +21,16 @@ async def kimi_chat_stream(messages, model="moonshot-v1-8k", temperature=0.3):
async for chunk in stream:
content = getattr(chunk.choices[0].delta, "content", None)
if content:
yield content
yield content


async def kimi_chat(messages, model="moonshot-v1-32k", temperature=0):
"""
异步但不流式AI对话工具方法,传入消息列表,返回AI回复内容。
"""
response = await client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature
)
return response.choices[0].message.content if response.choices else ""
17 changes: 17 additions & 0 deletions app/utils/readPDF.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import fitz
import asyncio

def extract_text_from_pdf(pdf_path):
# 打开PDF文件
doc = fitz.open(pdf_path)
text = ""
# 遍历每一页
for page_num in range(len(doc) - 2):
page = doc.load_page(page_num) # 加载页面
page_text = page.get_text("text")
text += page_text
doc.close() # 关闭PDF文件
return text

async def read_pdf(pdf_path: str):
return await asyncio.to_thread(extract_text_from_pdf, pdf_path)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pycparser==2.22
pydantic==2.11.2
pydantic_core==2.33.1
PyJWT==2.10.1
PyMuPDF==1.26.0
PyMySQL==1.1.1
pytest==8.3.5
python-dateutil==2.9.0.post0
Expand Down