mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor: remove residual normalization adapters (#122771)
This commit is contained in:
committed by
GitHub
parent
8bbc0a9bc7
commit
9da43d67e1
@@ -1,3 +1,4 @@
|
||||
import { normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type {
|
||||
CodexAppServerApprovalPolicySource,
|
||||
CodexAppServerCommandSource,
|
||||
@@ -53,7 +54,6 @@ import {
|
||||
normalizeCodexServiceTier,
|
||||
normalizeHeaders,
|
||||
normalizePositiveNumber,
|
||||
normalizeStringList,
|
||||
readBooleanEnv,
|
||||
readNonEmptyString,
|
||||
readNumberEnv,
|
||||
@@ -120,7 +120,7 @@ export function resolveCodexAppServerRuntimeOptions(
|
||||
}
|
||||
const args = resolveArgs(config.args, env.OPENCLAW_CODEX_APP_SERVER_ARGS);
|
||||
const headers = normalizeHeaders(config.headers);
|
||||
const clearEnv = normalizeStringList(config.clearEnv);
|
||||
const clearEnv = normalizeTrimmedStringList(config.clearEnv);
|
||||
const authToken = normalizeCodexAppServerSecretInput({
|
||||
value: config.authToken,
|
||||
path: "plugins.entries.codex.config.appServer.authToken",
|
||||
|
||||
@@ -4,7 +4,6 @@ import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-i
|
||||
import {
|
||||
asOptionalRecord as readRecord,
|
||||
normalizeOptionalString as readNonEmptyString,
|
||||
normalizeTrimmedStringList,
|
||||
parseBooleanValue,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { OpenClawExecAsk, OpenClawExecSecurity } from "./config-contracts.js";
|
||||
@@ -69,10 +68,6 @@ export function normalizeCodexAppServerSecretInput(params: {
|
||||
return normalizeResolvedSecretInputString(params);
|
||||
}
|
||||
|
||||
export function normalizeStringList(value: unknown): string[] {
|
||||
return normalizeTrimmedStringList(value);
|
||||
}
|
||||
|
||||
export function readBooleanEnv(value: string | undefined): boolean | undefined {
|
||||
return parseBooleanValue(value);
|
||||
}
|
||||
|
||||
@@ -10,11 +10,7 @@ import {
|
||||
normalizeOptionalTrimmedStringList,
|
||||
normalizeTrimmedStringList,
|
||||
} from "@openclaw/normalization-core/string-normalization";
|
||||
import {
|
||||
buildModelCatalogMergeKey,
|
||||
buildModelCatalogRef,
|
||||
normalizeModelCatalogProviderId,
|
||||
} from "./model-catalog-refs.js";
|
||||
import { buildModelCatalogMergeKey, buildModelCatalogRef } from "./model-catalog-refs.js";
|
||||
import {
|
||||
MODEL_CATALOG_APIS,
|
||||
MODEL_CATALOG_THINKING_LEVELS,
|
||||
@@ -39,6 +35,7 @@ import {
|
||||
type ModelCatalogVercelGatewayRouting,
|
||||
type NormalizedModelCatalogRow,
|
||||
} from "./model-catalog-types.js";
|
||||
import { normalizeProviderId } from "./provider-id.js";
|
||||
|
||||
// Normalizes raw provider model catalogs into stable rows for lookup and merging.
|
||||
|
||||
@@ -83,7 +80,7 @@ function normalizeSafeRecordKey(value: unknown): string {
|
||||
function normalizeOwnedProviderSet(providers: ReadonlySet<string>): ReadonlySet<string> {
|
||||
const normalized = new Set<string>();
|
||||
for (const provider of providers) {
|
||||
const providerId = normalizeModelCatalogProviderId(provider);
|
||||
const providerId = normalizeProviderId(provider);
|
||||
if (providerId) {
|
||||
normalized.add(providerId);
|
||||
}
|
||||
@@ -552,7 +549,7 @@ function normalizeModelCatalogProviders(
|
||||
}
|
||||
const providers: Record<string, ModelCatalogProvider> = {};
|
||||
for (const [rawProviderId, rawProvider] of Object.entries(value)) {
|
||||
const providerId = normalizeModelCatalogProviderId(rawProviderId);
|
||||
const providerId = normalizeProviderId(rawProviderId);
|
||||
if (!providerId || !ownedProviders.has(providerId)) {
|
||||
continue;
|
||||
}
|
||||
@@ -573,13 +570,11 @@ function normalizeModelCatalogAliases(
|
||||
}
|
||||
const aliases: Record<string, ModelCatalogAlias> = {};
|
||||
for (const [rawAlias, rawTarget] of Object.entries(value)) {
|
||||
const alias = normalizeModelCatalogProviderId(rawAlias);
|
||||
const alias = normalizeProviderId(rawAlias);
|
||||
if (!alias || !isRecord(rawTarget)) {
|
||||
continue;
|
||||
}
|
||||
const provider = normalizeModelCatalogProviderId(
|
||||
normalizeOptionalString(rawTarget.provider) ?? "",
|
||||
);
|
||||
const provider = normalizeProviderId(normalizeOptionalString(rawTarget.provider) ?? "");
|
||||
if (!provider || !ownedProviders.has(provider)) {
|
||||
continue;
|
||||
}
|
||||
@@ -603,7 +598,7 @@ function normalizeModelCatalogSuppressions(value: unknown): ModelCatalogSuppress
|
||||
if (!isRecord(entry)) {
|
||||
continue;
|
||||
}
|
||||
const provider = normalizeModelCatalogProviderId(normalizeOptionalString(entry.provider) ?? "");
|
||||
const provider = normalizeProviderId(normalizeOptionalString(entry.provider) ?? "");
|
||||
const model = normalizeOptionalString(entry.model) ?? "";
|
||||
if (!provider || !model) {
|
||||
continue;
|
||||
@@ -642,7 +637,7 @@ function normalizeModelCatalogDiscovery(
|
||||
}
|
||||
const discovery: Record<string, ModelCatalogDiscovery> = {};
|
||||
for (const [rawProviderId, rawMode] of Object.entries(value)) {
|
||||
const providerId = normalizeModelCatalogProviderId(rawProviderId);
|
||||
const providerId = normalizeProviderId(rawProviderId);
|
||||
const mode = normalizeOptionalString(rawMode) ?? "";
|
||||
if (providerId && ownedProviders.has(providerId) && MODEL_CATALOG_DISCOVERY_MODES.has(mode)) {
|
||||
discovery[providerId] = mode as ModelCatalogDiscovery;
|
||||
@@ -681,7 +676,7 @@ export function normalizeModelCatalogProviderRows(params: {
|
||||
providerCatalog: ModelCatalogProvider;
|
||||
source: ModelCatalogSource;
|
||||
}): NormalizedModelCatalogRow[] {
|
||||
const provider = normalizeModelCatalogProviderId(params.provider);
|
||||
const provider = normalizeProviderId(params.provider);
|
||||
if (!provider || !Array.isArray(params.providerCatalog.models)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Model Catalog Core module implements model catalog refs behavior.
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
import { normalizeProviderId } from "./provider-id.js";
|
||||
|
||||
export { normalizeProviderId as normalizeModelCatalogProviderId } from "./provider-id.js";
|
||||
|
||||
// Stable model catalog ref and merge-key builders.
|
||||
|
||||
@@ -43,14 +46,9 @@ export function isCloudModelRef(modelRef: string | undefined): boolean {
|
||||
return source?.source === "cloud" && parseModelSourceSuffix(source.base) === undefined;
|
||||
}
|
||||
|
||||
/** Normalize provider ids for catalog refs. */
|
||||
export function normalizeModelCatalogProviderId(provider: string): string {
|
||||
return normalizeLowercaseStringOrEmpty(provider);
|
||||
}
|
||||
|
||||
/** Build a provider/model catalog reference. */
|
||||
export function buildModelCatalogRef(provider: string, modelId: string): string {
|
||||
return `${normalizeModelCatalogProviderId(provider)}/${modelId}`;
|
||||
return `${normalizeProviderId(provider)}/${modelId}`;
|
||||
}
|
||||
|
||||
/** Parse a strict provider/model reference without normalizing either segment. */
|
||||
@@ -72,12 +70,12 @@ export function parseModelCatalogRef(value: string): ModelCatalogRef | null {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
provider: normalizeModelCatalogProviderId(parsed.provider),
|
||||
provider: normalizeProviderId(parsed.provider),
|
||||
modelId: parsed.model,
|
||||
};
|
||||
}
|
||||
|
||||
/** Build a case-insensitive merge key for provider/model rows. */
|
||||
export function buildModelCatalogMergeKey(provider: string, modelId: string): string {
|
||||
return `${normalizeModelCatalogProviderId(provider)}::${normalizeLowercaseStringOrEmpty(modelId)}`;
|
||||
return `${normalizeProviderId(provider)}::${normalizeLowercaseStringOrEmpty(modelId)}`;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
filterStringEntries,
|
||||
normalizeAtHashSlug,
|
||||
normalizeCsvOrLooseStringList,
|
||||
normalizeHyphenSlug,
|
||||
normalizeOptionalTrimmedStringList,
|
||||
normalizeSortedUniqueStringEntries,
|
||||
@@ -82,6 +83,15 @@ describe("normalization-core/string-normalization", () => {
|
||||
expect(normalizeOptionalTrimmedStringList(["", 42])).toBeUndefined();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ value: " first, second, , first ", expected: ["first", "second", "first"] },
|
||||
{ value: [" first ", 42, "", " ", 7], expected: ["first", "42", "7"] },
|
||||
{ value: null, expected: [] },
|
||||
{ value: { value: "first" }, expected: [] },
|
||||
])("normalizes CSV or loose string-list input", ({ value, expected }) => {
|
||||
expect(normalizeCsvOrLooseStringList(value)).toEqual(expected);
|
||||
});
|
||||
|
||||
it("normalizes sorted unique trimmed string lists", () => {
|
||||
expect(normalizeSortedUniqueTrimmedStringList([" b ", "a", "b", "", "a"])).toEqual(["a", "b"]);
|
||||
expect(normalizeSortedUniqueTrimmedStringList(["z", 1, " a "] as unknown[])).toEqual([
|
||||
|
||||
@@ -99,10 +99,6 @@ function isBareSentDeliveryStatus(value: unknown): boolean {
|
||||
return normalizeStatus(value) === SENT_DELIVERY_STATUS;
|
||||
}
|
||||
|
||||
function parseJsonRecord(value: string): Record<string, unknown> | undefined {
|
||||
return safeParseJsonRecord(value);
|
||||
}
|
||||
|
||||
function recordHasDeliveredMessageId(record: Record<string, unknown>): boolean {
|
||||
const hasDeliveredId = (value: unknown) => {
|
||||
const normalized = normalizeStatus(value);
|
||||
@@ -151,7 +147,7 @@ function deliveryEnvelopeHasCreatedConversationId(value: unknown, depth = 0): bo
|
||||
}
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeHasCreatedConversationId(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -183,7 +179,7 @@ function deliveryEnvelopeIndicatesOk(value: unknown, depth = 0): boolean {
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesOk(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -218,7 +214,7 @@ function deliveryEnvelopeIndicatesNonDelivery(value: unknown, depth = 0): boolea
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesNonDelivery(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -263,7 +259,7 @@ function deliveryEnvelopeIndicatesNoOp(value: unknown, depth = 0): boolean {
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesNoOp(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -314,7 +310,7 @@ function deliveryEnvelopeIndicatesSuccessfulBroadcast(value: unknown, depth = 0)
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesSuccessfulBroadcast(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -348,7 +344,7 @@ function deliveryEnvelopeIndicatesDryRun(value: unknown, depth = 0): boolean {
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesDryRun(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -363,7 +359,7 @@ function deliveryEnvelopeIndicatesDryRun(value: unknown, depth = 0): boolean {
|
||||
if (item && typeof item === "object" && !Array.isArray(item)) {
|
||||
const text = (item as Record<string, unknown>).text;
|
||||
if (typeof text === "string") {
|
||||
const parsed = parseJsonRecord(text);
|
||||
const parsed = safeParseJsonRecord(text);
|
||||
if (parsed && deliveryEnvelopeIndicatesDryRun(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
@@ -403,7 +399,7 @@ function deliveryEnvelopeIndicatesDelivered(
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesDelivered(parsed, depth + 1, requireReceipt)) {
|
||||
return true;
|
||||
}
|
||||
@@ -421,7 +417,7 @@ function deliveryEnvelopeIndicatesDelivered(
|
||||
if (item && typeof item === "object" && !Array.isArray(item)) {
|
||||
const text = (item as Record<string, unknown>).text;
|
||||
if (typeof text === "string") {
|
||||
const parsed = parseJsonRecord(text);
|
||||
const parsed = safeParseJsonRecord(text);
|
||||
if (parsed && deliveryEnvelopeIndicatesDelivered(parsed, depth + 1, requireReceipt)) {
|
||||
return true;
|
||||
}
|
||||
@@ -455,7 +451,7 @@ function deliveryEnvelopeIndicatesSessionsSendAccepted(value: unknown, depth = 0
|
||||
return true;
|
||||
}
|
||||
if (typeof record.text === "string") {
|
||||
const parsed = parseJsonRecord(record.text);
|
||||
const parsed = safeParseJsonRecord(record.text);
|
||||
if (parsed && deliveryEnvelopeIndicatesSessionsSendAccepted(parsed, depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import {
|
||||
clampTimerTimeoutMs,
|
||||
MAX_TIMER_TIMEOUT_MS,
|
||||
resolveOptionalIntegerOption,
|
||||
} from "@openclaw/normalization-core/number-coercion";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
|
||||
@@ -14,11 +15,8 @@ export const DEFAULT_AGENT_TIMEOUT_MS = DEFAULT_AGENT_TIMEOUT_SECONDS * 1000;
|
||||
const NO_TIMEOUT_MS = MAX_TIMER_TIMEOUT_MS;
|
||||
const NO_TIMEOUT_SECONDS = Math.floor(NO_TIMEOUT_MS / 1000);
|
||||
|
||||
const normalizeNumber = (value: unknown): number | undefined =>
|
||||
typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : undefined;
|
||||
|
||||
function resolveAgentTimeoutSeconds(cfg?: OpenClawConfig): number {
|
||||
const raw = normalizeNumber(cfg?.agents?.defaults?.timeoutSeconds);
|
||||
const raw = resolveOptionalIntegerOption(cfg?.agents?.defaults?.timeoutSeconds);
|
||||
// Config 0 uses the same unlimited-run sentinel as per-run overrides. The
|
||||
// LLM idle watchdog still enforces liveness under that sentinel.
|
||||
if (raw === 0) {
|
||||
@@ -34,10 +32,10 @@ export function resolveAgentTimeoutMs(opts: {
|
||||
overrideSeconds?: number | null;
|
||||
minMs?: number;
|
||||
}): number {
|
||||
const minMs = Math.max(normalizeNumber(opts.minMs) ?? 1, 1);
|
||||
const minMs = Math.max(resolveOptionalIntegerOption(opts.minMs) ?? 1, 1);
|
||||
const clampTimeoutMs = (valueMs: number) => clampTimerTimeoutMs(valueMs, minMs) ?? minMs;
|
||||
const defaultMs = clampTimeoutMs(resolveAgentTimeoutSeconds(opts.cfg) * 1000);
|
||||
const overrideMs = normalizeNumber(opts.overrideMs);
|
||||
const overrideMs = resolveOptionalIntegerOption(opts.overrideMs);
|
||||
if (overrideMs !== undefined) {
|
||||
if (overrideMs === 0) {
|
||||
return NO_TIMEOUT_MS;
|
||||
@@ -47,7 +45,7 @@ export function resolveAgentTimeoutMs(opts: {
|
||||
}
|
||||
return clampTimeoutMs(overrideMs);
|
||||
}
|
||||
const overrideSeconds = normalizeNumber(opts.overrideSeconds);
|
||||
const overrideSeconds = resolveOptionalIntegerOption(opts.overrideSeconds);
|
||||
if (overrideSeconds !== undefined) {
|
||||
if (overrideSeconds === 0) {
|
||||
return NO_TIMEOUT_MS;
|
||||
|
||||
@@ -30,13 +30,9 @@ function normalizeToolHistoryType(value: unknown): string | undefined {
|
||||
return normalized ? normalized.replace(/_/g, "") : undefined;
|
||||
}
|
||||
|
||||
function parseJsonRecord(value: string): Record<string, unknown> | undefined {
|
||||
return safeParseJsonRecord(value);
|
||||
}
|
||||
|
||||
function readMaybeJsonRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
if (typeof value === "string") {
|
||||
return parseJsonRecord(value);
|
||||
return safeParseJsonRecord(value);
|
||||
}
|
||||
return readRecord(value);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
normalizeOptionalString,
|
||||
normalizeStringifiedOptionalString,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import { normalizeCsvOrLooseStringList } from "@openclaw/normalization-core/string-normalization";
|
||||
import { listAgentIds, resolveAgentDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { AUTH_STORE_VERSION } from "../agents/auth-profiles/constants.js";
|
||||
import { loadPersistedAuthProfileStore } from "../agents/auth-profiles/persisted.js";
|
||||
@@ -66,13 +67,6 @@ function isAbsolutePathValue(value: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function parseCsv(value: string): string[] {
|
||||
return value
|
||||
.split(",")
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry.length > 0);
|
||||
}
|
||||
|
||||
function parseOptionalPositiveInt(value: string, max: number): number | undefined {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) {
|
||||
@@ -216,7 +210,7 @@ function assertNoCancel<T>(value: T | symbol, message: string): T {
|
||||
const AUTH_PROFILE_ID_PATTERN = /^[A-Za-z0-9:_-]{1,128}$/;
|
||||
|
||||
function validateEnvNameCsv(value: string): string | undefined {
|
||||
const entries = parseCsv(value);
|
||||
const entries = normalizeCsvOrLooseStringList(value);
|
||||
for (const entry of entries) {
|
||||
if (!isValidEnvSecretRefId(entry)) {
|
||||
return `Invalid env name: ${entry}`;
|
||||
@@ -237,7 +231,7 @@ async function promptEnvNameCsv(params: {
|
||||
}),
|
||||
"Secrets configure cancelled.",
|
||||
);
|
||||
return parseCsv(raw ?? "");
|
||||
return normalizeCsvOrLooseStringList(raw ?? "");
|
||||
}
|
||||
|
||||
async function promptOptionalPositiveInt(params: {
|
||||
@@ -599,7 +593,7 @@ async function promptExecProvider(
|
||||
message: "Trusted dirs (comma-separated absolute paths, blank for none)",
|
||||
initialValue: base?.trustedDirs?.join(",") ?? "",
|
||||
validate: (value) => {
|
||||
const entries = parseCsv(value ?? "");
|
||||
const entries = normalizeCsvOrLooseStringList(value ?? "");
|
||||
for (const entry of entries) {
|
||||
if (!isAbsolutePathValue(entry)) {
|
||||
return `Trusted dir must be absolute: ${entry}`;
|
||||
@@ -612,7 +606,7 @@ async function promptExecProvider(
|
||||
);
|
||||
|
||||
const args = await parseArgsInput(normalizeStringifiedOptionalString(argsRaw) ?? "");
|
||||
const trustedDirs = parseCsv(trustedDirsRaw ?? "");
|
||||
const trustedDirs = normalizeCsvOrLooseStringList(trustedDirsRaw ?? "");
|
||||
|
||||
return {
|
||||
source: "exec",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Persists managed task-flow records through the OpenClaw SQLite state database.
|
||||
import type { DatabaseSync } from "node:sqlite";
|
||||
import { safeParseJson } from "@openclaw/normalization-core";
|
||||
import type { Insertable, Selectable } from "kysely";
|
||||
import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js";
|
||||
import { normalizeSqliteNumber } from "../infra/sqlite-number.js";
|
||||
@@ -18,7 +17,7 @@ import {
|
||||
type TaskFlowRecord,
|
||||
type TaskFlowSyncMode,
|
||||
} from "./task-flow-registry.types.js";
|
||||
import { parseDeliveryContextJson } from "./task-registry.sqlite.shared.js";
|
||||
import { parseDeliveryContextJson, parseSqliteJsonValue } from "./task-registry.sqlite.shared.js";
|
||||
import { parseTaskNotifyPolicy } from "./task-registry.types.js";
|
||||
|
||||
type FlowRunsTable = OpenClawStateKyselyDatabase["flow_runs"];
|
||||
@@ -42,13 +41,6 @@ function serializeJson(value: unknown): string | null {
|
||||
return value === undefined ? null : JSON.stringify(value);
|
||||
}
|
||||
|
||||
function parseJsonValue(raw: string | null): JsonValue | undefined {
|
||||
if (!raw?.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
return safeParseJson(raw) as JsonValue | undefined;
|
||||
}
|
||||
|
||||
function rowToSyncMode(row: FlowRegistryRow): TaskFlowSyncMode {
|
||||
// Older single_task rows did not persist sync_mode; preserve their mirrored semantics.
|
||||
const syncMode = parseOptionalTaskFlowSyncMode(row.sync_mode);
|
||||
@@ -62,8 +54,8 @@ function rowToFlowRecord(row: FlowRegistryRow): TaskFlowRecord {
|
||||
const endedAt = normalizeSqliteNumber(row.ended_at);
|
||||
const cancelRequestedAt = normalizeSqliteNumber(row.cancel_requested_at);
|
||||
const requesterOrigin = parseDeliveryContextJson(row.requester_origin_json);
|
||||
const stateJson = parseJsonValue(row.state_json);
|
||||
const waitJson = parseJsonValue(row.wait_json);
|
||||
const stateJson = parseSqliteJsonValue<JsonValue>(row.state_json);
|
||||
const waitJson = parseSqliteJsonValue<JsonValue>(row.wait_json);
|
||||
return {
|
||||
flowId: row.flow_id,
|
||||
syncMode: rowToSyncMode(row),
|
||||
|
||||
@@ -5,7 +5,7 @@ import { normalizeDeliveryContext } from "../utils/delivery-context.shared.js";
|
||||
import type { DeliveryContext } from "../utils/delivery-context.types.js";
|
||||
|
||||
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Persisted JSON columns are typed by the receiving field.
|
||||
function parseSqliteJsonValue<T>(raw: string | null): T | undefined {
|
||||
export function parseSqliteJsonValue<T>(raw: string | null): T | undefined {
|
||||
if (!raw?.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Persists task registry records and events through the OpenClaw SQLite state database.
|
||||
import type { DatabaseSync } from "node:sqlite";
|
||||
import { safeParseJson } from "@openclaw/normalization-core";
|
||||
import type { Insertable, Selectable } from "kysely";
|
||||
import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js";
|
||||
import { assertSqliteTableIntegrity } from "../infra/sqlite-integrity.js";
|
||||
@@ -13,7 +12,7 @@ import {
|
||||
runOpenClawStateWriteTransaction,
|
||||
type OpenClawStateDatabase,
|
||||
} from "../state/openclaw-state-db.js";
|
||||
import { parseDeliveryContextJson } from "./task-registry.sqlite.shared.js";
|
||||
import { parseDeliveryContextJson, parseSqliteJsonValue } from "./task-registry.sqlite.shared.js";
|
||||
import type { TaskRegistryStoreSnapshot } from "./task-registry.store.types.js";
|
||||
import {
|
||||
parseOptionalTaskTerminalOutcome,
|
||||
@@ -91,13 +90,6 @@ function serializeJson(value: unknown): string | null {
|
||||
return value === undefined ? null : (JSON.stringify(value) ?? null);
|
||||
}
|
||||
|
||||
function parseJsonValue(raw: string | null): JsonValue | undefined {
|
||||
if (!raw?.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
return safeParseJson(raw) as JsonValue | undefined;
|
||||
}
|
||||
|
||||
function rowToTaskRecord(row: TaskRegistryRow): TaskRecord {
|
||||
const startedAt = normalizeSqliteNumber(row.started_at);
|
||||
const endedAt = normalizeSqliteNumber(row.ended_at);
|
||||
@@ -106,7 +98,7 @@ function rowToTaskRecord(row: TaskRegistryRow): TaskRecord {
|
||||
const toolUseCount = normalizeSqliteNumber(row.tool_use_count);
|
||||
const scopeKind = parseTaskScopeKind(row.scope_kind);
|
||||
const terminalOutcome = parseOptionalTaskTerminalOutcome(row.terminal_outcome);
|
||||
const detail = parseJsonValue(row.detail_json);
|
||||
const detail = parseSqliteJsonValue<JsonValue>(row.detail_json);
|
||||
// System tasks intentionally have no requester session; ownerKey is the lookup anchor.
|
||||
const requesterSessionKey =
|
||||
scopeKind === "system" ? "" : row.requester_session_key?.trim() || row.owner_key;
|
||||
|
||||
@@ -535,13 +535,6 @@ export function resolveEffectiveModelFallbacks(
|
||||
return resolveModelPrimary(entryModel) ? [] : resolveModelFallbacks(defaultModel);
|
||||
}
|
||||
|
||||
export function parseFallbackList(value: string): string[] {
|
||||
return value
|
||||
.split(",")
|
||||
.map((entry) => entry.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
type ConfiguredModelOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Control UI view renders agents panels overview screen content.
|
||||
import { normalizeCsvOrLooseStringList } from "@openclaw/normalization-core/string-normalization";
|
||||
import { html, nothing } from "lit";
|
||||
import type {
|
||||
AgentIdentityResult,
|
||||
@@ -13,7 +14,6 @@ import { t } from "../../i18n/index.ts";
|
||||
import {
|
||||
buildModelOptions,
|
||||
normalizeModelValue,
|
||||
parseFallbackList,
|
||||
resolveAgentConfig,
|
||||
resolveAgentRuntimeLabel,
|
||||
resolveAgentTextAvatar,
|
||||
@@ -141,7 +141,7 @@ export function renderAgentOverview(params: {
|
||||
const input = e.target as HTMLInputElement;
|
||||
if (e.key === "Enter" || e.key === ",") {
|
||||
e.preventDefault();
|
||||
const parsed = parseFallbackList(input.value);
|
||||
const parsed = normalizeCsvOrLooseStringList(input.value);
|
||||
if (parsed.length > 0) {
|
||||
onModelFallbacksChange(agent.id, [...fallbackChips, ...parsed]);
|
||||
input.value = "";
|
||||
@@ -357,7 +357,7 @@ export function renderAgentOverview(params: {
|
||||
@keydown=${handleChipKeydown}
|
||||
@blur=${(e: Event) => {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const parsed = parseFallbackList(input.value);
|
||||
const parsed = normalizeCsvOrLooseStringList(input.value);
|
||||
if (parsed.length > 0) {
|
||||
onModelFallbacksChange(agent.id, [...fallbackChips, ...parsed]);
|
||||
input.value = "";
|
||||
|
||||
Reference in New Issue
Block a user