refactor: simplify runtime conversions

This commit is contained in:
Peter Steinberger
2026-04-11 01:23:26 +01:00
parent 37b91be894
commit 9e0d358695
50 changed files with 80 additions and 98 deletions

View File

@@ -777,7 +777,7 @@ export function createAnthropicMessagesTransportStreamFn(): StreamFn {
delta?.type === "signature_delta" &&
typeof delta.signature === "string"
) {
block.thinkingSignature = `${String(block.thinkingSignature ?? "")}${delta.signature}`;
block.thinkingSignature = `${block.thinkingSignature ?? ""}${delta.signature}`;
}
continue;
}

View File

@@ -646,9 +646,7 @@ export async function compactEmbeddedPiSessionDirect(
if (promptCapabilities.length > 0) {
runtimeCapabilities ??= [];
const seenCapabilities = new Set(
runtimeCapabilities
.map((cap) => normalizeOptionalLowercaseString(String(cap)))
.filter(Boolean),
runtimeCapabilities.map((cap) => normalizeOptionalLowercaseString(cap)).filter(Boolean),
);
for (const capability of promptCapabilities) {
const normalizedCapability = normalizeOptionalLowercaseString(capability);

View File

@@ -611,9 +611,7 @@ export async function runEmbeddedAttempt(
if (promptCapabilities.length > 0) {
runtimeCapabilities ??= [];
const seenCapabilities = new Set(
runtimeCapabilities
.map((cap) => normalizeOptionalLowercaseString(String(cap)))
.filter(Boolean),
runtimeCapabilities.map((cap) => normalizeOptionalLowercaseString(cap)).filter(Boolean),
);
for (const capability of promptCapabilities) {
const normalizedCapability = normalizeOptionalLowercaseString(capability);

View File

@@ -3,7 +3,7 @@ import { compileGlobPatterns, matchesAnyGlobPattern } from "../../glob-pattern.j
import type { ContextPruningToolMatch } from "./settings.js";
function normalizeGlob(value: string) {
return normalizeLowercaseStringOrEmpty(String(value ?? ""));
return normalizeLowercaseStringOrEmpty(value ?? "");
}
export function makeToolPrunablePredicate(

View File

@@ -15,9 +15,7 @@ export type FallbackNoticeState = Pick<
>;
function truncateFallbackReasonPart(value: string, max = FALLBACK_REASON_PART_MAX): string {
const text = String(value ?? "")
.replace(/\s+/g, " ")
.trim();
const text = value.replace(/\s+/g, " ").trim();
if (text.length <= max) {
return text;
}

View File

@@ -104,7 +104,7 @@ export function buildThreadingToolContext(params: {
}
export const isBunFetchSocketError = (message?: string) =>
Boolean(message && BUN_FETCH_SOCKET_ERROR_RE.test(message));
message ? BUN_FETCH_SOCKET_ERROR_RE.test(message) : false;
export const formatBunFetchSocketError = (message: string) => {
const trimmed = message.trim();
@@ -121,15 +121,13 @@ export const resolveEnforceFinalTag = (
provider: string,
model = run.model,
) =>
Boolean(
(run.skipProviderRuntimeHints ? false : undefined) ??
(run.enforceFinalTag ||
isReasoningTagProvider(provider, {
config: run.config,
workspaceDir: run.workspaceDir,
modelId: model,
})),
);
(run.skipProviderRuntimeHints ? false : undefined) ??
(run.enforceFinalTag ||
isReasoningTagProvider(provider, {
config: run.config,
workspaceDir: run.workspaceDir,
modelId: model,
}));
export function resolveModelFallbackOptions(run: FollowupRun["run"]) {
const config = run.config;

View File

@@ -241,7 +241,7 @@ export function createBlockReplyPipeline(params: {
enqueue,
flush,
stop,
hasBuffered: () => Boolean(coalescer?.hasBuffered() || bufferedPayloads.length > 0),
hasBuffered: () => coalescer?.hasBuffered() || bufferedPayloads.length > 0,
didStream: () => didStream,
isAborted: () => aborted,
hasSentPayload: (payload) => {

View File

@@ -46,7 +46,7 @@ function resolveAllowFromFormatter(params: {
accountId: params.accountId,
allowFrom: values,
})
.map((entry) => normalizeOptionalString(String(entry)) ?? "")
.map((entry) => normalizeOptionalString(entry) ?? "")
.filter(Boolean);
}

View File

@@ -467,7 +467,7 @@ export function buildStatusMessage(args: StatusArgs): string {
initialFallbackState.active &&
normalizeLowercaseStringOrEmpty(runtimeModelRaw) ===
normalizeLowercaseStringOrEmpty(
normalizeOptionalString(String(entry?.fallbackNoticeActiveModel ?? "")) ?? "",
normalizeOptionalString(entry?.fallbackNoticeActiveModel ?? "") ?? "",
);
const runtimeMatchesSelectedModel =
normalizeLowercaseStringOrEmpty(runtimeModelRaw) ===

View File

@@ -465,7 +465,7 @@ export async function startCanvasHost(opts: CanvasHostServerOpts): Promise<Canva
const bindHost = normalizeOptionalString(opts.listenHost) || "127.0.0.1";
const server: Server = http.createServer((req, res) => {
if (lowercasePreservingWhitespace(String(req.headers.upgrade ?? "")) === "websocket") {
if (lowercasePreservingWhitespace(req.headers.upgrade ?? "") === "websocket") {
return;
}
void (async () => {

View File

@@ -20,7 +20,7 @@ function resolveLocation(location: NormalizedLocation): ResolvedLocation {
const source =
location.source ??
(location.isLive ? "live" : location.name || location.address ? "place" : "pin");
const isLive = Boolean(location.isLive ?? source === "live");
const isLive = location.isLive ?? source === "live";
return { ...location, source, isLive };
}

View File

@@ -188,7 +188,7 @@ export function describeAccountSnapshot<
extra?: Record<string, unknown> | undefined;
}): ChannelAccountSnapshot {
return {
accountId: String(params.account.accountId ?? DEFAULT_ACCOUNT_ID),
accountId: params.account.accountId ?? DEFAULT_ACCOUNT_ID,
name: normalizeOptionalString(params.account.name),
enabled: params.account.enabled !== false,
configured: params.configured,

View File

@@ -438,25 +438,23 @@ export function buildChannelSetupWizardAdapterFromSetupWizard(params: {
credentialValues,
})) ?? currentValue,
);
const rawValue = String(
await prompter.text({
message: textInput.message,
initialValue,
placeholder: textInput.placeholder,
validate: (value) => {
const trimmed = normalizeOptionalString(value) ?? "";
if (!trimmed && textInput.required !== false) {
return "Required";
}
return textInput.validate?.({
value: trimmed,
cfg: next,
accountId,
credentialValues,
});
},
}),
);
const rawValue = await prompter.text({
message: textInput.message,
initialValue,
placeholder: textInput.placeholder,
validate: (value) => {
const trimmed = normalizeOptionalString(value) ?? "";
if (!trimmed && textInput.required !== false) {
return "Required";
}
return textInput.validate?.({
value: trimmed,
cfg: next,
accountId,
credentialValues,
});
},
});
const trimmedValue = rawValue.trim();
if (!trimmedValue && textInput.required === false) {
if (textInput.applyEmptyValue) {

View File

@@ -35,7 +35,7 @@ function findRegisteredChannelPluginEntry(
normalizedKey: string,
): RegisteredChannelPluginEntry | undefined {
return listRegisteredChannelPluginEntries().find((entry) => {
const id = normalizeOptionalLowercaseString(String(entry.plugin.id ?? "")) ?? "";
const id = normalizeOptionalLowercaseString(entry.plugin.id ?? "") ?? "";
if (id && id === normalizedKey) {
return true;
}

View File

@@ -185,9 +185,7 @@ export function printDaemonStatus(status: DaemonStatus, opts: { json: boolean })
if (rpc.url) {
defaultRuntime.error(`${label("RPC target:")} ${rpc.url}`);
}
const lines = String(rpc.error ?? "unknown")
.split(/\r?\n/)
.filter(Boolean);
const lines = (rpc.error ?? "unknown").split(/\r?\n/).filter(Boolean);
for (const line of lines.slice(0, 12)) {
defaultRuntime.error(` ${errorText(line)}`);
}

View File

@@ -20,7 +20,7 @@ function parseManualOAuthInput(
input: string,
expectedState: string,
): { code: string; state: string } {
const trimmed = normalizeOptionalString(String(input ?? "")) ?? "";
const trimmed = normalizeOptionalString(input ?? "") ?? "";
if (!trimmed) {
throw new Error("Missing OAuth redirect URL or authorization code.");
}

View File

@@ -9,7 +9,7 @@ import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
export function resolveGatewayDevMode(argv: string[] = process.argv): boolean {
const entry = argv[1];
const normalizedEntry = entry?.replaceAll("\\", "/");
return Boolean(normalizedEntry?.includes("/src/") && normalizedEntry.endsWith(".ts"));
return normalizedEntry?.includes("/src/") && normalizedEntry.endsWith(".ts");
}
export async function resolveDaemonInstallRuntimeInputs(params: {

View File

@@ -15,7 +15,7 @@ export function pickGatewaySelfPresence(presence: unknown): GatewaySelfPresence
const self =
entries.find((e) => e.mode === "gateway" && e.reason === "self") ??
// Back-compat: older presence payloads only included a `text` line.
entries.find((e) => typeof e.text === "string" && String(e.text).startsWith("Gateway:")) ??
entries.find((e) => typeof e.text === "string" && e.text.startsWith("Gateway:")) ??
null;
if (!self) {
return null;

View File

@@ -43,7 +43,7 @@ export function buildGatewayStatusWarnings(params: {
warnings.push({
code: "ssh_tunnel_failed",
message: params.sshTunnelError
? `SSH tunnel failed: ${String(params.sshTunnelError)}`
? `SSH tunnel failed: ${params.sshTunnelError}`
: "SSH tunnel failed to start; falling back to direct probes.",
});
}

View File

@@ -122,7 +122,7 @@ export async function removeFallbackCommand(
const existing = getFallbacks(cfg, params.key);
const filtered = existing.filter((entry) => {
const resolvedEntry = resolveModelRefFromString({
raw: String(entry ?? ""),
raw: entry ?? "",
defaultProvider: DEFAULT_PROVIDER,
aliasIndex,
});

View File

@@ -2,7 +2,7 @@ import { colorize, isRich as isRichTerminal, theme } from "../../terminal/theme.
export { maskApiKey } from "../../utils/mask-api-key.js";
export const isRich = (opts?: { json?: boolean; plain?: boolean }) =>
Boolean(isRichTerminal() && !opts?.json && !opts?.plain);
isRichTerminal() && !opts?.json && !opts?.plain;
export const pad = (value: string, size: number) => value.padEnd(size);

View File

@@ -130,7 +130,7 @@ export function mapFailoverReasonToProbeStatus(reason?: string | null): AuthProb
function buildCandidateMap(modelCandidates: string[]): Map<string, string[]> {
const map = new Map<string, string[]>();
for (const raw of modelCandidates) {
const parsed = parseModelRef(String(raw ?? ""), DEFAULT_PROVIDER);
const parsed = parseModelRef(raw ?? "", DEFAULT_PROVIDER);
if (!parsed) {
continue;
}

View File

@@ -55,7 +55,7 @@ export function applyNonInteractiveGatewayConfig(params: {
const explicitGatewayToken = normalizeGatewayTokenInput(opts.gatewayToken);
const envGatewayToken = normalizeGatewayTokenInput(process.env.OPENCLAW_GATEWAY_TOKEN);
let gatewayToken = explicitGatewayToken || envGatewayToken || undefined;
const gatewayTokenRefEnv = normalizeOptionalString(String(opts.gatewayTokenRefEnv ?? "")) ?? "";
const gatewayTokenRefEnv = normalizeOptionalString(opts.gatewayTokenRefEnv ?? "") ?? "";
if (authMode === "token") {
if (gatewayTokenRefEnv) {

View File

@@ -209,12 +209,10 @@ export async function setupSkills(
if (!wantsKey) {
continue;
}
const apiKey = String(
await prompter.text({
message: `Enter ${skill.primaryEnv}`,
validate: (value) => (value?.trim() ? undefined : "Required"),
}),
);
const apiKey = await prompter.text({
message: `Enter ${skill.primaryEnv}`,
validate: (value) => (value?.trim() ? undefined : "Required"),
});
next = upsertSkillEntry(next, skill.skillKey, { apiKey: normalizeSecretInput(apiKey) });
}

View File

@@ -110,7 +110,7 @@ export async function sessionsCommand(
let activeMinutes: number | undefined;
if (opts.active !== undefined) {
const parsed = Number.parseInt(String(opts.active), 10);
const parsed = Number.parseInt(opts.active, 10);
if (Number.isNaN(parsed) || parsed <= 0) {
runtime.error("--active must be a positive integer (minutes)");
runtime.exit(1);

View File

@@ -84,7 +84,7 @@ export async function buildStatusAllReportLines(params: {
warn,
muted,
accentDim: theme.accentDim,
formatIssueMessage: (message) => String(message).slice(0, 90),
formatIssueMessage: (message) => message.slice(0, 90),
}),
...buildStatusChannelDetailsSections({
details: params.channels.details,

View File

@@ -66,7 +66,7 @@ export function buildStatusPluginCompatibilityValue(params: {
return params.ok("none");
}
const pluginCount = new Set(
params.notices.map((notice) => String(notice.pluginId ?? notice.plugin ?? "")),
params.notices.map((notice) => notice.pluginId ?? notice.plugin ?? ""),
).size;
return params.warn(
`${params.notices.length} notice${params.notices.length === 1 ? "" : "s"} · ${pluginCount} plugin${pluginCount === 1 ? "" : "s"}`,

View File

@@ -36,7 +36,7 @@ export function validateScheduleTimestamp(
if (atMs === null || !Number.isFinite(atMs)) {
return {
ok: false,
message: `Invalid schedule.at: expected ISO-8601 timestamp (got ${String(schedule.at)})`,
message: `Invalid schedule.at: expected ISO-8601 timestamp (got ${schedule.at})`,
};
}

View File

@@ -146,7 +146,7 @@ async function runAuthProfileHealth(ctx: DoctorHealthFlowContext): Promise<void>
await noteAuthProfileHealth({
cfg: ctx.cfg,
prompter: ctx.prompter,
allowKeychainPrompt: ctx.options.nonInteractive !== true && Boolean(process.stdin.isTTY),
allowKeychainPrompt: ctx.options.nonInteractive !== true && process.stdin.isTTY,
});
noteLegacyCodexProviderOverride(ctx.cfg);
ctx.gatewayDetails = buildGatewayConnectionDetails({ config: ctx.cfg });

View File

@@ -426,7 +426,7 @@ export const agentHandlers: GatewayRequestHandlers = {
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid agent params: unknown channel: ${String(normalized)}`,
`invalid agent params: unknown channel: ${normalized}`,
),
);
return;

View File

@@ -55,7 +55,7 @@ export async function logoutChannelAccount(params: {
if (!result) {
throw new Error(`Channel ${params.channelId} does not support logout`);
}
const cleared = Boolean(result.cleared);
const cleared = result.cleared;
const loggedOut = typeof result.loggedOut === "boolean" ? result.loggedOut : cleared;
if (loggedOut) {
params.context.markChannelLoggedOut(params.channelId, true, resolvedAccountId);

View File

@@ -634,7 +634,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const p = params;
const keysRaw = Array.isArray(p.keys) ? p.keys : [];
const keys = keysRaw
.map((key) => normalizeOptionalString(String(key ?? "")))
.map((key) => normalizeOptionalString(key ?? ""))
.filter((key): key is string => Boolean(key))
.slice(0, 64);
const limit =

View File

@@ -55,7 +55,7 @@ function collectSkillBins(entries: SkillEntry[]): string[] {
for (const spec of install) {
const specBins = spec?.bins ?? [];
for (const bin of specBins) {
const trimmed = normalizeOptionalString(String(bin)) ?? "";
const trimmed = normalizeOptionalString(bin) ?? "";
if (trimmed) {
bins.add(trimmed);
}

View File

@@ -75,7 +75,7 @@ export const wizardHandlers: GatewayRequestHandlers = {
return;
}
try {
await session.answer(String(answer.stepId ?? ""), answer.value);
await session.answer(answer.stepId ?? "", answer.value);
} catch (err) {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, formatForLog(err)));
return;

View File

@@ -271,10 +271,8 @@ export function attachGatewayWsConnectionHandler(params: AttachGatewayWsConnecti
});
const isNoisySwiftPmHelperClose = (userAgent: string | undefined, remote: string | undefined) =>
Boolean(
normalizeLowercaseStringOrEmpty(userAgent).includes("swiftpm-testing-helper") &&
isLoopbackAddress(remote),
);
normalizeLowercaseStringOrEmpty(userAgent).includes("swiftpm-testing-helper") &&
isLoopbackAddress(remote);
socket.once("close", (code, reason) => {
const durationMs = Date.now() - openedAt;

View File

@@ -590,7 +590,7 @@ export async function discoverGatewayBeacons(
const domainsRaw = Array.isArray(opts.domains) ? opts.domains : [];
const defaultDomains = ["local.", ...(wideAreaDomain ? [wideAreaDomain] : [])];
const domains = (domainsRaw.length > 0 ? domainsRaw : defaultDomains)
.map((d) => String(d).trim())
.map((d) => d.trim())
.filter(Boolean)
.map((d) => (d.endsWith(".") ? d : `${d}.`));

View File

@@ -68,6 +68,7 @@ type ConsoleLogFn = (...args: unknown[]) => void;
const WATCHDOG_INTERVAL_MS = 5_000;
const REPAIR_DEBOUNCE_MS = 30_000;
const STUCK_ANNOUNCING_MS = 8_000;
const BONJOUR_ANNOUNCED_STATE = "announced" as BonjourServiceState;
const CIAO_SELF_PROBE_RETRY_FRAGMENT =
"failed probing with reason: Error: Can't probe for a service which is announced already.";
@@ -95,7 +96,7 @@ function serviceSummary(label: string, svc: BonjourService): string {
}
function isAnnouncedState(state: BonjourServiceState | "unknown") {
return String(state) === "announced";
return state === BONJOUR_ANNOUNCED_STATE;
}
function handleCiaoUnhandledRejection(reason: unknown): boolean {

View File

@@ -35,7 +35,7 @@ const parseHostHeader = (value: HostSource): ParsedHostHeader => {
return { host: "" };
}
try {
const parsed = new URL(`http://${String(value).trim()}`);
const parsed = new URL(`http://${value.trim()}`);
const portRaw = parsed.port.trim();
const port = portRaw ? Number.parseInt(portRaw, 10) : undefined;
return {

View File

@@ -706,7 +706,7 @@ async function sendApnsRequest(params: {
});
req.on("response", (headers) => {
const statusHeader = headers[":status"];
statusCode = typeof statusHeader === "number" ? statusHeader : Number(statusHeader ?? 0);
statusCode = statusHeader ?? 0;
const idHeader = headers["apns-id"];
if (typeof idHeader === "string" && idHeader.trim().length > 0) {
apnsId = idHeader.trim();

View File

@@ -179,7 +179,7 @@ function mergeStringList(...values: Array<string[] | undefined>): string[] | und
continue;
}
for (const item of list) {
const trimmed = normalizeOptionalString(String(item)) ?? "";
const trimmed = normalizeOptionalString(item) ?? "";
if (trimmed) {
out.add(trimmed);
}

View File

@@ -92,7 +92,7 @@ function getColorForConsole(): ChalkInstance {
if (process.env.NO_COLOR && !hasForceColor) {
return new Chalk({ level: 0 });
}
const hasTty = Boolean(process.stdout.isTTY || process.stderr.isTTY);
const hasTty = process.stdout.isTTY || process.stderr.isTTY;
return hasTty || isRichConsoleEnv() ? new Chalk({ level: 1 }) : new Chalk({ level: 0 });
}

View File

@@ -43,7 +43,7 @@ export async function sendTranscriptEcho(params: {
if (!isDeliverableMessageChannel(normalizedChannel)) {
if (shouldLogVerbose()) {
logVerbose(
`media: echo-transcript skipped (channel "${String(normalizedChannel)}" is not deliverable)`,
`media: echo-transcript skipped (channel "${normalizedChannel}" is not deliverable)`,
);
}
return;

View File

@@ -421,7 +421,7 @@ export async function handleInvoke(
client: GatewayClient,
skillBins: SkillBinsProvider,
) {
const command = String(frame.command ?? "");
const command = frame.command ?? "";
if (command === "system.execApprovals.get") {
try {
ensureExecApprovals();

View File

@@ -238,7 +238,7 @@ export async function resolveWebhookTargetWithAuthOrReject<T>(params: {
ambiguousMessage?: string;
}): Promise<T | null> {
const match = await resolveSingleWebhookTargetAsync(params.targets, async (target) =>
Boolean(await params.isMatch(target)),
params.isMatch(target),
);
return resolveWebhookTargetMatchOrReject(params, match);
}

View File

@@ -341,8 +341,9 @@ function loadApprovalsFromDisk(): PluginBindingApprovalsFile {
return {
version: 1,
approvals: parsed.approvals
.filter((entry): entry is PluginBindingApprovalEntry =>
Boolean(entry && typeof entry === "object"),
.filter(
(entry): entry is PluginBindingApprovalEntry =>
entry !== null && typeof entry === "object",
)
.map((entry) => ({
pluginRoot: typeof entry.pluginRoot === "string" ? entry.pluginRoot : "",

View File

@@ -219,9 +219,7 @@ export async function promptAndConfigureOpenAICompatibleSelfHostedProvider(
validate: (value) => (value?.trim() ? undefined : "Required"),
});
const baseUrl = String(baseUrlRaw ?? "")
.trim()
.replace(/\/+$/, "");
const baseUrl = (baseUrlRaw ?? "").trim().replace(/\/+$/, "");
const apiKey = normalizeStringifiedOptionalString(apiKeyRaw) ?? "";
const modelId = normalizeStringifiedOptionalString(modelIdRaw) ?? "";
const credential: AuthProfileCredential = {

View File

@@ -99,7 +99,7 @@ export function* iterateAuthProfileCredentials(
if (!isRecord(value) || !isNonEmptyString(value.provider)) {
continue;
}
const provider = String(value.provider);
const provider = value.provider;
if (value.type === "api_key" || value.type === "token") {
yield toSecretCredentialVisit({
kind: value.type,

View File

@@ -90,7 +90,7 @@ export function resolveValidatedPlanTarget(candidate: {
}
const segments =
Array.isArray(candidate.pathSegments) && candidate.pathSegments.length > 0
? candidate.pathSegments.map((segment) => String(segment).trim()).filter(Boolean)
? candidate.pathSegments.map((segment) => segment.trim()).filter(Boolean)
: parseDotPath(path);
if (segments.length === 0 || hasForbiddenPathSegment(segments) || path !== toDotPath(segments)) {
return null;

View File

@@ -338,7 +338,7 @@ export async function collectChannelSecurityFindings(params: {
account,
});
for (const message of warnings ?? []) {
const trimmed = String(message).trim();
const trimmed = message.trim();
if (!trimmed) {
continue;
}

View File

@@ -133,9 +133,7 @@ export function createLocalShellRunner(deps: LocalShellDeps) {
deps.chatLog.addSystem(`[local] ${line}`);
}
}
deps.chatLog.addSystem(
`[local] exit ${code ?? "?"}${signal ? ` (signal ${String(signal)})` : ""}`,
);
deps.chatLog.addSystem(`[local] exit ${code ?? "?"}${signal ? ` (signal ${signal})` : ""}`);
deps.tui.requestRender();
resolve();
});