feat(frontend): add localized AI disclaimer (#4374)

* feat(frontend): add localized AI disclaimer

* fix(frontend): preserve sidecar composer alignment
This commit is contained in:
DanielWalnut 2026-07-22 21:31:27 +08:00 committed by GitHub
parent 1db84354bf
commit cb698832de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 47 additions and 1 deletions

View File

@ -682,6 +682,9 @@ Unsent Web UI composer drafts survive page reloads and switching between convers
The Web UI composer also supports browser-based voice dictation when the browser exposes the Web Speech API. The microphone button transcribes speech into the local draft only; DeerFlow receives only the transcribed text, while audio handling is delegated to the browser or operating system speech-recognition service according to that environment's policy. Users can review or edit the text before sending.
The Web UI displays a localized AI-generated-content disclaimer below the composer in both standard and custom-agent conversations, reminding users to verify important
information.
Interrupted first-turn runs still persist a fallback conversation title, so stopping a streaming response does not leave the thread as "Untitled" after refresh.
Streaming Markdown responses animate only newly arrived words; text that is already visible is not faded out and replayed when the next chunk extends the same block.

View File

@ -2689,6 +2689,15 @@ export function InputBox({
</div>
)}
<p
className={cn(
"text-muted-foreground/67 z-10 px-4 text-center text-xs leading-4",
!isWelcomeMode && "absolute top-full right-0 left-0",
)}
>
{t.inputBox.disclaimer}
</p>
<Dialog open={confirmOpen} onOpenChange={setConfirmOpen}>
<DialogContent>
<DialogHeader>

View File

@ -116,6 +116,7 @@ export const enUS: Translations = {
// Input Box
inputBox: {
placeholder: "How can I assist you today?",
disclaimer: "Deerflow is AI and can make mistakes",
createSkillPrompt:
"We're going to build a new skill step by step with `skill-creator`. To start, what do you want this skill to do?",
addAttachments: "Add attachments",

View File

@ -99,6 +99,7 @@ export interface Translations {
// Input Box
inputBox: {
placeholder: string;
disclaimer: string;
createSkillPrompt: string;
addAttachments: string;
inputPolish: string;

View File

@ -115,6 +115,7 @@ export const zhCN: Translations = {
// Input Box
inputBox: {
placeholder: "今天我能为你做些什么?",
disclaimer: "内容由AI生成重要信息请务必核查",
createSkillPrompt:
"我们一起用 skill-creator 技能来创建一个技能吧。先问问我希望这个技能能做什么。",
addAttachments: "添加附件",

View File

@ -31,7 +31,9 @@ test.describe("Agent chat", () => {
});
});
test("agent chat page loads with input box", async ({ page }) => {
test("agent chat page loads with input box and AI disclaimer", async ({
page,
}) => {
mockLangGraphAPI(page, { agents: MOCK_AGENTS });
await page.goto("/workspace/agents/test-agent/chats/new");
@ -39,6 +41,9 @@ test.describe("Agent chat", () => {
// The prompt input textarea should be visible
const textarea = page.getByPlaceholder(/how can i assist you/i);
await expect(textarea).toBeVisible({ timeout: 15_000 });
await expect(
page.getByText("Deerflow is AI and can make mistakes", { exact: true }),
).toBeVisible();
});
test("keeps new-chat drafts isolated between agents", async ({ page }) => {

View File

@ -34,6 +34,18 @@ test.describe("Chat workspace", () => {
await expect(page.getByRole("button", { name: /load more/i })).toBeHidden();
});
test("shows the localized AI disclaimer", async ({ page }) => {
await page.goto("/workspace/chats/new");
await page.evaluate(() => {
document.cookie = "locale=zh-CN; path=/; SameSite=Lax";
});
await page.reload();
await expect(
page.getByText("内容由AI生成重要信息请务必核查", { exact: true }),
).toBeVisible({ timeout: 15_000 });
});
test("can type a message in the input box", async ({ page }) => {
await page.goto("/workspace/chats/new");

View File

@ -0,0 +1,14 @@
import { describe, expect, it } from "@rstest/core";
import { translations } from "@/core/i18n/translations";
describe("AI disclaimer translations", () => {
it("provides the requested overseas and domestic copy", () => {
expect(translations["en-US"].inputBox.disclaimer).toBe(
"Deerflow is AI and can make mistakes",
);
expect(translations["zh-CN"].inputBox.disclaimer).toBe(
"内容由AI生成重要信息请务必核查",
);
});
});