From 8c270987bd489afeace001349f83bb13366ede55 Mon Sep 17 00:00:00 2001 From: ThearchyHelios Date: Wed, 14 Oct 2026 08:28:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A8=E5=8A=A9=E6=89=8B=EF=BC=9A=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=B7=A5=E5=85=B7=E5=87=BA=E9=94=99=EF=BC=88=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E4=B8=8D=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E4=B9=8B=E7=B1=BB=EF=BC=89=E4=B9=9F=E5=9C=A8=E6=B5=81?= =?UTF-8?q?=E9=87=8C=E7=85=A7=E5=AE=9E=E4=BA=A4=E4=B8=80=E6=9D=A1=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BA=8B=E4=BB=B6=EF=BC=8C=E4=B8=8D=E8=AE=A9=E6=B5=81?= =?UTF-8?q?=E5=8D=8A=E8=B7=AF=E6=96=AD=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/data/catalog_assistant.py | 3 ++- backend/tests/test_catalog_assistant.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/app/data/catalog_assistant.py b/backend/app/data/catalog_assistant.py index 9dadbd98..c6e5d9fa 100644 --- a/backend/app/data/catalog_assistant.py +++ b/backend/app/data/catalog_assistant.py @@ -813,11 +813,12 @@ async def stream(model: Any, model_id: str, ctx: AssistantContext, history: list[Any] = [SystemMessage(content=ctx.system), *_history(messages)] tools = _Tools(ctx) - runner = model.bind_tools(ctx.tools()) usage = {"input_tokens": 0, "output_tokens": 0} wrote = "" names = [t["function"]["name"] for t in ctx.tools()] try: + # 绑工具也放在这里面:响应头已经发出去了,出了错要照实交一条错误事件,不能让流半路断掉 + runner = model.bind_tools(ctx.tools()) for round_no in range(MAX_ROUNDS): fresh = True message: Any = None diff --git a/backend/tests/test_catalog_assistant.py b/backend/tests/test_catalog_assistant.py index f8f90b6f..8013dd75 100644 --- a/backend/tests/test_catalog_assistant.py +++ b/backend/tests/test_catalog_assistant.py @@ -524,6 +524,19 @@ async def test_errors_end_the_stream_without_done(client, tmp_path, monkeypatch) assert "上限" in events[-1]["message"] +async def test_a_model_without_tools_reports_an_error_event(client, tmp_path, monkeypatch): + sid = await _source(client, tmp_path) + + class NoTools(Scripted): + def bind_tools(self, tools, **_): + raise NotImplementedError("这个模型不支持工具调用") + + use(monkeypatch, NoTools([])) + events, _ = await _talk(client, sid, _ask("你好")) + assert events == [{"type": "error", "code": "assistant_failed", "message": events[0]["message"]}] + assert "工具调用" in events[0]["message"] + + async def test_transient_errors_are_retried_before_any_output(client, tmp_path, monkeypatch): sid = await _source(client, tmp_path) monkeypatch.setattr(catalog_assistant, "RETRY_DELAYS_S", (0.0, 0.0))