mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(ui): polish reasoning labels and settings margins
This commit is contained in:
@@ -52,6 +52,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/Codex: fail closed when an explicitly requested Codex harness is not registered instead of silently trying configured model fallbacks. Fixes #83349. Thanks @r2-vibes.
|
||||
- QA-Lab: make runtime tool coverage fail on missing required tool exercise instead of treating pass/pass parity envelope drift as missing coverage.
|
||||
- Core/plugins: harden clawpatch-reported edge cases across gateway auth cleanup, Claude session id paths, plugin activation policy, apply-patch hunk handling, diagnostic redaction, and plugin metadata validation.
|
||||
- UI: show reasoning choices as plain labels instead of leaking internal override wording in session and chat pickers.
|
||||
- Mac app: prefer explicit private/Tailscale/LAN Gateway endpoints over SSH tunnels, preserve legacy loopback tunnel configs, persist transport choices, and show captured SSH stderr when tunneling really fails.
|
||||
- Gateway/sessions: keep ACP/acpx and runtime child sessions visible in configured-only session lists when their owner or parent session belongs to a configured agent.
|
||||
- Mac app: keep app-level menu commands and Dashboard failure states reachable when the remote Gateway is disconnected, and keep the Settings sidebar toggle in the leading titlebar area.
|
||||
|
||||
@@ -14,7 +14,6 @@ struct ExecApprovalsSettings: View {
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.vertical, 4)
|
||||
.padding(.trailing, SettingsLayout.scrollbarGutter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function formatInheritedThinkingLabel(effectiveLevel: string | null | und
|
||||
if (!normalized || normalized === "off") {
|
||||
return "Off";
|
||||
}
|
||||
return `Inherited: ${normalized}`;
|
||||
return `Inherited: ${formatThinkingLevelDisplayLabel(normalized)}`;
|
||||
}
|
||||
|
||||
export function formatThinkingOverrideLabel(value: string, label?: string | null): string {
|
||||
@@ -18,6 +18,31 @@ export function formatThinkingOverrideLabel(value: string, label?: string | null
|
||||
if (!normalized || normalized === "off") {
|
||||
return "Off";
|
||||
}
|
||||
const displayLabel = label?.trim() || normalized;
|
||||
return `Override: ${displayLabel}`;
|
||||
return formatThinkingLevelDisplayLabel(label?.trim() || normalized);
|
||||
}
|
||||
|
||||
function formatThinkingLevelDisplayLabel(value: string): string {
|
||||
const raw = normalizeLowercaseStringOrEmpty(value);
|
||||
if (["on", "enable", "enabled"].includes(raw)) {
|
||||
return "On";
|
||||
}
|
||||
const normalized = normalizeThinkingOptionValue(value);
|
||||
switch (normalized) {
|
||||
case "adaptive":
|
||||
return "Adaptive";
|
||||
case "minimal":
|
||||
return "Minimal";
|
||||
case "low":
|
||||
return "Low";
|
||||
case "medium":
|
||||
return "Medium";
|
||||
case "high":
|
||||
return "High";
|
||||
case "xhigh":
|
||||
return "Extra high";
|
||||
case "max":
|
||||
return "Maximum";
|
||||
default:
|
||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1339,7 +1339,7 @@ describe("chat session controls", () => {
|
||||
]);
|
||||
expect(
|
||||
[...(thinkingSelect?.options ?? [])].map((option) => option.textContent?.trim()),
|
||||
).toEqual(["Off", "Off", "Override: adaptive", "Override: xhigh", "Override: maximum"]);
|
||||
).toEqual(["Off", "Off", "Adaptive", "Extra high", "Maximum"]);
|
||||
});
|
||||
|
||||
it("labels chat thinking default from the active session row", () => {
|
||||
@@ -1356,8 +1356,8 @@ describe("chat session controls", () => {
|
||||
);
|
||||
|
||||
expect(thinkingSelect?.value).toBe("");
|
||||
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: adaptive");
|
||||
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: Adaptive");
|
||||
});
|
||||
|
||||
it("always renders full thinking labels", () => {
|
||||
@@ -1387,14 +1387,14 @@ describe("chat session controls", () => {
|
||||
|
||||
expect(container.querySelector('select[data-chat-thinking-select-compact="true"]')).toBeNull();
|
||||
expect(thinkingSelect?.value).toBe("");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: high");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: High");
|
||||
expect([...thinkingSelect!.options].map((option) => option.textContent?.trim())).toEqual([
|
||||
"Inherited: high",
|
||||
"Inherited: High",
|
||||
"Off",
|
||||
"Override: low",
|
||||
"Override: medium",
|
||||
"Override: high",
|
||||
"Override: xhigh",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Extra high",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1411,7 +1411,7 @@ describe("chat session controls", () => {
|
||||
);
|
||||
|
||||
expect(thinkingSelect?.value).toBe("");
|
||||
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: adaptive");
|
||||
expect(thinkingSelect?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
|
||||
expect(thinkingSelect?.title).toBe("Inherited: Adaptive");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -272,7 +272,7 @@ describe("sessions view", () => {
|
||||
Array.from(thinking?.options ?? [])
|
||||
.find((option) => option.value === "max")
|
||||
?.textContent?.trim(),
|
||||
).toBe("Override: maximum");
|
||||
).toBe("Maximum");
|
||||
|
||||
thinking!.value = "max";
|
||||
thinking!.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
@@ -303,12 +303,12 @@ describe("sessions view", () => {
|
||||
|
||||
const thinking = container.querySelector("tbody select") as HTMLSelectElement | null;
|
||||
expect(thinking?.value).toBe("");
|
||||
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: adaptive");
|
||||
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: Adaptive");
|
||||
expect(
|
||||
Array.from(thinking?.options ?? [])
|
||||
.find((option) => option.value === "adaptive")
|
||||
?.textContent?.trim(),
|
||||
).toBe("Override: adaptive");
|
||||
).toBe("Adaptive");
|
||||
});
|
||||
|
||||
it("labels inherited thinking from list defaults when lightweight rows omit row defaults", async () => {
|
||||
@@ -340,9 +340,9 @@ describe("sessions view", () => {
|
||||
|
||||
const thinking = container.querySelector("tbody select") as HTMLSelectElement | null;
|
||||
expect(thinking?.value).toBe("");
|
||||
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: high");
|
||||
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: High");
|
||||
expect(Array.from(thinking?.options ?? []).map((option) => option.textContent?.trim())).toEqual(
|
||||
["Inherited: high", "Off", "Override: high"],
|
||||
["Inherited: High", "Off", "High"],
|
||||
);
|
||||
});
|
||||
|
||||
@@ -372,7 +372,7 @@ describe("sessions view", () => {
|
||||
Array.from(thinking?.options ?? [])
|
||||
.find((option) => option.value === "low")
|
||||
?.textContent?.trim(),
|
||||
).toBe("Override: on");
|
||||
).toBe("On");
|
||||
|
||||
thinking!.value = "low";
|
||||
thinking!.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
|
||||
Reference in New Issue
Block a user