fix(ios): localize Agent Pro detail labels (#112980)

* fix(ios): preserve localized Agent Pro detail labels

* fix(ios): localize Dreaming metric labels

* test(ios): refresh native localization inventory

* test(setup): align isolated detection fallback

* test(system-agent): allow slow shared TUI setup

* test(chat): allow loaded outbox retry drain

---------

Co-authored-by: Alix-007 <li.long15@xydigit.com>
This commit is contained in:
Peter Steinberger
2026-07-23 09:01:07 -07:00
committed by GitHub
parent 34caf4b0dc
commit 9a624cd78f
7 changed files with 56 additions and 13 deletions
@@ -486,12 +486,12 @@ struct AgentProDreamingDestination: View {
}
}
private func detailMetric(label: String, value: String) -> some View {
private func detailMetric(label: OpenClawTextValue, value: String) -> some View {
VStack(alignment: .leading, spacing: 3) {
Text(label)
label.text
.font(OpenClawType.caption2Medium)
.foregroundStyle(.secondary)
Text(value)
Text(verbatim: value)
.font(OpenClawType.subheadSemiBold)
.lineLimit(1)
.minimumScaleFactor(0.8)
@@ -2,12 +2,12 @@ import OpenClawKit
import SwiftUI
extension AgentProTab {
func detailMetric(label: String, value: String) -> some View {
func detailMetric(label: OpenClawTextValue, value: String) -> some View {
VStack(alignment: .leading, spacing: 3) {
Text(label)
label.text
.font(OpenClawType.caption2Medium)
.foregroundStyle(.secondary)
Text(value)
Text(verbatim: value)
.font(OpenClawType.subheadSemiBold)
.lineLimit(1)
.minimumScaleFactor(0.8)
@@ -19,13 +19,17 @@ extension AgentProTab {
in: RoundedRectangle(cornerRadius: OpenClawRadius.sm, style: .continuous))
}
func emptyDetailRow(icon: String, title: String, detail: String) -> some View {
func emptyDetailRow(
icon: String,
title: OpenClawTextValue,
detail: OpenClawTextValue) -> some View
{
HStack(spacing: 12) {
ProIconBadge(systemName: icon, color: .secondary)
VStack(alignment: .leading, spacing: 3) {
Text(title)
title.text
.font(OpenClawType.subheadSemiBold)
Text(detail)
detail.text
.font(OpenClawType.caption)
.foregroundStyle(.secondary)
.lineLimit(2)
@@ -1749,7 +1749,7 @@ struct ChatViewModelOutboxTests {
vm.messages.first { vm.outboxState(for: $0.id)?.isFailed == true }?.id
})
await MainActor.run { vm.retryOutboxMessage(failedMessageID) }
try await waitUntil("retried command drained") {
try await waitUntil("retried command drained", timeoutSeconds: 30) {
await store.loadCommands().isEmpty
}
#expect(await transport.state.sentIdempotencyKeys.count == 1)
+12
View File
@@ -240,6 +240,18 @@ const LOCALIZED_WRAPPER_CONTRACTS: Record<string, readonly string[]> = {
"private func detailMetric(label: OpenClawTextValue, value: String)",
"title: OpenClawTextValue,\n detail: OpenClawTextValue",
],
"apps/ios/Sources/Design/AgentProDreamingDestination.swift": [
"private func detailMetric(label: OpenClawTextValue, value: String)",
"label.text",
"Text(verbatim: value)",
],
"apps/ios/Sources/Design/AgentProTab+DetailComponents.swift": [
"func detailMetric(label: OpenClawTextValue, value: String)",
"Text(verbatim: value)",
"func emptyDetailRow(\n icon: String,\n title: OpenClawTextValue,\n detail: OpenClawTextValue)",
"title.text",
"detail.text",
],
"apps/ios/Sources/Design/CommandCenterSupport.swift": [
"Text(verbatim: self.item.title)",
"Text(verbatim: self.item.trailing)",
@@ -1,6 +1,8 @@
import { createServer, get } from "node:http";
import type { AddressInfo } from "node:net";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { DEFAULT_AGENT_WORKSPACE_DIR } from "../agents/workspace-default.js";
import { listRecommendedToolInstalls } from "../plugins/recommended-tool-installs.js";
import type { SetupInferenceDetection } from "./setup-inference.js";
const blockingWorkerUrl = new URL(
@@ -20,8 +22,8 @@ function emptyDetection(): SetupInferenceDetection {
unavailableCandidates: [],
manualProviders: [],
authOptions: [],
recommendedInstalls: [],
workspace: "/tmp/work",
recommendedInstalls: listRecommendedToolInstalls(),
workspace: DEFAULT_AGENT_WORKSPACE_DIR,
setupComplete: false,
};
}
+1 -1
View File
@@ -155,7 +155,7 @@ describe("runSystemAgentTui", () => {
if (!options.backend || typeof options.backend !== "object") {
throw new Error("expected openclaw TUI backend");
}
});
}, 240_000);
it("reports the verified model without its auth profile and the effective thinking level", async () => {
const config = {
+25
View File
@@ -381,6 +381,14 @@ describe("Apple app i18n catalogs", () => {
"apps/ios/Sources/Design/AgentProTab+Overview.swift",
"utf8",
);
const agentDetailComponents = await readFile(
"apps/ios/Sources/Design/AgentProTab+DetailComponents.swift",
"utf8",
);
const agentDreaming = await readFile(
"apps/ios/Sources/Design/AgentProDreamingDestination.swift",
"utf8",
);
const settingsActions = await readFile(
"apps/ios/Sources/Design/SettingsProTabActions.swift",
"utf8",
@@ -423,6 +431,23 @@ describe("Apple app i18n catalogs", () => {
expect(agentOverview).toContain(
"func metricTile(\n icon: String,\n title: OpenClawTextValue,\n value: String,\n detail: OpenClawTextValue",
);
expect(agentDetailComponents).toContain(
"func detailMetric(label: OpenClawTextValue, value: String)",
);
expect(agentDetailComponents).toContain("Text(verbatim: value)");
expect(agentDetailComponents).toContain(
"func emptyDetailRow(\n icon: String,\n title: OpenClawTextValue,\n detail: OpenClawTextValue)",
);
expect(agentDetailComponents).toContain("title.text");
expect(agentDetailComponents).toContain("detail.text");
expect(agentDetailComponents).not.toContain("func detailMetric(label: String");
expect(agentDetailComponents).not.toContain("func emptyDetailRow(icon: String, title: String");
expect(agentDreaming).toContain(
"private func detailMetric(label: OpenClawTextValue, value: String)",
);
expect(agentDreaming).toContain("label.text");
expect(agentDreaming).toContain("Text(verbatim: value)");
expect(agentDreaming).not.toContain("private func detailMetric(label: String");
expect(settingsActions).toContain(
"func diagnosticCheckRow(\n icon: String,\n title: OpenClawTextValue,\n detail: OpenClawTextValue,\n value: OpenClawTextValue",
);