Merge remote-tracking branch 'origin/master'

master
masong 5 months ago
commit 91c7acc569
  1. 2
      packages/dbgpt-app/src/dbgpt_app/dbgpt_server.py
  2. 0
      packages/dbgpt-system/src/dbgpt_system/app_description/__init__.py
  3. 46
      packages/dbgpt-system/src/dbgpt_system/app_description/controller.py
  4. 7
      packages/dbgpt-system/src/dbgpt_system/upload_image/ai_generate.py
  5. 106
      packages/dbgpt-system/src/dbgpt_system/upload_image/controller.py

@ -69,7 +69,6 @@ def mount_routers(app: FastAPI):
from dbgpt_system.sys_menu.controller import router as menu_v1
from dbgpt_system.sys_type.controller import router as type_v1
from dbgpt_system.upload_image.controller import router as upload_image_v1
from dbgpt_system.app_description.controller import router as app_description_v1
from dbgpt_system.sys_agent_user_share.agent_user_share_controller import router as user_share_v1
from dbgpt_app.openapi.user_share.api_user_share import router as user_share_chat_v1
app.include_router(api_v1, prefix="/api", tags=["Chat"])
@ -85,7 +84,6 @@ def mount_routers(app: FastAPI):
app.include_router(menu_v1,prefix = "/api/menu",tags=["Menu"])
app.include_router(type_v1,prefix = "/api/sys_type",tags=["sys_type"])
app.include_router(upload_image_v1,prefix = "/api/upload_image",tags=["upload_image"])
app.include_router(app_description_v1,prefix = "/api/app_description",tags=["app_description"])
app.include_router(knowledge_router, tags=["Knowledge"])
app.include_router(user_share_v1,prefix = "/api/agent_user_share",tags= ["AgentUserShare"])
app.include_router(user_share_chat_v1,prefix="/api/v3",tags=["UserShareChat"])

@ -1,46 +0,0 @@
# controller/app_description_v1.py
from fastapi import APIRouter, HTTPException
from dbgpt.component import SystemApp, ComponentType
from dbgpt.core import ModelRequest
from dbgpt.model.cluster.client import DefaultLLMClient # ✅ 使用已定义的客户端类
router = APIRouter()
system_app = SystemApp()
# 获取项目主配置的模型客户端(直接复用 DefaultLLMClient)
model_client = DefaultLLMClient()
_PROMPT_TEMPLATE = """作为应用助手,请根据名称生成描述:
名称{app_name}
要求
1. 突出核心功能
2. 口语化中文
3. 80字以内
生成结果"""
@router.post("/ai_generate_description")
async def generate_description(app_name: str):
try:
# 参数校验
if not app_name or len(app_name) > 50:
raise ValueError("应用名称需为1-50字符")
# 构造提示词
prompt = _PROMPT_TEMPLATE.format(app_name=app_name.strip())
# 调用模型(自动继承项目配置)
response = await model_client.generate(
ModelRequest(prompt=prompt, max_new_tokens=200)
)
# 清理结果
description = response.text.strip().strip('"').strip("'")
return {"description": description}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"生成失败: {str(e)}"
)

@ -0,0 +1,7 @@
from pydantic import BaseModel
# 定义请求体模型
class GenerateRequest(BaseModel):
app_name: str
describe: str

@ -5,6 +5,10 @@ from dbgpt.core.interface.file import FileStorageClient
from dbgpt._private.config import Config
import uuid
import io
import aiohttp
import requests
from dbgpt_system.upload_image.ai_generate import GenerateRequest
from io import BytesIO
router = APIRouter()
CFG = Config()
@ -13,6 +17,10 @@ CFG = Config()
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"}
MAX_FILE_SIZE = 16 * 1024 * 1024 # 16MB
#豆包相关
DB_IMAGES_URL = "https://ark.cn-beijing.volces.com/api/v3/images/generations"
DB_KEY = "Bearer 256e690a-3967-4ac9-97d5-5f7a08484456"
def get_fs() -> FileStorageClient:
return FileStorageClient.get_instance(CFG.SYSTEM_APP)
@ -66,4 +74,100 @@ async def upload_image(
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}")
raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}")
@router.post("/ai_generate")
async def ai_generate(request: GenerateRequest, user_info: UserRequest = Depends(get_user_from_headers)):
"""
根据应用名称和描述调用豆包生成一张logo上传并返回访问路径
"""
payload = {
"model": "doubao-seedream-3-0-t2i-250415",
"prompt": f"我需要你根据应用名称和描述生成一张应用logo,应用名称为:{request.app_name},描述为:{request.describe}",
"response_format": "url",
"size": "512x512",
"seed": 12,
"guidance_scale": 2.5,
"watermark": False
}
headers = {
"Authorization": DB_KEY,
"Content-Type": "application/json"
}
response = requests.request("POST", DB_IMAGES_URL, json=payload, headers=headers)
try:
res_json = response.json()
img_url = res_json['data'][0]["url"]
return await upload_ai_image(img_url)
except Exception as e:
raise HTTPException(500, f"AI图片生成失败: {str(e)}")
async def upload_ai_image(image_url: str, bucket: str = "ai_generated_images"):
try:
# 1. 下载图片(处理TOS签名URL的特殊情况)
async with aiohttp.ClientSession() as session:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
async with session.get(image_url, headers=headers) as resp:
if resp.status != 200:
error_content = await resp.text()
raise ValueError(
f"下载失败 HTTP {resp.status},错误信息: {error_content[:200]}"
)
# 获取真实文件扩展名(从URL或Content-Type)
content_type = resp.headers.get("Content-Type", "")
file_ext = (
"jpg" if "jpeg" in content_type.lower()
else content_type.split("/")[-1].lower()
if "/" in content_type
else image_url.split(".")[-1].lower().split("?")[0]
)
file_ext = file_ext if file_ext in ["jpg", "jpeg", "png", "gif"] else "jpg"
image_data = await resp.read()
# 2. 转换为文件流并上传
fs = get_fs()
file_id = f"ai_{uuid.uuid4().hex}.{file_ext}"
# 3. 上传文件(兼容不同存储后端)
try:
# 尝试两种常见参数形式
try:
file_uri = fs.save_file(
bucket=bucket,
file_name=file_id,
file_data=BytesIO(image_data) # 文件流形式
)
except TypeError:
file_uri = fs.save_file(
bucket=bucket,
file_name=file_id,
file_data=image_data # bytes形式
)
return JSONResponse(
status_code=200,
content={
"success": True,
"url": f"/file/preview/{file_uri}",
"filename": file_id,
"message": "上传成功"
}
)
except Exception as upload_error:
raise ValueError(f"存储服务上传失败: {str(upload_error)}")
except ValueError as ve:
raise HTTPException(400, f"图片处理错误: {str(ve)}")
except aiohttp.ClientError as ce:
raise HTTPException(502, f"网络请求失败: {str(ce)}")
except Exception as e:
raise HTTPException(500, f"上传过程异常: {str(e)}")
Loading…
Cancel
Save