From f3f11461de2297fe2356cbce7edd32abc1b0b85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=89=E9=91=AB=E5=8D=87?= Date: Thu, 25 Jun 2026 21:40:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(open-3qfx):=20=E5=85=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E5=BB=BA=E4=BC=9A=E8=AF=9D=E8=A1=A5=20default=20=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=8A=E4=B8=8B=E6=96=87,=E4=BF=AE=E5=A4=8D=20threa?= =?UTF-8?q?d=5Fmeta=20=E4=B8=8D=E8=90=BD=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 开放接口 /api/open/3qfx/ask 免登录、无 user context,start_run 写 thread_meta 前先 thread_store.get() 默认 user_id=AUTO,resolve_user_id(AUTO) 在无 context 时 抛 RuntimeError 被 start_run 的 try/except 当「非致命」吞掉,thread_meta 行从未 创建,前端按 metadata.taskId 怎么也搜不到这条会话(run 却已建)。 - 调 start_run 前显式 set_current_user 为 default 用户桶(后台 run_agent task 在 create_task 时快照此 context,故后台运行也归属 default,符合任务深链对话 全局共享、按创建者解析文件的语义),thread_meta 正常落库。 - 把 cop_task_detail_* 配置补到实际加载的 offline-backend-20260512/config.yaml (此前只加在不生效的 backend/config.yaml)。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../backend/app/gateway/routers/open_3qfx.py | 23 ++++++++++++++++++- offline-backend-20260512/config.yaml | 11 +++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/offline-backend-20260512/backend/app/gateway/routers/open_3qfx.py b/offline-backend-20260512/backend/app/gateway/routers/open_3qfx.py index ede4d92b..b15bb77a 100644 --- a/offline-backend-20260512/backend/app/gateway/routers/open_3qfx.py +++ b/offline-backend-20260512/backend/app/gateway/routers/open_3qfx.py @@ -42,6 +42,7 @@ from pydantic import BaseModel, Field from app.gateway.routers.thread_runs import RunCreateRequest from app.gateway.services import start_run from deerflow.config import get_app_config +from deerflow.runtime.user_context import DEFAULT_USER_ID, reset_current_user, set_current_user logger = logging.getLogger(__name__) @@ -51,6 +52,18 @@ router = APIRouter(prefix="/api/open/3qfx", tags=["open"]) _THREEQ_BUSINESS_CODE = "3Q" +class _OpenDefaultUser: + """开放接口(免登录)以「default」用户桶运行的占位 user。 + + 满足 :class:`deerflow.runtime.user_context.CurrentUser` 协议(仅需 ``.id``)。 + 免登录请求本身没有 user context,而 ``start_run`` 写 thread_meta 时默认 ``user_id=AUTO``, + 无 context 会抛 ``RuntimeError`` → 被 ``start_run`` 的 try/except 当「非致命」吞掉 → + **thread_meta 行从未创建**,于是前端按 ``metadata.taskId`` 怎么也搜不到这条会话。 + """ + + id = DEFAULT_USER_ID + + class ThreeQAskRequest(BaseModel): """3qfx 开放问答请求体。""" @@ -174,8 +187,16 @@ async def ask_3qfx(body: ThreeQAskRequest, request: Request) -> ThreeQAskRespons multitask_strategy="reject", ) + # 免登录 → 无 user context。显式设成「default」用户桶,否则 start_run 写 thread_meta 时 + # resolve_user_id(AUTO) 抛 RuntimeError 被吞掉,thread_meta 建不出来、前端按 taskId 搜不到。 + # run_agent 是后台 task,在 create_task 时快照本 context,故后台运行也归属 default 用户 + # (与 metadata.taskId「任务深链对话全局共享、按创建者解析文件」语义一致)。 # enforce_access=False:开放接口已自行解析 admin 配置的 3Q 智能体,不再按当前(无)登录用户做可见性校验。 - record = await start_run(run_body, thread_id, request, enforce_access=False) + token = set_current_user(_OpenDefaultUser()) + try: + record = await start_run(run_body, thread_id, request, enforce_access=False) + finally: + reset_current_user(token) return ThreeQAskResponse( thread_id=record.thread_id, diff --git a/offline-backend-20260512/config.yaml b/offline-backend-20260512/config.yaml index 34b86761..3360a25a 100644 --- a/offline-backend-20260512/config.yaml +++ b/offline-backend-20260512/config.yaml @@ -354,6 +354,9 @@ task_deeplink: test: true # 目的树查询走 mock.purpose_detail 假数据;同时 rwfx 进入「3q 是否完成」预检走 mock.sq_report 假数据 delete_test: true # 删除接口走 mock.delete 假数据(该接口尚未开发完) action_test: true # 行动→任务解析走 mock.action_detail 假数据(xdfx 行动id→任务id) + # 开放接口 POST /api/open/3qfx/ask 按 taskId 拉取任务详情拼开场白;上游不可达时打开下面开关走 mock.cop_task_detail。 + cop_task_detail_test: true + cop_task_detail_url: "https://ch1.b.uat.4.cn/consumer/taskAnalyseSearch/cop-task-detail" purpose_detail_url: "https://ch1.b.uat.4.cn/consumer/taskAnalyseSearch/getTaskPurposeDetail" # rwfx 与 xdfx 共用同一删除接口:rwfx 追加 ?taskId=(不传 actionId);xdfx 追加 ?actionId=(不传 taskId,直接不出现)。 delete_url: "https://ch1.b.uat.4.cn/bwjt/dropSixOrSevenData" @@ -417,3 +420,11 @@ task_deeplink: taskId: 3338 categoryType: "敌情关键事件 JSON" contentJson: "[{\"topic\":\"示例研判事件\",\"count\":1}]" + # cop_task_detail_test=true 时原样返回给开放接口 /api/open/3qfx/ask(结构同真实 cop-task-detail 返回)。 + cop_task_detail: + data: + id: 2055 + overview: "暑期文旅消费高峰期间的舆情态势综合研判与引导任务" + taskDirection: "正向引导 + 风险预警" + taskName: "任务01:暑期文旅舆情综合研判" + taskContent: "围绕暑期文旅消费高峰,对重点城市、重点景区的公众情绪与舆情态势做综合研判,识别情绪拐点与潜在风险,提出正向引导与处置建议。"