feat: 支持多语言提示词本地化和界面优化
- 添加 prompt_locale 参数支持简体中文、繁体中文和英文提示词本地化 - 移除内置 agents 配置以简化系统架构 - 更新 ContextBuilder 使用动态提示词模板而非硬编码内容 - 在 AgentLoop、Web 接口和 AgentService 中传递 locale 参数 - 添加输出语言指令确保用户界面内容按指定语言生成 - 扩展前端 LanguageSwitcher 组件支持三种语言选项 - 优化 Header 和侧边栏组件的响应式布局和文本截断处理 - 更新测试用例验证不同语言环境下的提示词正确性
This commit is contained in:
@ -1,145 +1,4 @@
|
||||
{
|
||||
"agents": [
|
||||
{
|
||||
"agent_id": "researcher",
|
||||
"capabilities": [
|
||||
"research",
|
||||
"analysis",
|
||||
"source review",
|
||||
"requirements"
|
||||
],
|
||||
"created_at": "2026-05-27T05:25:11.756341+00:00",
|
||||
"description": "Finds facts, references, constraints, and implementation options.",
|
||||
"display_name": "Researcher",
|
||||
"metadata": {},
|
||||
"model": null,
|
||||
"name": "researcher",
|
||||
"priority": 50,
|
||||
"provider_name": null,
|
||||
"role": "research",
|
||||
"skill_names": [],
|
||||
"source": "builtin",
|
||||
"status": "active",
|
||||
"system_prompt": "You are a research specialist. Gather concise evidence and tradeoffs for the parent task.",
|
||||
"tags": [
|
||||
"planning",
|
||||
"research"
|
||||
],
|
||||
"tool_hints": [],
|
||||
"updated_at": "2026-05-27T05:25:11.756349+00:00"
|
||||
},
|
||||
{
|
||||
"agent_id": "implementer",
|
||||
"capabilities": [
|
||||
"implementation",
|
||||
"coding",
|
||||
"refactor",
|
||||
"integration"
|
||||
],
|
||||
"created_at": "2026-05-27T05:25:11.756351+00:00",
|
||||
"description": "Builds scoped implementation slices and proposes concrete changes.",
|
||||
"display_name": "Implementer",
|
||||
"metadata": {},
|
||||
"model": null,
|
||||
"name": "implementer",
|
||||
"priority": 45,
|
||||
"provider_name": null,
|
||||
"role": "implementation",
|
||||
"skill_names": [],
|
||||
"source": "builtin",
|
||||
"status": "active",
|
||||
"system_prompt": "You are an implementation specialist. Produce practical, scoped implementation output.",
|
||||
"tags": [
|
||||
"coding",
|
||||
"build"
|
||||
],
|
||||
"tool_hints": [],
|
||||
"updated_at": "2026-05-27T05:25:11.756353+00:00"
|
||||
},
|
||||
{
|
||||
"agent_id": "reviewer",
|
||||
"capabilities": [
|
||||
"review",
|
||||
"quality",
|
||||
"risk",
|
||||
"verification"
|
||||
],
|
||||
"created_at": "2026-05-27T05:25:11.756355+00:00",
|
||||
"description": "Reviews plans, code, outputs, and risks before final synthesis.",
|
||||
"display_name": "Reviewer",
|
||||
"metadata": {},
|
||||
"model": null,
|
||||
"name": "reviewer",
|
||||
"priority": 45,
|
||||
"provider_name": null,
|
||||
"role": "review",
|
||||
"skill_names": [],
|
||||
"source": "builtin",
|
||||
"status": "active",
|
||||
"system_prompt": "You are a review specialist. Focus on defects, missing requirements, and risks.",
|
||||
"tags": [
|
||||
"review",
|
||||
"quality"
|
||||
],
|
||||
"tool_hints": [],
|
||||
"updated_at": "2026-05-27T05:25:11.756356+00:00"
|
||||
},
|
||||
{
|
||||
"agent_id": "tester",
|
||||
"capabilities": [
|
||||
"testing",
|
||||
"verification",
|
||||
"regression",
|
||||
"qa"
|
||||
],
|
||||
"created_at": "2026-05-27T05:25:11.756358+00:00",
|
||||
"description": "Designs and executes verification checks for task outputs.",
|
||||
"display_name": "Tester",
|
||||
"metadata": {},
|
||||
"model": null,
|
||||
"name": "tester",
|
||||
"priority": 40,
|
||||
"provider_name": null,
|
||||
"role": "testing",
|
||||
"skill_names": [],
|
||||
"source": "builtin",
|
||||
"status": "active",
|
||||
"system_prompt": "You are a testing specialist. Identify focused checks and report pass/fail evidence.",
|
||||
"tags": [
|
||||
"test",
|
||||
"quality"
|
||||
],
|
||||
"tool_hints": [],
|
||||
"updated_at": "2026-05-27T05:25:11.756358+00:00"
|
||||
},
|
||||
{
|
||||
"agent_id": "documenter",
|
||||
"capabilities": [
|
||||
"documentation",
|
||||
"explanation",
|
||||
"migration notes",
|
||||
"release notes"
|
||||
],
|
||||
"created_at": "2026-05-27T05:25:11.756360+00:00",
|
||||
"description": "Writes and reconciles user-facing and internal documentation updates.",
|
||||
"display_name": "Documenter",
|
||||
"metadata": {},
|
||||
"model": null,
|
||||
"name": "documenter",
|
||||
"priority": 35,
|
||||
"provider_name": null,
|
||||
"role": "documentation",
|
||||
"skill_names": [],
|
||||
"source": "builtin",
|
||||
"status": "active",
|
||||
"system_prompt": "You are a documentation specialist. Produce concise docs aligned with the implementation.",
|
||||
"tags": [
|
||||
"docs",
|
||||
"communication"
|
||||
],
|
||||
"tool_hints": [],
|
||||
"updated_at": "2026-05-27T05:25:11.756360+00:00"
|
||||
}
|
||||
],
|
||||
"agents": [],
|
||||
"version": 1
|
||||
}
|
||||
|
||||
@ -27,13 +27,7 @@ from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
from beaver.memory.curated.snapshot import MemorySnapshot
|
||||
|
||||
|
||||
BEAVER_USER_ASSISTANT_IDENTITY_PROMPT = (
|
||||
"You are 海狸 (Beaver), an AI assistant developed by 博维资讯系统有限公司. "
|
||||
"When communicating with users, keep this identity consistent. "
|
||||
"If users ask who you are, say that you are 海狸 (Beaver), 博维资讯系统有限公司研发的 AI 助手."
|
||||
)
|
||||
from beaver.prompts import get_main_agent_prompt
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
@ -113,6 +107,7 @@ class ContextBuildInput:
|
||||
"""
|
||||
|
||||
base_system_prompt: str = ""
|
||||
prompt_locale: str | None = None
|
||||
history: list[dict[str, Any]] = field(default_factory=list)
|
||||
current_user_input: str | list[dict[str, Any]] | None = None
|
||||
memory_snapshot: MemorySnapshot | None = None
|
||||
@ -171,7 +166,7 @@ class ContextBuilder:
|
||||
- activated skill 正文放到显式消息里,避免 system prompt 持续膨胀
|
||||
"""
|
||||
|
||||
sections: list[str] = [BEAVER_USER_ASSISTANT_IDENTITY_PROMPT]
|
||||
sections: list[str] = [get_main_agent_prompt(build_input.prompt_locale)]
|
||||
|
||||
base_system_prompt = (build_input.base_system_prompt or "").strip()
|
||||
if base_system_prompt:
|
||||
|
||||
@ -224,6 +224,7 @@ class AgentLoop:
|
||||
title: str | None = None,
|
||||
execution_context: str | None = None,
|
||||
skill_selection_context: str | None = None,
|
||||
prompt_locale: str | None = None,
|
||||
model: str | None = None,
|
||||
provider_name: str | None = None,
|
||||
api_key: str | None = None,
|
||||
@ -275,6 +276,7 @@ class AgentLoop:
|
||||
title=title,
|
||||
execution_context=execution_context,
|
||||
skill_selection_context=skill_selection_context,
|
||||
prompt_locale=prompt_locale,
|
||||
model=model,
|
||||
provider_name=provider_name,
|
||||
api_key=api_key,
|
||||
@ -314,6 +316,7 @@ class AgentLoop:
|
||||
title: str | None = None,
|
||||
execution_context: str | None = None,
|
||||
skill_selection_context: str | None = None,
|
||||
prompt_locale: str | None = None,
|
||||
model: str | None = None,
|
||||
provider_name: str | None = None,
|
||||
api_key: str | None = None,
|
||||
@ -572,6 +575,7 @@ class AgentLoop:
|
||||
|
||||
build_input = ContextBuildInput(
|
||||
base_system_prompt=self.profile.system_prompt,
|
||||
prompt_locale=prompt_locale,
|
||||
history=session_manager.get_history(
|
||||
resolved_session_id,
|
||||
max_messages=max(1, self.profile.max_context_messages),
|
||||
|
||||
@ -2463,6 +2463,7 @@ def create_app(
|
||||
"user_id": payload.user_id,
|
||||
"title": payload.title,
|
||||
"execution_context": payload.execution_context,
|
||||
"prompt_locale": payload.prompt_locale,
|
||||
"model": payload.model,
|
||||
"provider_name": payload.provider_name,
|
||||
"embedding_model": payload.embedding_model,
|
||||
@ -2578,6 +2579,7 @@ def create_app(
|
||||
"user_id": _clean_text(payload.get("user_id")) or None,
|
||||
"title": _clean_text(payload.get("title")) or None,
|
||||
"execution_context": _clean_text(payload.get("execution_context")) or None,
|
||||
"prompt_locale": _clean_text(payload.get("prompt_locale")) or None,
|
||||
"model": _clean_text(payload.get("model")) or None,
|
||||
"provider_name": _clean_text(payload.get("provider_name")) or None,
|
||||
"embedding_model": _clean_text(payload.get("embedding_model")) or None,
|
||||
|
||||
@ -55,6 +55,7 @@ class WebChatRequest(BaseModel):
|
||||
user_id: str | None = None
|
||||
title: str | None = None
|
||||
execution_context: str | None = None
|
||||
prompt_locale: str | None = None
|
||||
model: str | None = None
|
||||
provider_name: str | None = None
|
||||
embedding_model: str | None = None
|
||||
|
||||
5
app-instance/backend/beaver/prompts/__init__.py
Normal file
5
app-instance/backend/beaver/prompts/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""Prompt templates used by Beaver runtime components."""
|
||||
|
||||
from .main_agent import get_main_agent_prompt
|
||||
|
||||
__all__ = ["get_main_agent_prompt"]
|
||||
55
app-instance/backend/beaver/prompts/main_agent.py
Normal file
55
app-instance/backend/beaver/prompts/main_agent.py
Normal file
@ -0,0 +1,55 @@
|
||||
"""Locale-aware main agent prompt loading."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_MAIN_AGENT_PROMPT_LOCALE = "zh-Hans"
|
||||
|
||||
_PROMPT_FILES = {
|
||||
"zh-Hans": "zh-Hans.md",
|
||||
"zh-Hant": "zh-Hant.md",
|
||||
"en": "en.md",
|
||||
}
|
||||
|
||||
_LOCALE_ALIASES = {
|
||||
"zh": "zh-Hans",
|
||||
"zh-cn": "zh-Hans",
|
||||
"zh-hans": "zh-Hans",
|
||||
"zh-sg": "zh-Hans",
|
||||
"zh-hant": "zh-Hant",
|
||||
"zh-tw": "zh-Hant",
|
||||
"zh-hk": "zh-Hant",
|
||||
"zh-mo": "zh-Hant",
|
||||
"en": "en",
|
||||
"en-us": "en",
|
||||
"en-gb": "en",
|
||||
}
|
||||
|
||||
|
||||
def get_main_agent_prompt(locale: str | None = None) -> str:
|
||||
"""Return the main-agent identity prompt for a prompt locale."""
|
||||
|
||||
prompt_locale = normalize_main_agent_prompt_locale(locale)
|
||||
return _load_main_agent_prompt(prompt_locale)
|
||||
|
||||
|
||||
def normalize_main_agent_prompt_locale(locale: str | None = None) -> str:
|
||||
cleaned = (locale or DEFAULT_MAIN_AGENT_PROMPT_LOCALE).strip()
|
||||
if not cleaned:
|
||||
return DEFAULT_MAIN_AGENT_PROMPT_LOCALE
|
||||
normalized = _LOCALE_ALIASES.get(cleaned.lower())
|
||||
if normalized:
|
||||
return normalized
|
||||
return cleaned if cleaned in _PROMPT_FILES else DEFAULT_MAIN_AGENT_PROMPT_LOCALE
|
||||
|
||||
|
||||
@lru_cache(maxsize=len(_PROMPT_FILES))
|
||||
def _load_main_agent_prompt(locale: str) -> str:
|
||||
filename = _PROMPT_FILES.get(locale, _PROMPT_FILES[DEFAULT_MAIN_AGENT_PROMPT_LOCALE])
|
||||
path = Path(__file__).with_name("main_agent") / filename
|
||||
if not path.exists():
|
||||
fallback_path = Path(__file__).with_name("main_agent") / _PROMPT_FILES[DEFAULT_MAIN_AGENT_PROMPT_LOCALE]
|
||||
return fallback_path.read_text(encoding="utf-8").strip()
|
||||
return path.read_text(encoding="utf-8").strip()
|
||||
7
app-instance/backend/beaver/prompts/main_agent/en.md
Normal file
7
app-instance/backend/beaver/prompts/main_agent/en.md
Normal file
@ -0,0 +1,7 @@
|
||||
You are Beaver, an AI assistant developed by Boway Information Systems Co., Ltd.
|
||||
|
||||
When communicating with users, keep this identity consistent. If users ask who you are, say that you are Beaver, an AI assistant developed by Boway Information Systems Co., Ltd.
|
||||
|
||||
# Language
|
||||
|
||||
Use English for user-facing replies, task titles, summaries, plans, and final reports while this prompt is active. If the user explicitly asks for another language, follow that request.
|
||||
@ -0,0 +1,7 @@
|
||||
你是海狸 (Beaver),博维资讯系统有限公司研发的 AI 助手。
|
||||
|
||||
与用户沟通时,保持这个身份一致。用户问你是谁时,说明你是海狸 (Beaver),博维资讯系统有限公司研发的 AI 助手。
|
||||
|
||||
# 语言
|
||||
|
||||
使用简体中文进行面向用户的回复、任务标题、摘要、计划和最终报告。若用户明确要求其他语言,则按用户要求执行。
|
||||
@ -0,0 +1,7 @@
|
||||
你是海狸 (Beaver),博維資訊系統有限公司研發的 AI 助手。
|
||||
|
||||
與使用者溝通時,保持這個身份一致。使用者問你是誰時,說明你是海狸 (Beaver),博維資訊系統有限公司研發的 AI 助手。
|
||||
|
||||
# 語言
|
||||
|
||||
使用繁體中文進行面向使用者的回覆、任務標題、摘要、計劃和最終報告。若使用者明確要求其他語言,則按使用者要求執行。
|
||||
@ -22,6 +22,7 @@ from beaver.engine import AgentLoop, AgentProfile, AgentRunResult, EngineLoader
|
||||
from beaver.engine.providers import make_provider_bundle
|
||||
from beaver.foundation.events import InboundMessage, OutboundMessage
|
||||
from beaver.foundation.models import CronJob, CronRunRecord
|
||||
from beaver.prompts.main_agent import normalize_main_agent_prompt_locale
|
||||
from beaver.tasks import (
|
||||
EvidenceBuilder,
|
||||
MainAgentRouter,
|
||||
@ -622,6 +623,7 @@ class AgentService:
|
||||
session_id=session_id,
|
||||
description=message,
|
||||
metadata={
|
||||
"prompt_locale": normalize_main_agent_prompt_locale(kwargs.get("prompt_locale")),
|
||||
"router_reason": decision.reason,
|
||||
**({"short_title": decision.short_title} if decision.short_title else {}),
|
||||
},
|
||||
@ -749,6 +751,8 @@ class AgentService:
|
||||
session_manager = self._require_loaded(loaded, "session_manager")
|
||||
|
||||
base_execution_context = kwargs.get("execution_context")
|
||||
prompt_locale = kwargs.get("prompt_locale") or task.metadata.get("prompt_locale")
|
||||
output_language_instruction = self._output_language_instruction(prompt_locale)
|
||||
provider_bundle = kwargs.get("provider_bundle") or self._make_provider_bundle_for_task(loaded, kwargs)
|
||||
kwargs = dict(kwargs)
|
||||
team_provider_bundle_factory = kwargs.pop("team_provider_bundle_factory", None)
|
||||
@ -843,8 +847,11 @@ class AgentService:
|
||||
"allow_candidate_generation": False,
|
||||
}
|
||||
)
|
||||
if team_execution_context:
|
||||
attempt_kwargs["execution_context"] = self._join_context(base_execution_context, team_execution_context)
|
||||
attempt_kwargs["execution_context"] = self._join_context(
|
||||
base_execution_context,
|
||||
output_language_instruction,
|
||||
team_execution_context,
|
||||
)
|
||||
if plan.is_team and team_execution_context:
|
||||
attempt_kwargs["include_tools"] = False
|
||||
attempt_kwargs["max_tool_iterations"] = 0
|
||||
@ -979,6 +986,24 @@ class AgentService:
|
||||
"short_title": decision.short_title,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _output_language_instruction(prompt_locale: str | None) -> str:
|
||||
locale = normalize_main_agent_prompt_locale(prompt_locale)
|
||||
if locale == "en":
|
||||
return (
|
||||
"Output language: English. Use English for user-facing task titles, summaries, plans, "
|
||||
"and final answers unless the user explicitly requests another language."
|
||||
)
|
||||
if locale == "zh-Hant":
|
||||
return (
|
||||
"輸出語言:繁體中文。除非使用者明確要求其他語言,所有面向使用者的任務標題、摘要、"
|
||||
"計劃與最終回答都使用繁體中文。"
|
||||
)
|
||||
return (
|
||||
"输出语言:简体中文。除非用户明确要求其他语言,所有面向用户的任务标题、摘要、"
|
||||
"计划与最终回答都使用简体中文。"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _skill_names_for_run(loaded: Any, run_id: str) -> list[str]:
|
||||
store = getattr(loaded, "run_memory_store", None)
|
||||
|
||||
@ -26,3 +26,26 @@ def test_context_builder_injects_current_date_and_time() -> None:
|
||||
assert "Local UTC offset: +08:00" in system_prompt
|
||||
assert '"today", "tomorrow", "now", "this week", and "next month"' in system_prompt
|
||||
assert result.messages[-1] == {"role": "user", "content": "今天几号?"}
|
||||
|
||||
|
||||
def test_context_builder_uses_simplified_main_agent_prompt_by_default() -> None:
|
||||
system_prompt = ContextBuilder().build_system_prompt(ContextBuildInput())
|
||||
|
||||
assert "你是海狸 (Beaver)" in system_prompt
|
||||
assert "博维资讯系统有限公司研发的 AI 助手" in system_prompt
|
||||
assert "使用简体中文进行面向用户的回复" in system_prompt
|
||||
|
||||
|
||||
def test_context_builder_uses_traditional_main_agent_prompt_for_zh_hant() -> None:
|
||||
system_prompt = ContextBuilder().build_system_prompt(ContextBuildInput(prompt_locale="zh-Hant"))
|
||||
|
||||
assert "你是海狸 (Beaver)" in system_prompt
|
||||
assert "博維資訊系統有限公司研發的 AI 助手" in system_prompt
|
||||
assert "使用繁體中文進行面向使用者的回覆" in system_prompt
|
||||
|
||||
|
||||
def test_context_builder_uses_english_main_agent_prompt_for_en() -> None:
|
||||
system_prompt = ContextBuilder().build_system_prompt(ContextBuildInput(prompt_locale="en"))
|
||||
|
||||
assert "You are Beaver, an AI assistant developed by Boway Information Systems Co., Ltd." in system_prompt
|
||||
assert "Use English for user-facing replies" in system_prompt
|
||||
|
||||
@ -15,6 +15,7 @@ class StubProvider(LLMProvider):
|
||||
def __init__(self, responses: list[LLMResponse]) -> None:
|
||||
super().__init__()
|
||||
self._responses = list(responses)
|
||||
self.seen_messages: list[list[dict]] = []
|
||||
|
||||
async def chat(
|
||||
self,
|
||||
@ -26,6 +27,7 @@ class StubProvider(LLMProvider):
|
||||
) -> LLMResponse:
|
||||
if not self._responses:
|
||||
raise AssertionError("No stubbed provider responses left")
|
||||
self.seen_messages.append(messages)
|
||||
return self._responses.pop(0)
|
||||
|
||||
def get_default_model(self) -> str:
|
||||
@ -99,6 +101,52 @@ def test_task_run_records_evidence_and_waits_for_acceptance(tmp_path: Path) -> N
|
||||
assert "validated" not in event_types
|
||||
|
||||
|
||||
def test_task_mode_injects_prompt_locale_output_language(tmp_path: Path) -> None:
|
||||
service = AgentService(
|
||||
loader=EngineLoader(
|
||||
workspace=tmp_path,
|
||||
task_execution_planner=StubTaskExecutionPlanner(),
|
||||
)
|
||||
)
|
||||
main_provider = StubProvider(
|
||||
[
|
||||
LLMResponse(
|
||||
content="Done",
|
||||
finish_reason="stop",
|
||||
provider_name="stub",
|
||||
model="stub-model",
|
||||
)
|
||||
]
|
||||
)
|
||||
bundle = ProviderBundle(
|
||||
main_runtime=SimpleNamespace(model="stub-model", provider_name="stub"),
|
||||
main_provider=main_provider,
|
||||
auxiliary_runtime=SimpleNamespace(model="stub-model", provider_name="stub"),
|
||||
auxiliary_provider=StubProvider([_route_response("new_task", "Product summary")]),
|
||||
)
|
||||
|
||||
result = asyncio.run(
|
||||
service.process_direct(
|
||||
"Summarize the uploaded report in English",
|
||||
session_id="web:locale-task",
|
||||
prompt_locale="en",
|
||||
provider_bundle=bundle,
|
||||
)
|
||||
)
|
||||
|
||||
assert result.task_id
|
||||
assert main_provider.seen_messages
|
||||
system_prompt = main_provider.seen_messages[-1][0]["content"]
|
||||
assert "Use English for user-facing replies" in system_prompt
|
||||
assert "Output language: English." in system_prompt
|
||||
|
||||
task_service = service.create_loop().boot().task_service
|
||||
assert task_service is not None
|
||||
task = task_service.get_task(result.task_id)
|
||||
assert task is not None
|
||||
assert task.metadata["prompt_locale"] == "en"
|
||||
|
||||
|
||||
def test_unrelated_simple_chat_auto_accepts_active_task(tmp_path: Path) -> None:
|
||||
service = AgentService(
|
||||
loader=EngineLoader(
|
||||
|
||||
@ -73,6 +73,7 @@ def test_websocket_message_returns_chat_metadata_and_session_updated() -> None:
|
||||
{
|
||||
"type": "message",
|
||||
"content": "hello",
|
||||
"prompt_locale": "zh-Hant",
|
||||
"metadata": {"source": "test"},
|
||||
"attachments": [{"file_id": "file-1", "name": "a.txt"}],
|
||||
}
|
||||
@ -89,6 +90,7 @@ def test_websocket_message_returns_chat_metadata_and_session_updated() -> None:
|
||||
"user_id": None,
|
||||
"title": None,
|
||||
"execution_context": None,
|
||||
"prompt_locale": "zh-Hant",
|
||||
"model": None,
|
||||
"provider_name": None,
|
||||
"embedding_model": None,
|
||||
@ -134,6 +136,7 @@ def test_websocket_message_uses_direct_processing_when_loop_is_not_running() ->
|
||||
"user_id": None,
|
||||
"title": None,
|
||||
"execution_context": None,
|
||||
"prompt_locale": None,
|
||||
"model": None,
|
||||
"provider_name": None,
|
||||
"embedding_model": None,
|
||||
@ -149,7 +152,10 @@ def test_rest_chat_uses_direct_processing_when_loop_is_not_running() -> None:
|
||||
app = create_app(service=service, manage_service_lifecycle=False)
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.post("/api/chat", json={"session_id": "web:alpha", "message": "hello"})
|
||||
response = client.post(
|
||||
"/api/chat",
|
||||
json={"session_id": "web:alpha", "message": "hello", "prompt_locale": "en"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert service.calls == [
|
||||
@ -160,6 +166,7 @@ def test_rest_chat_uses_direct_processing_when_loop_is_not_running() -> None:
|
||||
"user_id": None,
|
||||
"title": None,
|
||||
"execution_context": None,
|
||||
"prompt_locale": "en",
|
||||
"model": None,
|
||||
"provider_name": None,
|
||||
"embedding_model": None,
|
||||
|
||||
Reference in New Issue
Block a user