diff --git a/server/routers/knowledge_router.py b/server/routers/knowledge_router.py index 7d2313f7..116c8195 100644 --- a/server/routers/knowledge_router.py +++ b/server/routers/knowledge_router.py @@ -730,9 +730,7 @@ async def delete_document(db_id: str, doc_id: str, current_user: User = Depends( minio_client = get_minio_client() await minio_client.adelete_file(MinIOClient.get_ref_bucket_name(db_id), file_name) # 同时删除 parsed bucket 中的 parsed.md 文件 - await minio_client.adelete_file( - minio_client.KB_BUCKETS["parsed"], f"{db_id}/{doc_id}/parsed.md" - ) + await minio_client.adelete_file(minio_client.KB_BUCKETS["parsed"], f"{db_id}/{doc_id}/parsed.md") logger.debug(f"成功从MinIO删除文件: {file_name}") except Exception as minio_error: logger.warning(f"从MinIO删除文件失败(可能是旧知识库): {minio_error}") diff --git a/src/agents/common/toolkits/buildin/__init__.py b/src/agents/common/toolkits/buildin/__init__.py index 3c8bb64a..f51d0a80 100644 --- a/src/agents/common/toolkits/buildin/__init__.py +++ b/src/agents/common/toolkits/buildin/__init__.py @@ -1,7 +1,8 @@ # buildin 工具包 -from .tools import calculator, query_knowledge_graph +from .tools import calculator, query_knowledge_graph, text_to_img_qwen_image __all__ = [ "calculator", "query_knowledge_graph", + "text_to_img_qwen_image", ] diff --git a/src/agents/common/toolkits/buildin/tools.py b/src/agents/common/toolkits/buildin/tools.py index b409fa6e..aa5187ea 100644 --- a/src/agents/common/toolkits/buildin/tools.py +++ b/src/agents/common/toolkits/buildin/tools.py @@ -1,9 +1,14 @@ +import os import traceback +import uuid from typing import Annotated, Any +import requests + from src import config, graph_base from src.agents.common.toolkits.registry import tool from src.agents.common.toolkits.registry import ToolExtraMetadata, _all_tool_instances, _extra_registry +from src.storage.minio import aupload_file_to_minio from src.utils import logger # Lazy initialization for TavilySearch (only when API key is available) @@ -84,3 +89,47 @@ def query_knowledge_graph(query: Annotated[str, "The keyword to query knowledge except Exception as e: logger.error(f"Knowledge graph query error: {e}, {traceback.format_exc()}") return f"知识图谱查询失败: {str(e)}" + + +@tool(category="buildin", tags=["图片", "生成"], display_name="Qwen-Image") +async def text_to_img_qwen_image( + prompt: Annotated[str, "用于生成图片的文本描述"], + negative_prompt: Annotated[str, "负面提示词,用于指定不想出现在图片中的元素"] = "", + num_inference_steps: Annotated[int, "推理步数,范围1-100"] = 20, + guidance_scale: Annotated[float, "引导强度,控制图片与提示词的匹配程度"] = 7.5, +) -> str: + """使用 Qwen-Image 模型生成图片,返回图片的URL,需要注意的是,生成结果不会默认展示,需要将返回的URL进行展示处理。""" + url = "https://api.siliconflow.cn/v1/images/generations" + + payload = { + "model": "Qwen/Qwen-Image", + "prompt": prompt, + "negative_prompt": negative_prompt, + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + } + headers = {"Authorization": f"Bearer {os.getenv('SILICONFLOW_API_KEY')}", "Content-Type": "application/json"} + + try: + response = requests.post(url, json=payload, headers=headers) + response_json = response.json() + except Exception as e: + logger.error(f"Failed to generate image with: {e}") + raise ValueError(f"Image generation failed: {e}") + + try: + image_url = response_json["images"][0]["url"] + except (KeyError, IndexError, TypeError) as e: + logger.error(f"Failed to parse image URL from response: {e}, {response_json=}") + raise ValueError(f"Image URL extraction failed: {e}") + + # Upload to MinIO + response = requests.get(image_url) + file_data = response.content + + file_name = f"{uuid.uuid4()}.jpg" + image_url = await aupload_file_to_minio( + bucket_name="generated-images", file_name=file_name, data=file_data, file_extension="jpg" + ) + logger.info(f"Image uploaded. URL: {image_url}") + return image_url diff --git a/src/agents/common/toolkits/debug/__init__.py b/src/agents/common/toolkits/debug/__init__.py index 8e9ade69..780a0fd8 100644 --- a/src/agents/common/toolkits/debug/__init__.py +++ b/src/agents/common/toolkits/debug/__init__.py @@ -1,7 +1,6 @@ # debug 工具包 -from .tools import get_approved_user_goal, text_to_img_demo +from .tools import get_approved_user_goal __all__ = [ "get_approved_user_goal", - "text_to_img_demo", ] diff --git a/src/agents/common/toolkits/debug/tools.py b/src/agents/common/toolkits/debug/tools.py index fe0fba3b..52e6ab45 100644 --- a/src/agents/common/toolkits/debug/tools.py +++ b/src/agents/common/toolkits/debug/tools.py @@ -1,51 +1,9 @@ -import os -import uuid - -import requests from langgraph.types import interrupt from src.agents.common.toolkits.registry import tool -from src.storage.minio import aupload_file_to_minio from src.utils import logger -@tool(category="debug", tags=["图片", "测试"], display_name="文生图测试") -async def text_to_img_demo(text: str) -> str: - """【测试用】使用模型生成图片, 会返回图片的URL""" - - url = "https://api.siliconflow.cn/v1/images/generations" - - payload = { - "model": "Qwen/Qwen-Image", - "prompt": text, - } - headers = {"Authorization": f"Bearer {os.getenv('SILICONFLOW_API_KEY')}", "Content-Type": "application/json"} - - try: - response = requests.post(url, json=payload, headers=headers) - response_json = response.json() - except Exception as e: - logger.error(f"Failed to generate image with: {e}") - raise ValueError(f"Image generation failed: {e}") - - try: - image_url = response_json["images"][0]["url"] - except (KeyError, IndexError, TypeError) as e: - logger.error(f"Failed to parse image URL from response: {e}, {response_json=}") - raise ValueError(f"Image URL extraction failed: {e}") - - # 2. Upload to MinIO (Simplified) - response = requests.get(image_url) - file_data = response.content - - file_name = f"{uuid.uuid4()}.jpg" - image_url = await aupload_file_to_minio( - bucket_name="generated-images", file_name=file_name, data=file_data, file_extension="jpg" - ) - logger.info(f"Image uploaded. URL: {image_url}") - return image_url - - @tool(category="debug", tags=["内置", "审批"], display_name="人工审批") def get_approved_user_goal( operation_description: str, diff --git a/test/test_kb_minio_cleanup.py b/test/test_kb_minio_cleanup.py index 22e90320..7c02545a 100644 --- a/test/test_kb_minio_cleanup.py +++ b/test/test_kb_minio_cleanup.py @@ -109,6 +109,7 @@ async def test_delete_knowledge_base_cleanup(): except Exception as e: print(f"\n❌ 测试异常: {e}") import traceback + traceback.print_exc() return False