refactor(plugins): consolidate record guards (#99361)

This commit is contained in:
Dallin Romney
2026-07-02 22:12:53 -07:00
committed by GitHub
parent 0e68c50139
commit de34dfdbe8
22 changed files with 23 additions and 90 deletions

View File

@@ -1,3 +1,4 @@
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
/**
* Config parsing for Codex Supervisor endpoints and safety gates.
*/
@@ -61,10 +62,6 @@ function normalizeEndpointId(value: string, index: number): string {
return `endpoint-${index + 1}`;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function parseEndpointRecord(value: unknown, index: number): CodexSupervisorEndpoint | undefined {
if (!isRecord(value)) {
return undefined;

View File

@@ -7,6 +7,7 @@ import { randomUUID } from "node:crypto";
import * as net from "node:net";
import * as os from "node:os";
import * as path from "node:path";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import WebSocket from "ws";
import type { CodexJsonRpcConnection, CodexSupervisorEndpoint } from "./types.js";
@@ -16,10 +17,6 @@ type PendingRequest = {
timeout: NodeJS.Timeout;
};
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function formatJsonRpcError(message: Record<string, unknown>): Error {
const error = isRecord(message.error) ? message.error : {};
const detail =

View File

@@ -2,6 +2,7 @@
* Codex app-server supervisor that lists sessions, reads transcripts, and
* starts/steers/interrupts turns across configured endpoints.
*/
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { connectCodexAppServerEndpoint } from "./json-rpc-client.js";
import type {
CodexJsonRpcConnection,
@@ -19,10 +20,6 @@ type EndpointConnector = (endpoint: CodexSupervisorEndpoint) => Promise<CodexJso
const ALL_CODEX_THREAD_SOURCE_KINDS = ["cli", "vscode", "exec", "appServer", "unknown"];
const DEFAULT_MAX_STORED_SESSIONS = 200;
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function asRecordArray(value: unknown): Record<string, unknown>[] {
if (!Array.isArray(value)) {
return [];

View File

@@ -2,6 +2,7 @@
* Runtime validators for Codex app-server protocol payloads, including schema
* normalization for generated JSON Schema before TypeBox compilation.
*/
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
import dynamicToolCallParamsSchema from "./protocol-generated/json/DynamicToolCallParams.json" with { type: "json" };
import errorNotificationSchema from "./protocol-generated/json/v2/ErrorNotification.json" with { type: "json" };
@@ -40,10 +41,6 @@ function compileCodexSchema<T>(schema: unknown): CodexValidator<T> {
};
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value && typeof value === "object" && !Array.isArray(value));
}
const schemaMapKeywords = new Set([
"$defs",
"definitions",

View File

@@ -1,11 +1,8 @@
// Copilot plugin entrypoint registers its OpenClaw integration.
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { createCopilotAgentHarness, type CopilotSessionBinding } from "./harness.js";
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function readPoolOptions(pluginConfig: unknown): { idleTtlMs: number } | undefined {
if (!isRecord(pluginConfig)) {
return undefined;

View File

@@ -30,6 +30,7 @@ import {
} from "@opentelemetry/semantic-conventions/incubating";
import { waitForDiagnosticEventsDrained } from "openclaw/plugin-sdk/diagnostic-runtime";
import { registerUnhandledRejectionHandler } from "openclaw/plugin-sdk/runtime-env";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import type {
DiagnosticEventMetadata,
DiagnosticEventPayload,
@@ -807,10 +808,6 @@ function describeJsonValue(value: unknown): string {
return typeof value;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function textPart(content: string): Record<string, unknown> {
return { type: "text", content };
}

View File

@@ -15,6 +15,7 @@ import {
updateSessionStore,
} from "openclaw/plugin-sdk/session-store-runtime";
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
const FEISHU_STATE_DIR = "feishu";
const BACKUP_PREFIX = "feishu-state-repair";
@@ -84,10 +85,6 @@ function timestampForPath(now = new Date()): string {
return now.toISOString().replaceAll(":", "-");
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value && typeof value === "object" && !Array.isArray(value));
}
function toFeishuSessionEntry(value: unknown): FeishuSessionEntry {
if (!isRecord(value)) {
return {};

View File

@@ -2,6 +2,7 @@ import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import type { CliBackendPreparedExecution } from "openclaw/plugin-sdk/cli-backend";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
import {
GOOGLE_GEMINI_CLI_PROVIDER_ID,
@@ -187,10 +188,6 @@ function resolveGeminiCliProfileHome(ctx: GeminiCliAuthHomeContext): {
return { home, geminiDir: path.join(home, ".gemini") };
}
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
function readGeminiAuthProfileCredential(
credential: unknown,
): GeminiAuthProfileCredential | undefined {

View File

@@ -4,15 +4,12 @@ import type {
ChannelDoctorLegacyConfigRule,
} from "openclaw/plugin-sdk/channel-contract";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
// Disabled `channels.imessage.catchup` blocks are retired. Enabled blocks stay
// as a compatibility contract: older configs that opted into replay still get
// downtime recovery, while new/default installs use the always-on recovery
// cursor plus stale-backlog fence.
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isEnabledCatchup(value: unknown): boolean {
return isRecord(value) && value.enabled === true;
}

View File

@@ -5,6 +5,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/plugin-entry";
import type { PluginDoctorStateMigration } from "openclaw/plugin-sdk/runtime-doctor";
import { resolveMemoryWikiConfig, type MemoryWikiPluginConfig } from "./src/config.js";
export { legacyConfigRules, normalizeCompatibilityConfig } from "./src/config-compat.js";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
countMemoryWikiImportRunStateRows,
createMemoryWikiImportRunStateStore,
@@ -24,10 +25,6 @@ import {
writeMemoryWikiSourceSyncState,
} from "./src/source-sync-state.js";
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value && typeof value === "object" && !Array.isArray(value));
}
function resolveHomeDir(env: NodeJS.ProcessEnv): string | undefined {
return env.HOME?.trim() || env.USERPROFILE?.trim() || undefined;
}

View File

@@ -5,6 +5,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import type { PluginDoctorStateMigration } from "openclaw/plugin-sdk/runtime-doctor";
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { normalizeStoredConversationId } from "./src/conversation-store-helpers.js";
import {
buildMSTeamsConversationStateKey,
@@ -156,10 +157,6 @@ async function readLegacyJsonFile<T>(
}
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function isStringArray(value: unknown): value is string[] {
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
}

View File

@@ -13,6 +13,7 @@ import {
type LookupFn,
ssrfPolicyFromHttpBaseUrlAllowedHostname,
} from "openclaw/plugin-sdk/ssrf-runtime";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import manifest from "./openclaw.plugin.json" with { type: "json" };
export const NVIDIA_DEFAULT_MODEL_ID = "nvidia/nemotron-3-ultra-550b-a55b";
@@ -165,10 +166,6 @@ function applyNvidiaModelDefaults(models: ModelDefinitionConfig[]): ModelDefinit
);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function parseNvidiaFeaturedModel(row: unknown): ModelDefinitionConfig | null {
if (!row || typeof row !== "object") {
return null;

View File

@@ -9,6 +9,7 @@ import {
} from "openclaw/plugin-sdk/provider-auth";
import { generateOAuthState } from "openclaw/plugin-sdk/provider-auth-runtime";
import { readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { applyOpenrouterConfig, OPENROUTER_DEFAULT_MODEL_REF } from "./onboard.js";
const PROVIDER_ID = "openrouter";
@@ -44,10 +45,6 @@ type OpenRouterOAuthLoginOptions = {
waitForCallback?: typeof waitForOpenRouterOAuthCallback;
};
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
function readString(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
}

View File

@@ -6,6 +6,7 @@ import {
readResponseTextLimited,
} from "openclaw/plugin-sdk/provider-http";
import { withTrustedWebSearchEndpoint } from "openclaw/plugin-sdk/provider-web-search";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
// Free hosted Search MCP. This keyless transport is used only after the user
// explicitly selects the `parallel-free` web_search provider. Docs:
@@ -37,10 +38,6 @@ export type ParallelMcpSearchResponse = {
usage?: unknown;
};
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function mcpHeaders(params: {
sessionId?: string;
protocolVersion?: string;

View File

@@ -4,6 +4,7 @@ import { basename, isAbsolute, resolve } from "node:path";
import JSON5 from "json5";
import type { HealthFinding } from "openclaw/plugin-sdk/health";
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
isPolicyValueAtLeastAsStrict,
policyContainerShapeFindings,
@@ -624,7 +625,3 @@ function ocPathSegment(value: string): string {
}
return JSON.stringify(value);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}

View File

@@ -2,6 +2,7 @@
import fs from "node:fs/promises";
import path from "node:path";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
formatGatewayLogSentinelSummary,
type GatewayLogSentinelFinding,
@@ -140,10 +141,6 @@ const QA_CONFIDENCE_SELF_TEST_CANARY_IDS = [
"jsonl-replay-ordering-drift",
] as const;
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function readString(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
}
@@ -389,8 +386,7 @@ function evaluateQaSuiteSummary(payload: unknown): QaConfidenceLaneEvaluation {
const failedCount = readCount(counts?.failed);
const explicitSkippedCount = readCount(counts?.skipped);
if (totalCount !== undefined) {
const providedCountSum =
(passedCount ?? 0) + (failedCount ?? 0) + (explicitSkippedCount ?? 0);
const providedCountSum = (passedCount ?? 0) + (failedCount ?? 0) + (explicitSkippedCount ?? 0);
if (totalCount < providedCountSum) {
return {
passed: false,

View File

@@ -1,6 +1,7 @@
// Qa Lab plugin module implements jsonl replay behavior.
import fs from "node:fs/promises";
import path from "node:path";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
runRuntimeParityScenario,
type RuntimeId,
@@ -51,10 +52,6 @@ export type JsonlReplayMarkdownReport = {
transcripts: JsonlReplayResult["transcripts"];
};
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function readString(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
}

View File

@@ -1,6 +1,7 @@
// Qa Lab plugin module implements auth store behavior.
import fs from "node:fs/promises";
import path from "node:path";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
type QaAuthProfileCredential =
| {
@@ -172,7 +173,3 @@ function isQaLegacyOAuthRef(value: unknown): value is QaLegacyOAuthRef {
/^[a-f0-9]{32}$/.test(value.id)
);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value && typeof value === "object" && !Array.isArray(value));
}

View File

@@ -5,6 +5,7 @@ import path from "node:path";
import { setTimeout as sleep } from "node:timers/promises";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
appendQaChildOutput,
appendQaChildOutputTail,
@@ -51,10 +52,6 @@ const MANAGED_DREAMING_CRON_MARKER = "[managed-by=memory-core.short-term-promoti
const MANAGED_DREAMING_CRON_NAME = "Memory Dreaming Promotion";
const MANAGED_DREAMING_PROMPT = "__openclaw_memory_core_short_term_promotion_dream__";
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function stripAnsiCodes(text: string) {
return text.replace(ANSI_ESCAPE_PATTERN, "");
}

View File

@@ -2,6 +2,7 @@
import type { Chat, Message, MessageOrigin, User } from "grammy/types";
import type { NormalizedLocation } from "openclaw/plugin-sdk/channel-inbound";
import {
isRecord,
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -104,10 +105,6 @@ function hasTelegramRichMessage(value: unknown): boolean {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function compactRichText(value: string): string {
return value
.split("\n")

View File

@@ -5,6 +5,7 @@ import type {
AgentToolResultMiddlewareEvent,
OpenClawAgentToolResult,
} from "openclaw/plugin-sdk/agent-harness";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { createTokenjuiceOpenClawEmbeddedExtension } from "./runtime-api.js";
type TokenjuiceToolResultHandler = (
@@ -18,10 +19,6 @@ type TokenjuiceToolResultHandler = (
ctx: { cwd: string },
) => Promise<Partial<OpenClawAgentToolResult> | void> | Partial<OpenClawAgentToolResult> | void;
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function readCwd(event: AgentToolResultMiddlewareEvent): string {
if (event.cwd?.trim()) {
return event.cwd;

View File

@@ -3,6 +3,7 @@ import type { Command } from "commander";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { resolveWorkboardCardByIdOrPrefix } from "./card-lookup.js";
import type { WorkboardDispatchResult, WorkboardStore } from "./store.js";
import type { WorkboardCard } from "./types.js";
@@ -27,10 +28,6 @@ function writeLine(value: string): void {
process.stdout.write(`${value}\n`);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value && typeof value === "object" && !Array.isArray(value));
}
function splitLabels(value: string | undefined): string[] | undefined {
return value
?.split(",")