UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

99 lines (98 loc) 3.91 kB
import { t as sanitizeForLog } from "./ansi-BI9w76Cm.js"; import { n as parseToolsBySenderTypedKey } from "./types.tools-2c_JFIK0.js"; import { t as asObjectRecord } from "./object-BsiS9JXh.js"; import { a as resolveConfigPathTarget, t as formatConfigPath } from "./doctor-config-analysis-BUgmtVDJ.js"; //#region src/commands/doctor/shared/legacy-tools-by-sender.ts function collectLegacyToolsBySenderKeyHits(value, pathParts, hits) { if (Array.isArray(value)) { for (const [index, entry] of value.entries()) collectLegacyToolsBySenderKeyHits(entry, [...pathParts, index], hits); return; } const record = asObjectRecord(value); if (!record) return; const toolsBySender = asObjectRecord(record.toolsBySender); if (toolsBySender) { const path = [...pathParts, "toolsBySender"]; const pathLabel = formatConfigPath(path); for (const rawKey of Object.keys(toolsBySender)) { const trimmed = rawKey.trim(); if (!trimmed || trimmed === "*" || parseToolsBySenderTypedKey(trimmed)) continue; hits.push({ toolsBySenderPath: path, pathLabel, key: rawKey, targetKey: `id:${trimmed}` }); } } for (const [key, nested] of Object.entries(record)) { if (key === "toolsBySender") continue; collectLegacyToolsBySenderKeyHits(nested, [...pathParts, key], hits); } } /** Find untyped toolsBySender keys that should be migrated to explicit id: keys. */ function scanLegacyToolsBySenderKeys(cfg) { const hits = []; collectLegacyToolsBySenderKeyHits(cfg, [], hits); return hits; } /** Format doctor warnings for legacy untyped toolsBySender keys. */ function collectLegacyToolsBySenderWarnings(params) { if (params.hits.length === 0) return []; const sample = params.hits[0]; const sampleLabel = sanitizeForLog(sample ? `${sample.pathLabel}.${sample.key}` : "toolsBySender"); return [ `- Found ${params.hits.length} legacy untyped toolsBySender key${params.hits.length === 1 ? "" : "s"} (for example ${sampleLabel}).`, "- Untyped sender keys are deprecated; use explicit prefixes (id:, e164:, username:, name:).", `- Run "${params.doctorFixCommand}" to migrate legacy keys to typed id: entries.` ]; } /** Migrate untyped toolsBySender keys to typed id: keys where possible. */ function maybeRepairLegacyToolsBySenderKeys(cfg) { const hits = scanLegacyToolsBySenderKeys(cfg); if (hits.length === 0) return { config: cfg, changes: [] }; const next = structuredClone(cfg); const summary = /* @__PURE__ */ new Map(); let changed = false; for (const hit of hits) { const toolsBySender = asObjectRecord(resolveConfigPathTarget(next, hit.toolsBySenderPath)); if (!toolsBySender || !(hit.key in toolsBySender)) continue; const row = summary.get(hit.pathLabel) ?? { migrated: 0, dropped: 0, examples: [] }; if (toolsBySender[hit.targetKey] === void 0) { toolsBySender[hit.targetKey] = toolsBySender[hit.key]; row.migrated++; if (row.examples.length < 3) row.examples.push(`${hit.key} -> ${hit.targetKey}`); } else { row.dropped++; if (row.examples.length < 3) row.examples.push(`${hit.key} (kept existing ${hit.targetKey})`); } delete toolsBySender[hit.key]; summary.set(hit.pathLabel, row); changed = true; } if (!changed) return { config: cfg, changes: [] }; const changes = []; for (const [pathLabel, row] of summary) { if (row.migrated > 0) { const suffix = row.examples.length > 0 ? ` (${row.examples.join(", ")})` : ""; changes.push(`- ${pathLabel}: migrated ${row.migrated} legacy key${row.migrated === 1 ? "" : "s"} to typed id: entries${suffix}.`); } if (row.dropped > 0) changes.push(`- ${pathLabel}: removed ${row.dropped} legacy key${row.dropped === 1 ? "" : "s"} where typed id: entries already existed.`); } return { config: next, changes }; } //#endregion export { maybeRepairLegacyToolsBySenderKeys as n, scanLegacyToolsBySenderKeys as r, collectLegacyToolsBySenderWarnings as t };