Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,22 @@ export async function verifyWorkspaceLocales({ browser, url, installApi, outputD

const page = await browser.newPage({ locale: "en-US", viewport: { width: 1440, height: 960 } });
try {
await installApi(page);
const api = await installApi(page);
await page.goto(url, { waitUntil: "networkidle" });
await page.getByTestId("personal-goal-home").waitFor();
assert.match(await page.getByRole("region", { name: "Control plane source" }).innerText(), /This machine/);
const englishText = await page.locator("body").innerText();
for (const chinese of ["本机", "仅查状态"]) assert.ok(!englishText.includes(chinese), `English Workspace shows ${chinese}`);
await page.screenshot({ path: resolve(outputDir, "locale-default-english.png") });
await page.getByRole("combobox", { name: "Select chat runtime", exact: true }).click();
const statusOnly = page.getByRole("option", { name: "Status only", exact: true });
assert.ok(await statusOnly.isVisible(), "English Runtime picker shows the translated status-only route");
await statusOnly.click();
await page.getByLabel("Send a message to LoopX").fill("Show the current state.");
await page.getByRole("button", { name: "Send", exact: true }).click();
await page.locator(".personal-manager-conversation-messages article.is-assistant > strong").getByText("Status only", { exact: true }).waitFor();
assert.equal(api.turnRequests.length, 0, "Localizing the status-only route must not start an Agent Turn");
assert.ok(!(await page.locator("body").innerText()).includes("LoopX 状态投影"), "The status-only reply source follows the selected language");
await page.setViewportSize({ width: 390, height: 844 });
await page.locator(".personal-channel-scroll").evaluate((element) => { element.scrollTop = 0; });
const clippedStats = await page.locator(".personal-digest-stats span").evaluateAll((stats) =>
Expand All @@ -86,6 +98,7 @@ export async function verifyWorkspaceLocales({ browser, url, installApi, outputD
await page.reload({ waitUntil: "networkidle" });
await page.getByTestId("personal-goal-home").waitFor();
assert.equal(await page.locator("html").getAttribute("lang"), "zh-CN");
assert.match(await page.getByRole("region", { name: "控制面来源" }).innerText(), /本机/);
await page.screenshot({ path: resolve(outputDir, "locale-saved-chinese.png") });
await page.getByRole("button", { name: "设置", exact: true }).click();
await page.getByRole("button", { name: /语言/ }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,9 @@ const en = {
"header.goalView": "Goal view",
"header.live": "Live",
"header.manager": "LoopX Manager",
"header.statusOnlyAgent": "Status only",
"header.statusOnlyDescription": "No model calls",
"header.statusProjection": "LoopX state projection",
"header.managerModelSettings": "Change steward model and reasoning effort",
"header.managerDescription": "Your personal workspace across Goals",
"header.managerRuntime": "{profile} · {sandbox}",
Expand Down Expand Up @@ -875,6 +878,7 @@ const en = {
"source.hostPlaceholder": "Enter or search for a Host",
"source.invalid": "The SSH source settings are invalid.",
"source.loadingHosts": "Loading…",
"source.local": "This machine",
"source.localInteractive": "Local interactive",
"source.localPort": "Local port",
"source.manual": "Manual URL",
Expand Down Expand Up @@ -1675,6 +1679,9 @@ const zhCN: Record<WorkspaceMessageKey, string> = {
"header.goalView": "Goal 视图",
"header.live": "实时",
"header.manager": "LoopX 管家",
"header.statusOnlyAgent": "仅查状态",
"header.statusOnlyDescription": "不调用模型",
"header.statusProjection": "LoopX 状态投影",
"header.managerModelSettings": "调整管家模型与思考深度",
"header.managerDescription": "跨 Goal 的个人工作入口",
"header.managerRuntime": "{profile} · {sandbox}",
Expand Down Expand Up @@ -2119,6 +2126,7 @@ const zhCN: Record<WorkspaceMessageKey, string> = {
"source.hostPlaceholder": "输入或搜索 Host",
"source.invalid": "SSH 来源参数无效。",
"source.loadingHosts": "正在读取…",
"source.local": "本机",
"source.localInteractive": "本机交互",
"source.localPort": "本地端口",
"source.manual": "手动 URL",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function StatusSourceSwitcher({
const [statusUrl, setStatusUrl] = useState("");
const quickAddPrefix = "configured:";
const sourceOptions = [
...sources.map((source) => ({ label: source.label, value: source.id })),
...sources.map((source) => ({ label: source.kind === "local" ? t("source.local") : source.label, value: source.id })),
...configuredHosts
.filter((host) => !sources.some((source) => source.label === host.alias))
.map((host) => ({
Expand Down
10 changes: 5 additions & 5 deletions apps/presentation/dashboard/src/views/dashboard-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1342,12 +1342,12 @@ function PersonalGoalHome({
{
agentId: "status-only",
available: true,
capability: "不调用模型",
capability: t("header.statusOnlyDescription"),
adapterKind: "status_projection",
interrupt: false,
label: "仅查状态",
label: t("header.statusOnlyAgent"),
resume: true,
statusLabel: "只读",
statusLabel: t("common.readOnly"),
streaming: false,
toolCalls: false,
trustScope: "read_only",
Expand Down Expand Up @@ -2215,9 +2215,9 @@ function PersonalGoalHome({
const answer = personalManagerSnapshot(targetQuestionModel);
const usesStatusOnlyRoute = selectedRoute.agentId === "status-only";
const answerMessageId = appendManagerAssistantMessage(targetContextId, {
agentLabel: usesStatusOnlyRoute ? "仅查状态" : "LoopX 管家",
agentLabel: usesStatusOnlyRoute ? t("header.statusOnlyAgent") : t("header.manager"),
lines: answer.lines.slice(0, 3),
sourceLabel: usesStatusOnlyRoute ? "LoopX 状态投影 · 仅查状态" : "LoopX 状态投影",
sourceLabel: usesStatusOnlyRoute ? `${t("header.statusProjection")} · ${t("header.statusOnlyAgent")}` : t("header.statusProjection"),
text: answer.text,
});
void recordProjectionExchange({
Expand Down
Loading