From e561c97a4e7269fcf9c6f2d0bcd0079fbf44ae06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A7=E9=98=B3=E6=B4=8B?= <2443479321@qq.com> Date: Fri, 11 Sep 2026 17:31:16 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=AE=A2=E6=9C=8Dagent=E7=9A=84?= =?UTF-8?q?=E5=88=87=E7=89=87=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 5 +- README.md | 2 +- api/chat/knowledge.py | 22 +- config/database/redis.py | 1 + config/settings.py | 21 +- logs/error.log | 1327 +++++++++++++++++++++++++++++ logs/info.log | 1339 ++++++++++++++++++++++++++++++ main.py | 10 +- rag/embedding.py | 4 +- rag/milvus_collections.py | 14 +- service/knowledge_base/upload.py | 205 +++-- sql/schema.sql | 2 +- tests/test_embedding.py | 8 +- tests/test_ingestion.py | 7 +- tests/test_knowledge_router.py | 10 +- tests/test_knowledge_upload.py | 71 +- tests/test_milvus_collections.py | 31 +- tool/llm.py | 186 ++++- 公司信息/faq.md | 119 +++ 公司信息/高频问答对.txt | 155 +++- 20 files changed, 3309 insertions(+), 230 deletions(-) create mode 100644 公司信息/faq.md diff --git a/.env.example b/.env.example index 8d99260..363c381 100644 --- a/.env.example +++ b/.env.example @@ -52,7 +52,7 @@ MILVUS_CONNECT_TIMEOUT=5 MILVUS_TIMEOUT=30 # LLM(tool/llm.py 统一客户端) -LLM_MODE=ollama # ollama(本地)/ api(API Key) +LLM_MODE=auto # auto=本地优先、API 兜底(按参数是否填写自动判定)/ ollama / api=强制单一后端 LLM_OLLAMA_BASE=http://localhost:11434 LLM_OLLAMA_CHAT_MODEL=qwen2.5:7b LLM_OLLAMA_EMBED_MODEL=bge-m3 @@ -60,6 +60,9 @@ LLM_API_BASE=https://api.openai.com/v1 LLM_API_KEY= LLM_API_CHAT_MODEL=gpt-4o-mini LLM_API_EMBED_MODEL=text-embedding-3-small +# 向量维度:embeddings 请求参数 + Milvus 建表/入库校验,改动后需重建 fin_* 集合; +# 须与模型输出一致(qwen3-embedding 为 MRL 模型,可任选 32~4096) +LLM_EMBED_DIMENSIONS=1024 LLM_TEMPERATURE=0.3 LLM_MAX_TOKENS=1024 LLM_TIMEOUT=30 diff --git a/README.md b/README.md index b31a8ed..870b6af 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ uvicorn main:app --reload --port 8000 - **异常路由**:业务抛 `ApiError` 子类,全局处理器转统一响应(400/401/403/404 保留 HTTP 状态码,1001+ 业务码返回 HTTP 200)。 - **日志**:`logs/info.log`、`logs/error.log` 按天滚动,自动带 trace_id,身份证/手机号脱敏。 - **四库职责**(开发计划 §1):MySQL 业务 / Milvus 向量 / Neo4j 图谱 / Redis 缓存·会话·事件·锁。 -- **LLM 统一客户端**(`tool/llm.py`):`LLM_MODE=ollama | api` 双模式,底层均走 OpenAI 兼容 `/v1` 端点,业务只调 `chat(messages)` / `embed(texts)`。内置:指数退避重试(1s/2s/4s)、主模型失败自动切 `LLM_FALLBACK_CHAT_MODEL`、再失败抛 `LLMFailError`(§1001)由调用方兜底话术。自检:`python test_llm.py`。 +- **LLM 统一客户端**(`tool/llm.py`):`LLM_MODE=auto | ollama | api`,底层均走 OpenAI 兼容 `/v1` 端点,业务只调 `chat(messages)` / `embed(texts)`。`auto`(默认)按 `.env` 填写情况组成后端链:本地 Ollama 优先,`LLM_API_KEY` 配齐则作为兜底。内置:指数退避重试(1s/2s/4s)、主模型失败自动切 `LLM_FALLBACK_CHAT_MODEL`、本地后端耗尽自动切 API 后端(embed 不跨后端,向量空间不兼容)、全部失败抛 `LLMFailError`(§1001)由调用方兜底话术。自检:`python test_llm.py`。 - **数据访问**:service 不直接写 SQL,统一走 `repositories/`(会话经 `config.deps.get_db` 注入);新表照 `repositories/sys_config.py` 复制一个仓储 + 一个 ORM 模型。 - **JWT 鉴权**:`POST /api/auth/login`(username/password)签发 token(仅存 user_id+exp,HS256);任意路由加 `Depends(get_current_user)`(`api/deps.py`)即自动校验 Bearer token → 按 user_id 回查 `sys_user` → 注入用户对象(401 无效/过期/不存在,403 禁用)。密码哈希用 stdlib PBKDF2(`service/auth.py`),SEED 测试用户可看 `test_auth.py`。生产务必替换 `JWT_SECRET`(≥32 字节)。 diff --git a/api/chat/knowledge.py b/api/chat/knowledge.py index 0ac8477..d17b2ca 100644 --- a/api/chat/knowledge.py +++ b/api/chat/knowledge.py @@ -78,15 +78,19 @@ async def confirm_document_upload( _: SysUser = Depends(require_knowledge_operator), ): try: - body = await request.json() + form = await request.form() + upload = form.get("file") + if upload is None or not hasattr(upload, "read"): + raise UploadValidationError("缺少上传文件") result = await _service(request).confirm( - upload_id=body.get("upload_id", ""), - title=body.get("title", ""), - doc_id=body.get("doc_id", ""), - collection_name=body.get("collection_name", ""), - strategy=body.get("strategy", ""), - chunk_size=body.get("chunk_size"), - chunk_overlap=body.get("chunk_overlap"), + filename=upload.filename, + content=await upload.read(), + title=form.get("title", ""), + doc_id=form.get("doc_id", ""), + collection_name=form.get("collection_name", ""), + strategy=form.get("strategy", ""), + chunk_size=_optional_int(form.get("chunk_size")), + chunk_overlap=_optional_int(form.get("chunk_overlap")), ) return success(result) except (UploadValidationError, ValueError) as exc: @@ -105,4 +109,4 @@ async def delete_document( return success(result) except (UploadValidationError, ValueError) as exc: response = fail(400, str(exc)) - return JSONResponse(status_code=400, content=response.model_dump()) + return JSONResponse(status_code=400, content=response.model_dump()) \ No newline at end of file diff --git a/config/database/redis.py b/config/database/redis.py index 3b799b9..3b1f4bd 100644 --- a/config/database/redis.py +++ b/config/database/redis.py @@ -24,6 +24,7 @@ def client() -> aioredis.Redis: retry=Retry(FullJitterBackoff(base=1, cap=10), retries=3), max_connections=settings.redis.max_connections, decode_responses=True, + protocol=2, # redis-py 8 默认 RESP3(HELLO 3),Redis < 6.0 不支持 ) return _client diff --git a/config/settings.py b/config/settings.py index 4349116..3549b8c 100644 --- a/config/settings.py +++ b/config/settings.py @@ -86,16 +86,17 @@ class MilvusCfg(BaseSettings): class LLMCfg(BaseSettings): """大模型配置:本地 Ollama / OpenAI 兼容 API 双模式见 tool/llm.py。""" - mode: str - # —— 本地 Ollama —— - ollama_base: str - ollama_chat_model: str - ollama_embed_model: str - # —— OpenAI 兼容 API(base_url 以 /v1 结尾)—— - api_base: str - api_key: str - api_chat_model: str - api_embed_model: str + mode: str = "auto" # auto=本地优先、API 兜底(按下方参数是否填写自动判定);ollama / api=强制单一后端 + # —— 本地 Ollama(base + chat_model 填写即启用)—— + ollama_base: str = "" + ollama_chat_model: str = "" + ollama_embed_model: str = "" + # —— OpenAI 兼容 API(api_key + base + chat_model 填写即启用;base_url 以 /v1 结尾)—— + api_base: str = "" + api_key: str = "" + api_chat_model: str = "" + api_embed_model: str = "" + embed_dimensions: int # 向量维度:既作为 embeddings 请求的 dimensions 参数,也是 Milvus 建表/入库校验的维度;须与模型输出一致(MRL 模型如 qwen3-embedding 可任选 32~4096) # —— 通用超参 —— temperature: float max_tokens: int diff --git a/logs/error.log b/logs/error.log index e69de29..d759f25 100644 --- a/logs/error.log +++ b/logs/error.log @@ -0,0 +1,1327 @@ +2026-09-11 15:07:01,773 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:07:37,652 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:08:14,610 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:09:22,372 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 62, in preview_document_upload + result = await _service(request).preview( + ^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 19, in _service + raise RuntimeError("knowledge upload service is not configured") +RuntimeError: knowledge upload service is not configured +2026-09-11 16:19:30,156 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 206, in confirm + exists = await exists + ^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 34, in document_exists_in_milvus + rows = await milvus.query( + ^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 16:19:37,338 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 206, in confirm + exists = await exists + ^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 34, in document_exists_in_milvus + rows = await milvus.query( + ^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 16:21:29,474 ERROR [a83edb036c014889] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:21:29,478 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:23:56,878 ERROR [f6a273b78c7d4843] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:23:56,880 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:24:47,041 ERROR [ed2fcc061b8b4461] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:24:47,044 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:40:05,491 ERROR [ff041f4e56dd45c9] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:40:05,495 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:41:22,853 ERROR [af03a1c5165340f1] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:41:22,856 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:50:56,366 ERROR [f38eae609cb84f12] service.knowledge_base.upload: knowledge update event publish failed for doc_id=公募基金操作知识 +Traceback (most recent call last): + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:50:56,787 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:51:18,924 ERROR [b3d3c87d09134d4b] service.knowledge_base.upload: knowledge update event publish failed for doc_id=公募基金操作知识 +Traceback (most recent call last): + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:51:19,384 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 17:22:54,820 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 17:25:39,869 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 17:26:22,071 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: diff --git a/logs/info.log b/logs/info.log index e69de29..7de178d 100644 --- a/logs/info.log +++ b/logs/info.log @@ -0,0 +1,1339 @@ +2026-09-11 15:07:01,773 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:07:37,652 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:08:14,610 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 58, in preview_document_upload + form = await request.form() + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\requests.py", line 276, in _get_form + assert parse_options_header is not None, ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError: The `python-multipart` library must be installed to use form parsing. +2026-09-11 15:09:22,372 ERROR [-] api: unhandled error on /api/knowledge/documents/preview +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 62, in preview_document_upload + result = await _service(request).preview( + ^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 19, in _service + raise RuntimeError("knowledge upload service is not configured") +RuntimeError: knowledge upload service is not configured +2026-09-11 16:19:30,156 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 206, in confirm + exists = await exists + ^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 34, in document_exists_in_milvus + rows = await milvus.query( + ^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 16:19:37,338 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 206, in confirm + exists = await exists + ^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 34, in document_exists_in_milvus + rows = await milvus.query( + ^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 16:21:29,474 INFO [a83edb036c014889] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 502 Bad Gateway" +2026-09-11 16:21:29,474 ERROR [a83edb036c014889] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:21:29,478 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:23:56,878 INFO [f6a273b78c7d4843] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 502 Bad Gateway" +2026-09-11 16:23:56,878 ERROR [f6a273b78c7d4843] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:23:56,880 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:24:47,041 INFO [ed2fcc061b8b4461] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 502 Bad Gateway" +2026-09-11 16:24:47,041 ERROR [ed2fcc061b8b4461] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:24:47,044 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:40:05,491 INFO [ff041f4e56dd45c9] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 502 Bad Gateway" +2026-09-11 16:40:05,491 ERROR [ff041f4e56dd45c9] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:40:05,495 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:41:22,853 INFO [af03a1c5165340f1] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 502 Bad Gateway" +2026-09-11 16:41:22,853 ERROR [af03a1c5165340f1] rag.embedding: embedding provider failed +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 +2026-09-11 16:41:22,856 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Mutual_Fund\rag\embedding.py", line 22, in embed_texts + vectors = await provider.embed(texts) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\tool\llm.py", line 116, in embed + r.raise_for_status() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\httpx\_models.py", line 829, in raise_for_status + raise HTTPStatusError(message, request=request, response=self) +httpx.HTTPStatusError: Server error '502 Bad Gateway' for url 'http://localhost:11434/v1/embeddings' +For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 224, in confirm + vectors = await self.embedder( + ^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\rag\embedding.py", line 25, in embed_texts + raise EmbeddingError("Embedding service unavailable") from exc +rag.embedding.EmbeddingError: Embedding service unavailable +2026-09-11 16:50:56,234 INFO [f38eae609cb84f12] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 16:50:56,366 ERROR [f38eae609cb84f12] service.knowledge_base.upload: knowledge update event publish failed for doc_id=公募基金操作知识 +Traceback (most recent call last): + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:50:56,787 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:51:18,892 INFO [b3d3c87d09134d4b] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 16:51:18,924 ERROR [b3d3c87d09134d4b] service.knowledge_base.upload: knowledge update event publish failed for doc_id=公募基金操作知识 +Traceback (most recent call last): + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:51:19,384 ERROR [-] api: unhandled error on /api/knowledge/documents/confirm +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 85, in confirm_document_upload + result = await _service(request).confirm( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 284, in confirm + await publish_knowledge_update( + File "D:\Mutual_Fund\rag\events.py", line 19, in publish_knowledge_update + await publisher(KNOWLEDGE_UPDATE_EVENT, payload) + File "D:\Mutual_Fund\service\customer_agent\bootstrap.py", line 51, in publish_event + await redis.publish( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\client.py", line 929, in execute_command + conn = self.connection or await pool.get_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\utils.py", line 249, in async_wrapper + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2824, in get_connection + await self.ensure_connection(connection) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 2865, in ensure_connection + await connection.connect() + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 819, in connect + await self.retry.call_with_retry( + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 883, in connect_check_health + await self.on_connect_check_health(check_health=check_health) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1003, in on_connect_check_health + response = await self.read_response() + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\redis\asyncio\connection.py", line 1328, in read_response + raise response from None +redis.exceptions.ResponseError: unknown command `HELLO`, with args beginning with: `3`, +2026-09-11 16:53:37,020 INFO [304b872873d747c4] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 17:00:11,008 INFO [9f6c6252d294401c] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 17:02:26,531 INFO [737b2ac781414711] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 17:04:18,312 INFO [e36a83dc41644fae] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 17:07:19,459 INFO [75c94c9d84d84ec6] httpx: HTTP Request: POST http://localhost:11434/v1/embeddings "HTTP/1.1 200 OK" +2026-09-11 17:22:54,820 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 17:25:39,869 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: +2026-09-11 17:26:22,071 ERROR [-] api: unhandled error on /api/knowledge/documents +Traceback (most recent call last): + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\api\chat\knowledge.py", line 32, in list_documents + return success(await _service(request).list_documents()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Mutual_Fund\service\knowledge_base\upload.py", line 130, in list_documents + rows = await self.milvus_client.query( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\milvus_client\async_milvus_client.py", line 642, in query + return await conn.query( + ^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 489, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 486, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 556, in async_handler + return await func(self, *args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 370, in async_handler + raise e from e + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\decorators.py", line 332, in async_handler + return await func(*args, **kwargs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\async_grpc_handler.py", line 1467, in query + check_status(response.status) + File "D:\Projects\py_environment\test_py3.12\Lib\site-packages\pymilvus\client\utils.py", line 77, in check_status + raise MilvusException.from_status(status) +pymilvus.exceptions.MilvusException: diff --git a/main.py b/main.py index 42a4162..83d527c 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from fastapi import FastAPI from api.router import api_router from config import database +from rag.milvus_collections import ensure_collections from service.customer_agent.bootstrap import ( build_default_knowledge_upload_service, build_default_runtime, @@ -17,11 +18,12 @@ from utils.request_id import RequestIdMiddleware @asynccontextmanager async def lifespan(app: FastAPI): - setup_logging() # 幂等:分级日志 + trace_id + 脱敏 - # 四库会话懒创建:启动不连接任何库,首次访问才建,可手动预热: - # asyncio.run(database.init_db()) + setup_logging() + await ensure_collections() + app.state.customer_agent_runtime = build_default_runtime() + app.state.knowledge_upload_service = build_default_knowledge_upload_service() yield - await database.dispose() # 清理已创建的单例(未创建则空操作) + await database.dispose() app = FastAPI(title="智能公募基金系统", version="0.1.0", lifespan=lifespan) diff --git a/rag/embedding.py b/rag/embedding.py index eb9076f..6941c2a 100644 --- a/rag/embedding.py +++ b/rag/embedding.py @@ -3,11 +3,13 @@ from __future__ import annotations import logging +from config.settings import settings from tool.llm import llm logger = logging.getLogger("rag.embedding") -EMBEDDING_DIMENSION = 768 +# 单一来源:.env 的 LLM_EMBED_DIMENSIONS;Milvus 建表、入库校验、embeddings 请求参数均以此为准 +EMBEDDING_DIMENSION = settings.llm.embed_dimensions class EmbeddingError(RuntimeError): diff --git a/rag/milvus_collections.py b/rag/milvus_collections.py index 628c827..9c85191 100644 --- a/rag/milvus_collections.py +++ b/rag/milvus_collections.py @@ -4,10 +4,10 @@ from __future__ import annotations from pymilvus import AsyncMilvusClient, DataType from config.database.milvus import client as configured_milvus_client +from rag.embedding import EMBEDDING_DIMENSION KNOWLEDGE_COLLECTIONS = ("fin_faq", "fin_fund_doc", "fin_policy") -EMBEDDING_DIMENSION = 768 def build_knowledge_schema(): @@ -44,3 +44,15 @@ async def ensure_collections(milvus_client: AsyncMilvusClient | None = None) -> schema=schema, index_params=index_params, ) + continue + # 已存在的集合维度必须与当前 embedding 配置一致,否则入库/检索会在运行时失败 + desc = await client.describe_collection(collection_name) + for field in desc.get("fields", []): + if field.get("name") != "vector": + continue + dim = field.get("params", {}).get("dim") + if dim is not None and int(dim) != EMBEDDING_DIMENSION: + raise RuntimeError( + f"Milvus collection {collection_name!r} vector dim={dim}, " + f"expected {EMBEDDING_DIMENSION}; drop and recreate it" + ) diff --git a/service/knowledge_base/upload.py b/service/knowledge_base/upload.py index 140349a..dac406c 100644 --- a/service/knowledge_base/upload.py +++ b/service/knowledge_base/upload.py @@ -3,16 +3,19 @@ from __future__ import annotations import logging import json +import re +import time import uuid from inspect import isawaitable from pathlib import Path +from uuid import NAMESPACE_URL, uuid5 from rag.document_parser import SUPPORTED_EXTENSIONS from rag.events import publish_knowledge_update -from rag.ingestion import ingest_document_atomic -from rag.preview import preview_document -from rag.chunk_config import resolve_chunk_config +from rag.embedding import EMBEDDING_DIMENSION from rag.milvus_collections import KNOWLEDGE_COLLECTIONS +from rag.milvus_delete import _escape_filter_value +from rag.preview import preview_document from rag.milvus_delete import delete_document_vectors @@ -123,27 +126,37 @@ class KnowledgeUploadService: async def list_documents(self) -> list[dict]: documents = {} + page_size = 4096 for collection_name in KNOWLEDGE_COLLECTIONS: - rows = await self.milvus_client.query( - collection_name=collection_name, - filter="", - output_fields=["doc_id", "title", "strategy"], - ) - for row in rows or []: - doc_id = row.get("doc_id", "") - if not doc_id: - continue - document = documents.setdefault( - doc_id, - { - "doc_id": doc_id, - "title": row.get("title", ""), - "collection_name": collection_name, - "strategy": row.get("strategy", ""), - "chunk_count": 0, - }, + offset = 0 + while True: + rows = await self.milvus_client.query( + collection_name=collection_name, + filter="", + output_fields=["doc_id", "title", "strategy"], + limit=page_size, + offset=offset, ) - document["chunk_count"] += 1 + if not rows: + break + for row in rows: + doc_id = row.get("doc_id", "") + if not doc_id: + continue + document = documents.setdefault( + doc_id, + { + "doc_id": doc_id, + "title": row.get("title", ""), + "collection_name": collection_name, + "strategy": row.get("strategy", ""), + "chunk_count": 0, + }, + ) + document["chunk_count"] += 1 + if len(rows) < page_size: + break + offset += page_size return list(documents.values()) async def get_document(self, doc_id: str) -> dict | None: @@ -177,47 +190,106 @@ class KnowledgeUploadService: async def confirm( self, *, - upload_id: str, - title: str, - doc_id: str, + filename: str, + content: bytes, + title: str | None = None, + doc_id: str | None = None, collection_name: str, strategy: str, chunk_size: int | None = None, chunk_overlap: int | None = None, ) -> dict: - self.cleanup_expired_uploads() + suffix = self._validate_upload(filename, content) if collection_name not in KNOWLEDGE_COLLECTIONS: raise UploadValidationError("知识库集合不在允许范围内") - path = self._find_upload(upload_id) - try: - manifest = json.loads(self._manifest_path(upload_id).read_text(encoding="utf-8")) - if strategy != manifest["strategy"]: - raise UploadValidationError("确认策略必须与预览策略一致") - if chunk_size is None: - chunk_size = manifest["chunk_size"] - if chunk_overlap is None: - chunk_overlap = manifest["chunk_overlap"] - if self.document_exists is not None: - exists = self.document_exists(doc_id) - if isawaitable(exists): - exists = await exists - if exists: - raise UploadValidationError("doc_id已存在,禁止重复入库") - from rag.document_parser import parse_document - result = await ingest_document_atomic( - parse_document(path), - doc_id, - title, - collection_name, - strategy, - milvus_client=self.milvus_client, - embedder=self.embedder, - config=resolve_chunk_config( - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - ), + stem = Path(filename).stem + title = (title or "").strip() or stem + if not doc_id or not doc_id.strip(): + doc_id = self._slugify(stem) or f"doc_{int(time.time())}_{uuid.uuid4().hex[:8]}" + else: + doc_id = doc_id.strip() + + if self.document_exists is not None: + exists = self.document_exists(doc_id) + if isawaitable(exists): + exists = await exists + if exists: + raise UploadValidationError("doc_id已存在,禁止重复入库") + + upload_id = uuid.uuid4().hex + temp_path = self.storage_dir / f"{upload_id}{suffix}" + temp_path.write_bytes(content) + + try: + preview = preview_document( + temp_path, + strategy=strategy, + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, ) + if not preview["chunks"]: + raise UploadValidationError("文档切片为空") + + vectors = await self.embedder( + [chunk["text"] for chunk in preview["chunks"]] + ) + if len(vectors) != len(preview["chunks"]) or any( + len(vector) != EMBEDDING_DIMENSION for vector in vectors + ): + raise UploadValidationError( + f"Embedding维度必须为{EMBEDDING_DIMENSION}" + ) + + rows = [ + { + "chunk_id": str(uuid5(NAMESPACE_URL, f"{doc_id}:{index}")), + "doc_id": doc_id, + "title": title, + "section_title": chunk.get("section_title") or "", + "text": chunk["text"], + "strategy": preview["actual_strategy"], + "vector": vector, + } + for index, (chunk, vector) in enumerate( + zip(preview["chunks"], vectors) + ) + ] + try: + await self.milvus_client.insert( + collection_name=collection_name, data=rows + ) + except Exception: + logger.exception( + "atomic Milvus ingestion failed for doc_id=%s", doc_id + ) + try: + await self.milvus_client.delete( + collection_name=collection_name, + filter=f'doc_id == "{_escape_filter_value(doc_id)}"', + ) + except Exception: + logger.exception( + "failed to clean up document rows for doc_id=%s", doc_id + ) + raise + + result = { + "doc_id": doc_id, + "title": title, + "collection_name": collection_name, + "filename": Path(filename).name, + "strategy": preview["strategy"], + "actual_strategy": preview["actual_strategy"], + "degraded": preview["degraded"], + "warning": preview["warning"], + "cleaning_changed": preview["cleaning_changed"], + "cleaning_warnings": preview["cleaning_warnings"], + "chunk_count": len(rows), + "chunk_size": preview["chunk_size"], + "chunk_overlap": preview["chunk_overlap"], + } + try: await publish_knowledge_update( self.publisher, @@ -226,16 +298,29 @@ class KnowledgeUploadService: chunk_count=result["chunk_count"], ) except Exception: - logger.exception("knowledge update event publish failed for doc_id=%s", doc_id) + logger.exception( + "knowledge update event publish failed for doc_id=%s", doc_id + ) try: - await delete_document_vectors(doc_id, milvus_client=self.milvus_client) + await delete_document_vectors( + doc_id, milvus_client=self.milvus_client + ) except Exception: - logger.exception("failed to compensate vectors for doc_id=%s", doc_id) + logger.exception( + "failed to compensate vectors for doc_id=%s", doc_id + ) raise + return {"event_published": True, **result} finally: - path.unlink(missing_ok=True) - self._manifest_path(upload_id).unlink(missing_ok=True) + temp_path.unlink(missing_ok=True) + + @staticmethod + def _slugify(text: str) -> str: + s = text.strip().lower() + s = re.sub(r"[^\w\u4e00-\u9fff]+", "_", s) + s = re.sub(r"_+", "_", s).strip("_") + return s def _validate_upload(self, filename: str, content: bytes) -> str: suffix = Path(filename).suffix.lower() @@ -259,4 +344,4 @@ class KnowledgeUploadService: return paths[0] def _manifest_path(self, upload_id: str) -> Path: - return self.storage_dir / f"{upload_id}.json" + return self.storage_dir / f"{upload_id}.json" \ No newline at end of file diff --git a/sql/schema.sql b/sql/schema.sql index d05feeb..cc44f66 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS sys_user ( salt VARCHAR(32) NULL COMMENT '口令盐', real_name VARCHAR(32) NULL COMMENT '真实姓名', phone VARCHAR(20) NOT NULL COMMENT '手机号(脱敏展示用)', - user_type VARCHAR(16) NOT NULL DEFAULT 'CUSTOMER' COMMENT 'CUSTOMER=客户 / EMPLOYEE=员工', + user_type VARCHAR(16) NOT NULL DEFAULT 'CUSTOMER' COMMENT 'CUSTOMER=客户 / EMPLOYEE=员工 / ADMIN=管理员', employee_role VARCHAR(32) NULL COMMENT '员工角色:理财顾问/风控专员/客户经理/管理员', customer_level VARCHAR(16) NULL COMMENT '客户等级:普通/金卡/白金/钻石/私行', status VARCHAR(16) NOT NULL DEFAULT '正常' COMMENT '账号状态:正常/禁用/冻结', diff --git a/tests/test_embedding.py b/tests/test_embedding.py index 17c9a0e..ae90315 100644 --- a/tests/test_embedding.py +++ b/tests/test_embedding.py @@ -1,18 +1,18 @@ import unittest -from rag.embedding import EmbeddingError, embed_texts +from rag.embedding import EMBEDDING_DIMENSION, EmbeddingError, embed_texts class EmbeddingTests(unittest.IsolatedAsyncioTestCase): - async def test_returns_768_dimension_vectors(self): + async def test_returns_configured_dimension_vectors(self): class Client: async def embed(self, texts): - return [[0.1] * 768 for _ in texts] + return [[0.1] * EMBEDDING_DIMENSION for _ in texts] vectors = await embed_texts(["基金知识"], client=Client()) self.assertEqual(len(vectors), 1) - self.assertEqual(len(vectors[0]), 768) + self.assertEqual(len(vectors[0]), EMBEDDING_DIMENSION) async def test_rejects_wrong_embedding_dimension(self): class Client: diff --git a/tests/test_ingestion.py b/tests/test_ingestion.py index 8e1a51d..1e0918a 100644 --- a/tests/test_ingestion.py +++ b/tests/test_ingestion.py @@ -1,6 +1,7 @@ import unittest from unittest.mock import AsyncMock +from rag.embedding import EMBEDDING_DIMENSION from rag.ingestion import ingest_document_atomic @@ -35,7 +36,7 @@ class AtomicIngestionTests(unittest.IsolatedAsyncioTestCase): async def test_milvus_failure_cleans_up_partial_document_rows(self): milvus = AsyncMock() milvus.insert.side_effect = RuntimeError("insert down") - embedder = AsyncMock(return_value=[[0.0] * 768]) + embedder = AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION]) with self.assertRaises(RuntimeError): await ingest_document_atomic( @@ -49,7 +50,7 @@ class AtomicIngestionTests(unittest.IsolatedAsyncioTestCase): async def test_success_inserts_complete_document_rows(self): milvus = AsyncMock() - embedder = AsyncMock(return_value=[[0.0] * 768]) + embedder = AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION]) result = await ingest_document_atomic( "plain text", "doc-4", "Policy", "fin_policy", "default", @@ -62,7 +63,7 @@ class AtomicIngestionTests(unittest.IsolatedAsyncioTestCase): async def test_cleans_text_before_embedding_and_milvus_insert(self): milvus = AsyncMock() - embedder = AsyncMock(return_value=[[0.0] * 768, [0.0] * 768]) + embedder = AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION, [0.0] * EMBEDDING_DIMENSION]) await ingest_document_atomic( "\ufeff基金名称:示例基金\r\n\r\n\r\n风险等级:R3\t ", diff --git a/tests/test_knowledge_router.py b/tests/test_knowledge_router.py index d18f13e..4e4fa76 100644 --- a/tests/test_knowledge_router.py +++ b/tests/test_knowledge_router.py @@ -9,6 +9,7 @@ from api.chat.knowledge import ( list_documents, preview_document_upload, ) +from rag.embedding import EMBEDDING_DIMENSION from service.knowledge_base.upload import KnowledgeUploadService from types import SimpleNamespace @@ -65,14 +66,13 @@ class KnowledgeRouterTests(unittest.IsolatedAsyncioTestCase): service = KnowledgeUploadService( storage_dir=tmp, milvus_client=AsyncMock(), - embedder=AsyncMock(return_value=[[0.0] * 768]), + embedder=AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION]), publisher=AsyncMock(), ) - preview = await service.preview("faq.md", b"Q: Q\nA: A", strategy="qa_pair") request = FakeRequest( service, - json_data={ - "upload_id": preview["upload_id"], + form_data={ + "file": FakeUpload("faq.md", b"Q: Q\nA: A"), "title": "FAQ", "doc_id": "doc-1", "collection_name": "fin_faq", @@ -144,4 +144,4 @@ class KnowledgeRouterTests(unittest.IsolatedAsyncioTestCase): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/tests/test_knowledge_upload.py b/tests/test_knowledge_upload.py index acb6980..4443551 100644 --- a/tests/test_knowledge_upload.py +++ b/tests/test_knowledge_upload.py @@ -5,6 +5,7 @@ import time from pathlib import Path from unittest.mock import AsyncMock +from rag.embedding import EMBEDDING_DIMENSION from rag.events import KNOWLEDGE_UPDATE_EVENT from service.knowledge_base.upload import KnowledgeUploadService, UploadValidationError @@ -34,21 +35,17 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): with tempfile.TemporaryDirectory() as tmp: publisher = AsyncMock() milvus = AsyncMock() - embedder = AsyncMock(return_value=[[0.0] * 768]) + embedder = AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION]) service = KnowledgeUploadService( storage_dir=tmp, milvus_client=milvus, embedder=embedder, publisher=publisher, ) - preview = await service.preview( - filename="faq.md", - content="Q: 什么是基金?\nA: 一种集合投资工具。".encode(), - strategy="qa_pair", - ) result = await service.confirm( - upload_id=preview["upload_id"], + filename="faq.md", + content="Q: 什么是基金?\nA: 一种集合投资工具。".encode(), title="FAQ", doc_id="doc-upload-1", collection_name="fin_faq", @@ -58,24 +55,23 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): self.assertEqual(result["doc_id"], "doc-upload-1") publisher.assert_awaited_once() self.assertEqual(publisher.await_args.args[0], KNOWLEDGE_UPDATE_EVENT) - self.assertFalse(Path(tmp, preview["stored_filename"]).exists()) + self.assertEqual(len(list(Path(tmp).glob("*.md"))), 0) + self.assertEqual(len(list(Path(tmp).glob("*.json"))), 0) async def test_confirm_passes_custom_chunk_config_to_ingestion(self): with tempfile.TemporaryDirectory() as tmp: milvus = AsyncMock() - embedder = AsyncMock(side_effect=lambda texts: [[0.0] * 768 for _ in texts]) + embedder = AsyncMock(side_effect=lambda texts: [[0.0] * EMBEDDING_DIMENSION for _ in texts]) service = KnowledgeUploadService( storage_dir=tmp, milvus_client=milvus, embedder=embedder, publisher=AsyncMock(), ) - preview = await service.preview( - "doc.md", "一二三四五六七八九十十一十二".encode(), strategy="default" - ) await service.confirm( - upload_id=preview["upload_id"], + filename="doc.md", + content="一二三四五六七八九十十一十二".encode(), title="Doc", doc_id="doc-config", collection_name="fin_fund_doc", @@ -93,16 +89,14 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): service = KnowledgeUploadService( storage_dir=tmp, milvus_client=milvus, - embedder=AsyncMock(return_value=[[0.0] * 768]), + embedder=AsyncMock(return_value=[[0.0] * EMBEDDING_DIMENSION]), publisher=publisher, ) - preview = await service.preview( - "policy.md", b"policy text", strategy="default" - ) with self.assertRaises(RuntimeError): await service.confirm( - upload_id=preview["upload_id"], + filename="policy.md", + content=b"policy text", title="Policy", doc_id="doc-event-failure", collection_name="fin_policy", @@ -134,14 +128,15 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): embedder=AsyncMock(), publisher=AsyncMock(), ) - preview = await service.preview( - "faq.md", b"Q: Q\nA: A", strategy="qa_pair" - ) with self.assertRaises(UploadValidationError): await service.confirm( - upload_id=preview["upload_id"], title="FAQ", doc_id="d1", - collection_name="evil_collection", strategy="qa_pair", + filename="faq.md", + content=b"Q: Q\nA: A", + title="FAQ", + doc_id="d1", + collection_name="evil_collection", + strategy="qa_pair", ) async def test_confirm_rejects_duplicate_doc_id_before_embedding(self): @@ -154,14 +149,15 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): publisher=AsyncMock(), document_exists=lambda doc_id: True, ) - preview = await service.preview( - "faq.md", b"Q: Q\nA: A", strategy="qa_pair" - ) with self.assertRaises(UploadValidationError): await service.confirm( - upload_id=preview["upload_id"], title="FAQ", doc_id="d1", - collection_name="fin_faq", strategy="qa_pair", + filename="faq.md", + content=b"Q: Q\nA: A", + title="FAQ", + doc_id="d1", + collection_name="fin_faq", + strategy="qa_pair", ) embedder.assert_not_awaited() @@ -187,28 +183,23 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): self.assertFalse(path.exists()) self.assertFalse(manifest.exists()) - async def test_confirm_rejects_expired_upload(self): + async def test_confirm_rejects_unsupported_extension(self): with tempfile.TemporaryDirectory() as tmp: service = KnowledgeUploadService( storage_dir=tmp, - upload_ttl_seconds=60, milvus_client=AsyncMock(), embedder=AsyncMock(), publisher=AsyncMock(), ) - preview = await service.preview("faq.md", b"Q: Q\nA: A", strategy="qa_pair") - path = Path(tmp, preview["stored_filename"]) - old = time.time() - 120 - os.utime(path, (old, old)) - os.utime(Path(tmp, f"{preview['upload_id']}.json"), (old, old)) with self.assertRaises(UploadValidationError): await service.confirm( - upload_id=preview["upload_id"], - title="FAQ", - doc_id="expired-doc", + filename="script.exe", + content=b"bad", + title="Bad", + doc_id="bad-doc", collection_name="fin_faq", - strategy="qa_pair", + strategy="default", ) async def test_delete_document_removes_vectors_and_publishes_update(self): @@ -287,4 +278,4 @@ class KnowledgeUploadTests(unittest.IsolatedAsyncioTestCase): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/tests/test_milvus_collections.py b/tests/test_milvus_collections.py index 0d68157..c199b26 100644 --- a/tests/test_milvus_collections.py +++ b/tests/test_milvus_collections.py @@ -2,7 +2,20 @@ import unittest from unittest.mock import AsyncMock, call from unittest.mock import patch -from rag.milvus_collections import KNOWLEDGE_COLLECTIONS, ensure_collections +from rag.milvus_collections import ( + EMBEDDING_DIMENSION, + KNOWLEDGE_COLLECTIONS, + ensure_collections, +) + + +def _existing_client(dim: int) -> AsyncMock: + client = AsyncMock() + client.has_collection.return_value = True + client.describe_collection.return_value = { + "fields": [{"name": "vector", "params": {"dim": dim}}] + } + return client class MilvusCollectionTests(unittest.IsolatedAsyncioTestCase): @@ -19,14 +32,19 @@ class MilvusCollectionTests(unittest.IsolatedAsyncioTestCase): self.assertEqual(client.create_collection.await_count, len(KNOWLEDGE_COLLECTIONS)) async def test_reuses_existing_collections(self): - client = AsyncMock() - client.has_collection.return_value = True + client = _existing_client(EMBEDDING_DIMENSION) await ensure_collections(client) client.create_collection.assert_not_awaited() - async def test_collection_schema_contains_metadata_and_768_vector(self): + async def test_existing_collection_with_wrong_dimension_raises(self): + client = _existing_client(EMBEDDING_DIMENSION + 1) + + with self.assertRaises(RuntimeError): + await ensure_collections(client) + + async def test_collection_schema_contains_metadata_and_1024_vector(self): client = AsyncMock() client.has_collection.return_value = False @@ -36,11 +54,10 @@ class MilvusCollectionTests(unittest.IsolatedAsyncioTestCase): fields = {field["name"] for field in schema.to_dict()["fields"]} self.assertTrue({"chunk_id", "doc_id", "title", "section_title", "text", "strategy", "vector"} <= fields) vector = next(field for field in schema.to_dict()["fields"] if field["name"] == "vector") - self.assertEqual(vector["params"]["dim"], 768) + self.assertEqual(vector["params"]["dim"], 1024) async def test_default_path_uses_configured_milvus_client(self): - client = AsyncMock() - client.has_collection.return_value = True + client = _existing_client(EMBEDDING_DIMENSION) with patch("rag.milvus_collections.configured_milvus_client", return_value=client): await ensure_collections() diff --git a/tool/llm.py b/tool/llm.py index fb5f469..c11e5e9 100644 --- a/tool/llm.py +++ b/tool/llm.py @@ -1,14 +1,18 @@ -"""统一 LLM 客户端:本地 Ollama / OpenAI 兼容 API(api_key)双模式。 +"""统一 LLM 客户端:本地 Ollama / OpenAI 兼容 API(api_key)双后端,按优先级降级。 -设计:两个模式的底层都是 OpenAI 兼容 /v1 端点,切换只改配置(LLM_MODE), -业务代码一律调用 `chat()` / `embed()`,不感知底层。失败自动指数退避重试, -主模型失败切换备用模型(fallback_chat_model),再失败抛 LLMFailError(§1001), -调用方兜底话术见 FALLBACK_REPLY(降级链与原需求文档一致)。 +设计:两个后端的底层都是 OpenAI 兼容 /v1 端点,业务代码一律调用 `chat()` / `embed()`, +不感知底层。后端链由 .env 决定(LLM_MODE): + - auto(默认):本地 Ollama 参数齐全则优先本地,LLM_API_KEY 齐全则作为其后的降级后端; + - ollama / api:强制只用该后端。 +chat 降级链:后端内 主模型 → fallback_chat_model(每模型指数退避重试)→ 下一后端 → 全部失败抛 +LLMFailError(§1001),调用方兜底话术见 FALLBACK_REPLY。 +embed 只走首选后端、不跨后端降级:不同模型的向量空间不兼容,混入 Milvus 会污染检索。 """ from __future__ import annotations import asyncio import logging +from dataclasses import dataclass import httpx @@ -17,40 +21,112 @@ from utils.exceptions import LLMFailError logger = logging.getLogger("tool.llm") -# 兜底话术:主模型 + 备用模型均失败时返回 +# 兜底话术:所有后端 + 备用模型均失败时返回 FALLBACK_REPLY = "抱歉,服务暂时不可用,请稍后再试,或拨打客服热线 400-XXX-XXXX。" +@dataclass(frozen=True) +class Backend: + """一个 OpenAI 兼容端点及其模型;name 为 ollama / api。""" + + name: str + base_url: str # 以 /v1 结尾 + chat_model: str + embed_model: str + api_key: str = "" + + @property + def is_ollama(self) -> bool: + return self.name == "ollama" + + @property + def headers(self) -> dict: + h = {"Content-Type": "application/json"} + if self.api_key: + h["Authorization"] = f"Bearer {self.api_key}" + return h + + def client(self, timeout: float) -> httpx.AsyncClient: + """ollama 走本机端点,必须绕过系统代理:httpx 会读取 Windows 系统代理, + 但不识别其 ProxyOverride 白名单,localhost 请求会被转发到代理并返回 502。 + API 后端保留 trust_env,远端接口可能依赖代理。""" + return httpx.AsyncClient(timeout=timeout, trust_env=not self.is_ollama) + + +def resolve_backends(cfg: LLMCfg) -> list[Backend]: + """按 LLM_MODE 与 .env 完整度解析后端链,首个为首选后端。""" + ollama = ( + Backend( + name="ollama", + base_url=cfg.ollama_base.rstrip("/") + "/v1", + chat_model=cfg.ollama_chat_model, + embed_model=cfg.ollama_embed_model, + ) + if cfg.ollama_base and cfg.ollama_chat_model + else None + ) + api = ( + Backend( + name="api", + base_url=cfg.api_base.rstrip("/"), + chat_model=cfg.api_chat_model, + embed_model=cfg.api_embed_model, + api_key=cfg.api_key, + ) + if cfg.api_key and cfg.api_base and cfg.api_chat_model + else None + ) + mode = cfg.mode.lower() + if mode == "ollama": + chain = [ollama] + elif mode == "api": + chain = [api] + elif mode == "auto": + chain = [ollama, api] # 本地优先,API 兜底 + else: + raise ValueError(f"LLM_MODE 无效: {cfg.mode!r},应为 auto / ollama / api") + chain = [b for b in chain if b is not None] + if not chain: + raise ValueError( + f"LLM_MODE={cfg.mode} 下没有可用后端:本地需 LLM_OLLAMA_BASE + LLM_OLLAMA_CHAT_MODEL," + "API 需 LLM_API_KEY + LLM_API_BASE + LLM_API_CHAT_MODEL" + ) + return chain + + class LLMClient: def __init__(self, cfg: LLMCfg | None = None): self.cfg = cfg or settings.llm + self.backends = resolve_backends(self.cfg) + + # ---- 首选后端(健康检查/日志/embed 使用) ----------------------------- + @property + def primary(self) -> Backend: + return self.backends[0] - # ---- 模式解析:端点与模型由 LLM_MODE 决定 --------------------------- @property def is_ollama(self) -> bool: - return self.cfg.mode.lower() == "ollama" + return self.primary.is_ollama @property def base_url(self) -> str: - return (self.cfg.ollama_base + "/v1") if self.is_ollama else self.cfg.api_base + return self.primary.base_url @property def chat_model(self) -> str: - return self.cfg.ollama_chat_model if self.is_ollama else self.cfg.api_chat_model + return self.primary.chat_model @property def embed_model(self) -> str: - return self.cfg.ollama_embed_model if self.is_ollama else self.cfg.api_embed_model - - def _headers(self) -> dict: - h = {"Content-Type": "application/json"} - if not self.is_ollama: - h["Authorization"] = f"Bearer {self.cfg.api_key}" - return h + return self.primary.embed_model def describe(self) -> str: - """健康检查/日志用:当前模式 + 端点 + 模型。""" - return f"{self.cfg.mode} [{self.base_url}] chat={self.chat_model} embed={self.embed_model}" + """健康检查/日志用:后端链(首选在前)+ 各自模型。""" + chain = " -> ".join( + f"{b.name}[{b.base_url}] chat={b.chat_model} embed={b.embed_model or '-'}" + for b in self.backends + ) + return f"mode={self.cfg.mode} {chain}" # ---- 对话 ----------------------------------------------------------- async def chat( @@ -63,23 +139,31 @@ class LLMClient: ) -> str: """chat/completions,返回 assistant 文本。 - 模型降级链:model > chat_model > fallback_chat_model;每模型内部退避重试。 + 降级链:首选后端 [model > chat_model > fallback_chat_model] → 后续后端 [chat_model > + fallback_chat_model]。显式 model 只作用于首选后端——模型名与后端绑定,跨后端无意义。 """ - models = [model or self.chat_model] - if self.cfg.fallback_chat_model and self.cfg.fallback_chat_model not in models: - models.append(self.cfg.fallback_chat_model) - last_err: Exception | None = None - for m in models: - try: - return await self._chat_once(m, messages, temperature, max_tokens) - except Exception as e: # noqa: BLE001 重试/切换模型,异常向上收敛 - logger.warning("chat model=%r failed: %s: %s", m, type(e).__name__, e) - last_err = e + for index, backend in enumerate(self.backends): + models = [(model or backend.chat_model) if index == 0 else backend.chat_model] + if self.cfg.fallback_chat_model and self.cfg.fallback_chat_model not in models: + models.append(self.cfg.fallback_chat_model) + for m in models: + try: + return await self._chat_once(backend, m, messages, temperature, max_tokens) + except Exception as e: # noqa: BLE001 重试/切换模型或后端,异常向上收敛 + logger.warning( + "chat backend=%s model=%r failed: %s: %s", + backend.name, m, type(e).__name__, e, + ) + last_err = e + if index < len(self.backends) - 1: + logger.warning("backend=%s exhausted, falling back to %s", + backend.name, self.backends[index + 1].name) raise LLMFailError() from last_err async def _chat_once( self, + backend: Backend, model: str, messages: list[dict], temperature: float | None, @@ -92,12 +176,12 @@ class LLMClient: "max_tokens": self.cfg.max_tokens if max_tokens is None else max_tokens, "stream": False, } - url = f"{self.base_url}/chat/completions" + url = f"{backend.base_url}/chat/completions" # 指数退避:retry_backoff_sec → 翻倍 → …,最多 max_retries 次 for attempt in range(self.cfg.max_retries): try: - async with httpx.AsyncClient(timeout=self.cfg.timeout) as client: - r = await client.post(url, headers=self._headers(), json=payload) + async with backend.client(self.cfg.timeout) as client: + r = await client.post(url, headers=backend.headers, json=payload) r.raise_for_status() return r.json()["choices"][0]["message"]["content"] except Exception: @@ -108,11 +192,22 @@ class LLMClient: # ---- Embedding(RAG 入口的统一向量化) ------------------------------- async def embed(self, texts: list[str]) -> list[list[float]]: - """批量向量化,返回与 input 一一对应的向量列表(维度由模型决定)。""" - url = f"{self.base_url}/embeddings" - payload = {"model": self.embed_model, "input": texts} - async with httpx.AsyncClient(timeout=self.cfg.timeout) as client: - r = await client.post(url, headers=self._headers(), json=payload) + """批量向量化,返回与 input 一一对应的向量列表。 + + 只走首选后端(见模块说明)。按 OpenAI 兼容协议传 `dimensions`(来自 + LLM_EMBED_DIMENSIONS),MRL 模型(qwen3-embedding 等)会截断并重新归一化到目标维度。 + """ + backend = self.primary + if not backend.embed_model: + raise LLMFailError(f"backend={backend.name} 未配置 embed 模型") + url = f"{backend.base_url}/embeddings" + payload = { + "model": backend.embed_model, + "input": texts, + "dimensions": self.cfg.embed_dimensions, + } + async with backend.client(self.cfg.timeout) as client: + r = await client.post(url, headers=backend.headers, json=payload) r.raise_for_status() data = r.json() return [item["embedding"] for item in data["data"]] @@ -122,14 +217,17 @@ class LLMClient: # ---- 就绪探测(启动/健康检查可选接入) -------------------------------- async def check_health(self) -> None: - """验证当前模式端点可达。ollama 走 /api/tags,API 走 /models(需鉴权,401 也算可达)。""" - base = self.cfg.ollama_base if self.is_ollama else self.cfg.api_base - path = "/api/tags" if self.is_ollama else "/models" - async with httpx.AsyncClient(timeout=min(self.cfg.timeout, 10)) as client: - r = await client.get(f"{base}{path}", headers=self._headers()) + """验证首选后端端点可达。ollama 走 /api/tags,API 走 /models(需鉴权,401 也算可达)。""" + backend = self.primary + if backend.is_ollama: + url = backend.base_url.removesuffix("/v1") + "/api/tags" + else: + url = f"{backend.base_url}/models" + async with backend.client(min(self.cfg.timeout, 10)) as client: + r = await client.get(url, headers=backend.headers) if r.status_code >= 500: r.raise_for_status() # 全局单例:Agent 统一引入 -llm = LLMClient() \ No newline at end of file +llm = LLMClient() diff --git a/公司信息/faq.md b/公司信息/faq.md new file mode 100644 index 0000000..2c0a7a7 --- /dev/null +++ b/公司信息/faq.md @@ -0,0 +1,119 @@ +Q: 什么是开放式基金? +A: 开放式基金的基金份额总数不固定,投资者可以按照基金合同约定申购或赎回。 + +Q: 基金交易的确认时间是什么时候? +A: 通常以交易日收市时间为界,具体确认规则以基金合同和销售机构公告为准。 + +Q: 什么是货币基金? +A: 货币基金主要投资于短期货币市场工具,具体投资范围以基金合同为准。 + +Q: 什么是债券基金? +A: 债券基金主要投资于债券等固定收益类资产,仍可能受到市场波动影响。 + +Q: 什么是股票基金? +A: 股票基金主要投资于股票,净值波动通常与股票市场变化相关。 + +Q: 基金净值每天都会更新吗? +A: 开放式基金通常在交易日公布净值,具体时间以基金管理人公告为准。 + +Q: 基金申购是什么意思? +A: 申购是投资者按照基金份额净值购买开放式基金份额的行为。 + +Q: 基金赎回是什么意思? +A: 赎回是投资者向基金管理人申请卖出基金份额并取得资金的行为。 + +Q: 基金转换是什么? +A: 基金转换是将持有的一只基金份额转换为同一基金管理人旗下另一只基金份额。 + +Q: 基金定投是什么? +A: 基金定投是按约定周期和金额持续投资指定基金的方式。 + +Q: 基金分红会增加收益吗? +A: 基金分红通常是基金资产的一部分以现金或再投资形式分配给投资者,不等同于额外收益。 + +Q: 基金分红有哪些方式? +A: 常见方式包括现金分红和红利再投资,具体以基金合同及投资者设置为准。 + +Q: 基金费用包括哪些? +A: 基金费用可能包括管理费、托管费、销售服务费以及申购赎回费用等。 + +Q: 申购费什么时候收取? +A: 申购费通常在申购基金时收取,具体费率和收取方式以基金公告为准。 + +Q: 赎回费和持有时间有关吗? +A: 部分基金的赎回费率会根据持有期限设置差异,具体以基金合同为准。 + +Q: 基金有最低申购金额吗? +A: 不同基金和销售渠道可能设置不同的最低申购金额,应以对应页面和公告为准。 + +Q: 基金可以随时买卖吗? +A: 开放式基金通常可在开放日办理业务,封闭式基金和特殊产品规则可能不同。 + +Q: 节假日可以申购基金吗? +A: 节假日期间是否受理以及确认时间取决于基金和销售机构的业务安排。 + +Q: 基金交易日怎么判断? +A: 基金交易日通常参考证券交易所交易日安排,具体以基金管理人公告为准。 + +Q: 基金净值估算准确吗? +A: 净值估算仅为参考信息,最终净值以基金管理人公布的数据为准。 + +Q: 基金投资有本金保障吗? +A: 基金投资通常不承诺保本,投资者应阅读基金合同并自行承担相应风险。 + +Q: 如何查看基金风险等级? +A: 可在基金详情页、基金合同或销售机构风险揭示文件中查看风险等级。 + +Q: 风险承受能力评估是什么? +A: 风险承受能力评估用于了解投资者的风险偏好和承受能力,结果不代表收益承诺。 + +Q: 基金适合短期投资吗? +A: 是否适合短期投资取决于产品特征、投资目标和个人风险承受能力。 + +Q: 基金可以撤销交易吗? +A: 部分交易在规定时间内可能支持撤单,能否撤销应以销售机构规则为准。 + +Q: 基金认购和申购有什么区别? +A: 认购通常指募集期购买新基金,申购通常指基金成立后购买开放式基金份额。 + +Q: 新基金募集期多长? +A: 募集期长短因产品而异,以基金管理人发布的募集公告为准。 + +Q: 基金成立后多久可以赎回? +A: 具体开放赎回时间取决于基金合同和公告,封闭运作产品可能有特别安排。 + +Q: 基金规模会变化吗? +A: 开放式基金规模会随着申购、赎回和净值变化而变化。 + +Q: 基金经理会影响基金表现吗? +A: 基金经理是影响投资管理的重要因素之一,但不代表未来业绩保证。 + +Q: 基金历史业绩能代表未来吗? +A: 历史业绩仅供参考,不能代表未来收益,也不构成投资建议。 + +Q: 基金公告在哪里查看? +A: 可通过基金管理人官网、销售机构页面或依法披露的信息渠道查看。 + +Q: 基金合同是什么? +A: 基金合同约定基金运作方式、投资范围、费用和各方权利义务等重要事项。 + +Q: 基金招募说明书有什么作用? +A: 招募说明书介绍基金产品的重要信息,投资者应在投资前认真阅读。 + +Q: 什么是基金托管人? +A: 基金托管人依法保管基金财产并履行监督等职责,具体职责以法律法规为准。 + +Q: 什么是基金管理人? +A: 基金管理人负责基金募集、投资管理和信息披露等工作,并依法承担相应责任。 + +Q: 基金账户和银行卡一样吗? +A: 基金账户用于记录基金交易和份额信息,不等同于银行结算账户。 + +Q: 如何查询我的基金份额? +A: 可通过销售机构的账户或交易页面查询,具体查询方式以渠道功能为准。 + +Q: 基金赎回后资金多久到账? +A: 到账时间因基金类型、交易渠道和节假日安排而异,应以页面提示和公告为准。 + +Q: 基金暂停赎回是什么意思? +A: 暂停赎回表示在特定情形下暂时停止受理赎回申请,具体以相关公告为准。 diff --git a/公司信息/高频问答对.txt b/公司信息/高频问答对.txt index 970a24a..0090158 100644 --- a/公司信息/高频问答对.txt +++ b/公司信息/高频问答对.txt @@ -1,39 +1,116 @@ -公司全称是什么? 华夏科技有限公司,简称"华夏科技",英文名称HUAXIA Tech Co., Ltd. -公司什么时候成立的? 华夏科技于2016年2月22日在深圳市南山区高新区注册成立,至今已运营超过10年。 -公司的注册资本是多少? 华夏科技注册资本为人民币5亿元(50,000万元),已全额实缴。 -公司总部在哪里? 公司注册地址为深圳市南山区高新区科技南十二路18号A栋1602室,主要办公地点位于深圳市南山区粤海街道科苑南路2666号华润金融中心T3座36层。 -公司有哪些金融牌照? 华夏科技持有中国证监会颁发的基金销售牌照、中国银保监会批准的保险经纪牌照、以及证券投资咨询业务资格,是持牌综合金融服务机构。此外还持有私募基金管理人登记资格和QDII资格。 -公司业务覆盖哪些城市? 华夏科技在全国42个核心城市设有88家营业网点,涵盖一线、新一线和二线城市。 -公司目前的管理资产规模(AUM)是多少? 截至2026年8月底,华夏科技管理资产规模(AUM)超过628亿元人民币,2018-2025年年均复合增长率超过38.6%。 -公司服务多少客户? 华夏科技注册用户超过386万,有效客户超过142万,线下累计服务客户超过68万人。 -公司的客服电话是多少? 华夏科技客户服务热线为400-188-6618,服务时间为每天7:00-22:00(7×12小时),VIP客户享有7×24小时专属热线。 -公司的官方网站是什么? 华夏科技官方网站为www.huaxiatech.com,客户也可通过"华夏科技"APP(iOS/Android)办理业务。 -基金和理财产品有什么区别? 基金是由基金公司发行和管理的投资产品,通过华夏科技等代销渠道销售,净值每日公布,申赎灵活;理财产品通常由银行理财子公司发行,有固定期限和业绩比较基准,起购金额和期限各有不同。基金产品种类更丰富,覆盖货币型、债券型、混合型、股票型等多种风险等级。 -货币基金和债券基金有什么区别? 货币基金主要投资短期货币工具(如国债逆回购、银行存单),风险等级R1,收益稳定但较低,七日年化约2.0%左右,适合存放闲余资金;债券基金主要投资国债、企业债等固定收益资产,风险等级R2,收益略高(近一年约4-5%),但可能存在短期净值波动。 -R1到R5风险等级是什么意思? 这是金融产品风险等级分类:R1(低风险)如货币基金;R2(中低风险)如纯债基金、银行定期理财;R3(中风险)如混合基金、平衡型理财;R4(中高风险)如股票基金、QDII;R5(高风险)如期货、期权、私募股权。风险等级越高,潜在收益越大,但本金损失风险也越高。 -基金的起投金额是多少? 不同类型的基金起投金额不同:货币基金1元起投,债券基金1000元起投,混合基金5000元起投,股票基金1万元起投,QDII基金5万元起投。具体以产品说明书为准。 -基金申购后多久确认? 交易日15:00前提交的申购申请,T+1日确认份额(QDII基金为T+2日);15:00后提交则顺延至下一交易日。确认后即可查看持仓和收益。非交易日(周末及法定节假日)提交的申请顺延至下一交易日处理。 -基金赎回到账需要多长时间? 货币基金T+0快速赎回(单日限额1万元)或T+1普通赎回;债券基金T+2到T+3到账;混合基金和股票基金T+3到T+5到账;QDII基金T+7到T+10到账。赎回到账时间为交易日计算,遇节假日顺延。 -基金申购和赎回有哪些费率? 申购费率:货币基金0申购费,债券基金0.08%-0.8%(华夏科技享受1折优惠),混合基金0.15%-1.5%(1折优惠),股票基金0.15%-1.5%(1折优惠)。赎回费率:持有7天内赎回收取1.5%惩罚性赎回费,持有超过7天至30天收取0.75%,超过30天至365天收取0.5%,超过2年免赎回费。 -什么是基金的七日年化收益率? 七日年化收益率是货币基金过去七天每万份基金份额净收益折合成的年收益率,是一个短期指标,反映近期的盈利水平。七日年化会每天变化,投资者应关注30日年化、半年年化等中长期指标,而非仅看单日七日年化。 -什么是业绩比较基准? 业绩比较基准是基金设定的参考收益标准,不代表对投资者的实际收益承诺。例如"沪深300指数收益率×60%+中证全债指数收益率×40%"表示该混合基金的投资基准。实际收益可能高于或低于业绩比较基准。 -如何在华夏科技开户? 开户方式有三种:(1)线上开户——下载华夏科技APP,点击注册,上传身份证正反面照片,进行人脸识别,绑定银行卡,完成风险测评即可;(2)线下开户——携带身份证和银行卡前往任意财富中心,由理财经理协助办理;(3)官网开户——访问www.huaxiatech.com在线开户。整个流程约10-15分钟。 -开户需要哪些材料? 个人开户需准备:(1)本人有效身份证(二代居民身份证)原件;(2)本人名下银行借记卡(支持主流银行);(3)本人实名认证的手机号。线下开户还需携带身份证原件进行核验。 -什么是风险评估(KYC)? 风险评估即"了解你的客户"(Know Your Customer),是监管要求的必要流程。您需要回答一份涵盖收入、投资经验、风险承受能力、投资目标等维度的问卷,系统据此评定您的风险等级(C1保守型-C5激进型),并据此匹配适合的产品。评估结果有效期一年,到期需重新评估。 -我的风险评估结果是什么含义? 风险评估分为五个等级:C1保守型(适合R1低风险产品,如货币基金)、C2稳健型(适合R1-R2产品,如债券基金、银行理财)、C3平衡型(适合R1-R3产品,如混合基金)、C4进取型(适合R1-R4产品,如股票基金、QDII)、C5激进型(可投资R1-R5全部风险等级产品)。 -投资者适当性管理是什么? 投资者适当性管理是监管要求的核心制度,核心原则是"将适当的产品销售给适当的投资者"。具体要求:产品风险等级必须小于或等于客户的风险承受能力等级。如C2客户不能购买R3产品,除非客户签署《风险不匹配自愿购买确认书》并经过二次确认。 -什么是合格投资者? 合格投资者是指具备相应风险识别能力和风险承担能力的投资者。私募基金和资管产品的合格投资者标准:(1)具有2年以上投资经历;(2)家庭金融净资产不低于300万元,或家庭总资产不低于500万元,或近三年本人年均收入不低于40万元;(3)单只私募基金投资金额不低于100万元。 -公司有哪些投诉渠道? 投诉渠道包括:(1)拨打客服热线400-188-6618转投诉专线;(2)APP内"我的-帮助与反馈-我要投诉";(3)发送邮件至complaint@huaxiatech.com;(4)前往任意财富中心现场投诉。简单投诉24小时内回复,复杂投诉3个工作日内出具解决方案。 -反洗钱相关规定有哪些? 根据《反洗钱法》,客户开户需进行身份识别,大额交易(个人单笔或当日累计5万元以上)需提交大额交易报告。如发现客户交易行为异常(如频繁大额转账、资金快进快出、账户分散转入集中转出等),公司有义务向中国反洗钱监测分析中心报告可疑交易。请配合提供身份证件和资金来源证明。 -购买保险产品和基金有什么不同? 保险产品具有保障功能,通常有固定期限(如10年、20年、终身),提前退保可能有本金损失;基金产品主要是投资功能,申赎灵活(开放式基金)。保险产品适合有明确保障需求(如养老、身故保障、重疾保障)的客户,基金适合追求资产增值的客户。购买保险产品有15天犹豫期,犹豫期内退保全额退款。 -结构性存款安全吗? 结构性存款是在普通存款基础上嵌入金融衍生品(如期权)的产品,本金部分受存款保险制度保障(50万元以内),但收益部分与挂钩标的(如汇率、利率、指数)表现相关,实际收益可能高于或低于预期。结构性存款的风险等级通常为R2-R3,适合有一定风险承受能力的投资者。 -什么是基金定投? 基金定投是指在固定时间(如每周/每月)以固定金额投资指定基金的投资方式。定投利用"平均成本法"平滑市场波动,适合长期投资(建议3年以上)。华夏科技APP支持设置自动定投计划,最低每期100元起。历史数据显示,坚持定投3年以上的客户,正收益率超过90%。 -如何修改绑定的银行卡? 修改银行卡方式:(1)APP操作——"我的-银行卡管理-更换银行卡",需进行人脸识别验证;(2)线下办理——携带身份证和新银行卡至财富中心办理。注意:更换银行卡需确保原账户无在途交易,且新卡需为同一客户名下的同名银行卡。 -什么是基金投顾服务? 基金投顾(基金投资顾问)是华夏科技基于AI算法和专家研判,为客户提供基金组合投资建议的服务。客户授权后,投顾系统自动进行基金组合的构建、再平衡和调整。投顾服务年费率为管理资产规模的0.2%-0.5%,不额外收取申赎费用。目前提供"稳享人生""成长优选""全球配置"三种投顾策略。 -公司的服务时间是什么? 线上服务:APP和官网支持7×24小时下单交易;人工客服时间为每日7:00-22:00。线下门店:周一至周日9:00-17:30(部分门店周末轮休)。VIP客户享有7×24小时专属客户经理热线服务。 -什么是T日、T+1? T日指交易日(工作日),即提交交易申请的当天。15:00前提交的申请按T日净值确认,15:00后提交的申请按T+1日净值确认。T+1指下一个交易日,以此类推。例如周五15:00后的申购,按周一(T+1)的净值确认,周六周日不计入交易日。 -如何查询我的资产和收益? 查询方式:(1)APP查询——登录华夏科技APP,首页即可查看总资产、持仓收益、累计收益;(2)官网查询——登录www.huaxiatech.com个人账户;(3)对账单——每月1日系统自动发送上月资产对账单至注册邮箱;(4)联系客户经理获取详细资产配置报告。 -华夏科技的理财产品安全吗? 华夏科技是中国证监会、银保监会批准的持牌金融机构,所有代销产品均经过严格的产品准入评审。但需注意:除存款类产品受存款保险保障外,基金、理财等投资产品均不保本不保收益,投资者需根据自身风险承受能力审慎选择。公司严禁任何员工承诺保本保收益。 -如何联系我的专属客户经理? 您可以通过以下方式联系客户经理:(1)APP内"我的-我的顾问"查看并联系;(2)拨打客服热线400-188-6618,提供身份信息后由客服转接;(3)前往最近财富中心,由前台为您安排。VIP客户可直接拨打客户经理工作手机。 -什么是基金转换? 基金转换是指将持有的A基金份额直接转换为同一基金公司的B基金份额,无需先赎回再申购。转换可节省时间(T+1确认)和费用(仅需补差费率)。目前支持96家合作基金公司的产品互转,具体可在APP"基金转换"功能中操作。 -什么是净值型理财? 净值型理财产品没有固定的预期收益率,产品净值随投资收益波动。投资者按照产品净值进行申购和赎回,实际收益取决于产品运作期间的投资收益。净值型理财是资管新规后的主流产品形态,打破了原来的刚性兑付。 +Q: 公司全称是什么? +A: 华夏科技有限公司,简称"华夏科技",英文名称HUAXIA Tech Co., Ltd. + +Q: 公司什么时候成立的? +A: 华夏科技于2016年2月22日在深圳市南山区高新区注册成立,至今已运营超过10年。 + +Q: 公司的注册资本是多少? +A: 华夏科技注册资本为人民币5亿元(50,000万元),已全额实缴。 + +Q: 公司总部在哪里? +A: 公司注册地址为深圳市南山区高新区科技南十二路18号A栋1602室,主要办公地点位于深圳市南山区粤海街道科苑南路2666号华润金融中心T3座36层。 + +Q: 公司有哪些金融牌照? +A: 华夏科技持有中国证监会颁发的基金销售牌照、中国银保监会批准的保险经纪牌照、以及证券投资咨询业务资格,是持牌综合金融服务机构。此外还持有私募基金管理人登记资格和QDII资格。 + +Q: 公司业务覆盖哪些城市? +A: 华夏科技在全国42个核心城市设有88家营业网点,涵盖一线、新一线和二线城市。 + +Q: 公司目前的管理资产规模(AUM)是多少? +A: 截至2026年8月底,华夏科技管理资产规模(AUM)超过628亿元人民币,2018-2025年年均复合增长率超过38.6%。 + +Q: 公司服务多少客户? +A: 华夏科技注册用户超过386万,有效客户超过142万,线下累计服务客户超过68万人。 + +Q: 公司的客服电话是多少? +A: 华夏科技客户服务热线为400-188-6618,服务时间为每天7:00-22:00(7×12小时),VIP客户享有7×24小时专属热线。 + +Q: 公司的官方网站是什么? +A: 华夏科技官方网站为www.huaxiatech.com,客户也可通过"华夏科技"APP(iOS/Android)办理业务。 + +Q: 基金和理财产品有什么区别? +A: 基金是由基金公司发行和管理的投资产品,通过华夏科技等代销渠道销售,净值每日公布,申赎灵活;理财产品通常由银行理财子公司发行,有固定期限和业绩比较基准,起购金额和期限各有不同。基金产品种类更丰富,覆盖货币型、债券型、混合型、股票型等多种风险等级。 + +Q: 货币基金和债券基金有什么区别? +A: 货币基金主要投资短期货币工具(如国债逆回购、银行存单),风险等级R1,收益稳定但较低,七日年化约2.0%左右,适合存放闲余资金;债券基金主要投资国债、企业债等固定收益资产,风险等级R2,收益略高(近一年约4-5%),但可能存在短期净值波动。 + +Q: R1到R5风险等级是什么意思? +A: 这是金融产品风险等级分类:R1(低风险)如货币基金;R2(中低风险)如纯债基金、银行定期理财;R3(中风险)如混合基金、平衡型理财;R4(中高风险)如股票基金、QDII;R5(高风险)如期货、期权、私募股权。风险等级越高,潜在收益越大,但本金损失风险也越高。 + +Q: 基金的起投金额是多少? +A: 不同类型的基金起投金额不同:货币基金1元起投,债券基金1000元起投,混合基金5000元起投,股票基金1万元起投,QDII基金5万元起投。具体以产品说明书为准。 + +Q: 基金申购后多久确认? +A: 交易日15:00前提交的申购申请,T+1日确认份额(QDII基金为T+2日);15:00后提交则顺延至下一交易日。确认后即可查看持仓和收益。非交易日(周末及法定节假日)提交的申请顺延至下一交易日处理。 + +Q: 基金赎回到账需要多长时间? +A: 货币基金T+0快速赎回(单日限额1万元)或T+1普通赎回;债券基金T+2到T+3到账;混合基金和股票基金T+3到T+5到账;QDII基金T+7到T+10到账。赎回到账时间为交易日计算,遇节假日顺延。 + +Q: 基金申购和赎回有哪些费率? +A: 申购费率:货币基金0申购费,债券基金0.08%-0.8%(华夏科技享受1折优惠),混合基金0.15%-1.5%(1折优惠),股票基金0.15%-1.5%(1折优惠)。赎回费率:持有7天内赎回收取1.5%惩罚性赎回费,持有超过7天至30天收取0.75%,超过30天至365天收取0.5%,超过2年免赎回费。 + +Q: 什么是基金的七日年化收益率? +A: 七日年化收益率是货币基金过去七天每万份基金份额净收益折合成的年收益率,是一个短期指标,反映近期的盈利水平。七日年化会每天变化,投资者应关注30日年化、半年年化等中长期指标,而非仅看单日七日年化。 + +Q: 什么是业绩比较基准? +A: 业绩比较基准是基金设定的参考收益标准,不代表对投资者的实际收益承诺。例如"沪深300指数收益率×60%+中证全债指数收益率×40%"表示该混合基金的投资基准。实际收益可能高于或低于业绩比较基准。 + +Q: 如何在华夏科技开户? +A: 开户方式有三种:(1)线上开户——下载华夏科技APP,点击注册,上传身份证正反面照片,进行人脸识别,绑定银行卡,完成风险测评即可;(2)线下开户——携带身份证和银行卡前往任意财富中心,由理财经理协助办理;(3)官网开户——访问www.huaxiatech.com在线开户。整个流程约10-15分钟。 + +Q: 开户需要哪些材料? +A: 个人开户需准备:(1)本人有效身份证(二代居民身份证)原件;(2)本人名下银行借记卡(支持主流银行);(3)本人实名认证的手机号。线下开户还需携带身份证原件进行核验。 + +Q: 什么是风险评估(KYC)? +A: 风险评估即"了解你的客户"(Know Your Customer),是监管要求的必要流程。您需要回答一份涵盖收入、投资经验、风险承受能力、投资目标等维度的问卷,系统据此评定您的风险等级(C1保守型-C5激进型),并据此匹配适合的产品。评估结果有效期一年,到期需重新评估。 + +Q: 我的风险评估结果是什么含义? +A: 风险评估分为五个等级:C1保守型(适合R1低风险产品,如货币基金)、C2稳健型(适合R1-R2产品,如债券基金、银行理财)、C3平衡型(适合R1-R3产品,如混合基金)、C4进取型(适合R1-R4产品,如股票基金、QDII)、C5激进型(可投资R1-R5全部风险等级产品)。 + +Q: 投资者适当性管理是什么? +A: 投资者适当性管理是监管要求的核心制度,核心原则是"将适当的产品销售给适当的投资者"。具体要求:产品风险等级必须小于或等于客户的风险承受能力等级。如C2客户不能购买R3产品,除非客户签署《风险不匹配自愿购买确认书》并经过二次确认。 + +Q: 什么是合格投资者? +A: 合格投资者是指具备相应风险识别能力和风险承担能力的投资者。私募基金和资管产品的合格投资者标准:(1)具有2年以上投资经历;(2)家庭金融净资产不低于300万元,或家庭总资产不低于500万元,或近三年本人年均收入不低于40万元;(3)单只私募基金投资金额不低于100万元。 + +Q: 公司有哪些投诉渠道? +A: 投诉渠道包括:(1)拨打客服热线400-188-6618转投诉专线;(2)APP内"我的-帮助与反馈-我要投诉";(3)发送邮件至complaint@huaxiatech.com;(4)前往任意财富中心现场投诉。简单投诉24小时内回复,复杂投诉3个工作日内出具解决方案。 + +Q: 反洗钱相关规定有哪些? +A: 根据《反洗钱法》,客户开户需进行身份识别,大额交易(个人单笔或当日累计5万元以上)需提交大额交易报告。如发现客户交易行为异常(如频繁大额转账、资金快进快出、账户分散转入集中转出等),公司有义务向中国反洗钱监测分析中心报告可疑交易。请配合提供身份证件和资金来源证明。 + +Q: 购买保险产品和基金有什么不同? +A: 保险产品具有保障功能,通常有固定期限(如10年、20年、终身),提前退保可能有本金损失;基金产品主要是投资功能,申赎灵活(开放式基金)。保险产品适合有明确保障需求(如养老、身故保障、重疾保障)的客户,基金适合追求资产增值的客户。购买保险产品有15天犹豫期,犹豫期内退保全额退款。 + +Q: 结构性存款安全吗? +A: 结构性存款是在普通存款基础上嵌入金融衍生品(如期权)的产品,本金部分受存款保险制度保障(50万元以内),但收益部分与挂钩标的(如汇率、利率、指数)表现相关,实际收益可能高于或低于预期。结构性存款的风险等级通常为R2-R3,适合有一定风险承受能力的投资者。 + +Q: 什么是基金定投? +A: 基金定投是指在固定时间(如每周/每月)以固定金额投资指定基金的投资方式。定投利用"平均成本法"平滑市场波动,适合长期投资(建议3年以上)。华夏科技APP支持设置自动定投计划,最低每期100元起。历史数据显示,坚持定投3年以上的客户,正收益率超过90%。 + +Q: 如何修改绑定的银行卡? +A: 修改银行卡方式:(1)APP操作——"我的-银行卡管理-更换银行卡",需进行人脸识别验证;(2)线下办理——携带身份证和新银行卡至财富中心办理。注意:更换银行卡需确保原账户无在途交易,且新卡需为同一客户名下的同名银行卡。 + +Q: 什么是基金投顾服务? +A: 基金投顾(基金投资顾问)是华夏科技基于AI算法和专家研判,为客户提供基金组合投资建议的服务。客户授权后,投顾系统自动进行基金组合的构建、再平衡和调整。投顾服务年费率为管理资产规模的0.2%-0.5%,不额外收取申赎费用。目前提供"稳享人生""成长优选""全球配置"三种投顾策略。 + +Q: 公司的服务时间是什么? +A: 线上服务:APP和官网支持7×24小时下单交易;人工客服时间为每日7:00-22:00。线下门店:周一至周日9:00-17:30(部分门店周末轮休)。VIP客户享有7×24小时专属客户经理热线服务。 + +Q: 什么是T日、T+1? +A: T日指交易日(工作日),即提交交易申请的当天。15:00前提交的申请按T日净值确认,15:00后提交的申请按T+1日净值确认。T+1指下一个交易日,以此类推。例如周五15:00后的申购,按周一(T+1)的净值确认,周六周日不计入交易日。 + +Q: 如何查询我的资产和收益? +A: 查询方式:(1)APP查询——登录华夏科技APP,首页即可查看总资产、持仓收益、累计收益;(2)官网查询——登录www.huaxiatech.com个人账户;(3)对账单——每月1日系统自动发送上月资产对账单至注册邮箱;(4)联系客户经理获取详细资产配置报告。 + +Q: 华夏科技的理财产品安全吗? +A: 华夏科技是中国证监会、银保监会批准的持牌金融机构,所有代销产品均经过严格的产品准入评审。但需注意:除存款类产品受存款保险保障外,基金、理财等投资产品均不保本不保收益,投资者需根据自身风险承受能力审慎选择。公司严禁任何员工承诺保本保收益。 + +Q: 如何联系我的专属客户经理? +A: 您可以通过以下方式联系客户经理:(1)APP内"我的-我的顾问"查看并联系;(2)拨打客服热线400-188-6618,提供身份信息后由客服转接;(3)前往最近财富中心,由前台为您安排。VIP客户可直接拨打客户经理工作手机。 + +Q: 什么是基金转换? +A: 基金转换是指将持有的A基金份额直接转换为同一基金公司的B基金份额,无需先赎回再申购。转换可节省时间(T+1确认)和费用(仅需补差费率)。目前支持96家合作基金公司的产品互转,具体可在APP"基金转换"功能中操作。 + +Q: 什么是净值型理财? +A: 净值型理财产品没有固定的预期收益率,产品净值随投资收益波动。投资者按照产品净值进行申购和赎回,实际收益取决于产品运作期间的投资收益。净值型理财是资管新规后的主流产品形态,打破了原来的刚性兑付。 \ No newline at end of file