feat: pass chat_template_kwargs through agent chat completion (#14542)

### What problem does this PR solve?

The agent API currently does not pass chat_template_kwargs to the
underlying LLM call path, so clients cannot control template-level model
behavior (such as thinking-mode toggles) when invoking
/agents/chat/completion. This PR adds passthrough support for
chat_template_kwargs across agent execution flows (session and
non-session, streaming and non-streaming) by propagating it through
canvas runtime state and into LLM invocation kwargs. This addresses the
feature gap raised in [Issue
#14182](https://github.com/infiniflow/ragflow/issues/14182).

Closes #14182 

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
Full Stack Developer
2026-05-22 02:15:49 -05:00
committed by GitHub
parent c33d0b8081
commit 8f90740d2e
5 changed files with 49 additions and 7 deletions

View File

@@ -177,6 +177,7 @@ async def _run_workflow_session(
canvas_category,
return_trace,
stream,
chat_template_kwargs=None,
):
async def commit_runtime_replica():
commit_ok = CanvasReplicaService.commit_after_run(
@@ -213,6 +214,14 @@ async def _run_workflow_session(
final_ans = {}
trace_items = []
structured_output = {}
run_kwargs = {
"query": query,
"files": files,
"user_id": user_id,
"inputs": inputs,
}
if chat_template_kwargs is not None:
run_kwargs["chat_template_kwargs"] = chat_template_kwargs
async def persist_workflow_session():
if not final_ans:
@@ -237,7 +246,7 @@ async def _run_workflow_session(
nonlocal full_content, reference, final_ans, trace_items, structured_output
done_sent = False
try:
async for ans in canvas.run(query=query, files=files, user_id=user_id, inputs=inputs):
async for ans in canvas.run(**run_kwargs):
ans["session_id"] = session_id
if ans.get("event") == "message":
full_content += ans.get("data", {}).get("content", "")
@@ -285,7 +294,7 @@ async def _run_workflow_session(
return _build_sse_response(sse())
try:
async for ans in canvas.run(query=query, files=files, user_id=user_id, inputs=inputs):
async for ans in canvas.run(**run_kwargs):
ans["session_id"] = session_id
if ans.get("event") == "message":
full_content += ans.get("data", {}).get("content", "")
@@ -1258,6 +1267,7 @@ async def agent_chat_completion(tenant_id, agent_id=None):
canvas_category=getattr(cvs, "canvas_category", CanvasCategory.Agent),
return_trace=bool(req.get("return_trace", False)),
stream=req.get("stream", True),
chat_template_kwargs=req.get("chat_template_kwargs"),
)
if not session_id:
@@ -1404,6 +1414,7 @@ async def agent_chat_completion(tenant_id, agent_id=None):
canvas_category=canvas_category,
return_trace=bool(req.get("return_trace", False)),
stream=req.get("stream", True),
chat_template_kwargs=req.get("chat_template_kwargs"),
)
return_trace = bool(req.get("return_trace", False))

View File

@@ -315,6 +315,7 @@ async def completion(tenant_id, agent_id, session_id=None, **kwargs):
files = kwargs.get("files", [])
inputs = kwargs.get("inputs", {})
user_id = kwargs.get("user_id", "")
chat_template_kwargs = kwargs.get("chat_template_kwargs")
custom_header = kwargs.get("custom_header", "")
release_mode = str(kwargs.get("release", "")).strip().lower()
@@ -347,7 +348,16 @@ async def completion(tenant_id, agent_id, session_id=None, **kwargs):
"files": files
})
txt = ""
async for ans in canvas.run(query=query, files=files, user_id=user_id, inputs=inputs):
run_kwargs = {
"query": query,
"files": files,
"user_id": user_id,
"inputs": inputs,
}
if chat_template_kwargs is not None:
run_kwargs["chat_template_kwargs"] = chat_template_kwargs
async for ans in canvas.run(**run_kwargs):
ans["session_id"] = session_id
if ans["event"] == "message":
txt += ans["data"]["content"]