import type { ClawdbotConfig } from "../config/config.js"; import type { PluginSlotsConfig } from "../config/types.plugins.js"; import type { PluginKind } from "./types.js"; export type PluginSlotKey = keyof PluginSlotsConfig; type SlotPluginRecord = { id: string; kind?: PluginKind; }; const SLOT_BY_KIND: Record = { memory: "memory", }; const DEFAULT_SLOT_BY_KEY: Record = { memory: "memory-core", }; export function slotKeyForPluginKind(kind?: PluginKind): PluginSlotKey | null { if (!kind) return null; return SLOT_BY_KIND[kind] ?? null; } export function defaultSlotIdForKey(slotKey: PluginSlotKey): string { return DEFAULT_SLOT_BY_KEY[slotKey]; } export type SlotSelectionResult = { config: ClawdbotConfig; warnings: string[]; changed: boolean; }; export function applyExclusiveSlotSelection(params: { config: ClawdbotConfig; selectedId: string; selectedKind?: PluginKind; registry?: { plugins: SlotPluginRecord[] }; }): SlotSelectionResult { const slotKey = slotKeyForPluginKind(params.selectedKind); if (!slotKey) { return { config: params.config, warnings: [], changed: false }; } const warnings: string[] = []; const pluginsConfig = params.config.plugins ?? {}; const prevSlot = pluginsConfig.slots?.[slotKey]; const slots = { ...pluginsConfig.slots, [slotKey]: params.selectedId, }; const inferredPrevSlot = prevSlot ?? defaultSlotIdForKey(slotKey); if (inferredPrevSlot && inferredPrevSlot !== params.selectedId) { warnings.push( `Exclusive slot "${slotKey}" switched from "${inferredPrevSlot}" to "${params.selectedId}".`, ); } const entries = { ...pluginsConfig.entries }; const disabledIds: string[] = []; if (params.registry) { for (const plugin of params.registry.plugins) { if (plugin.id === params.selectedId) continue; if (plugin.kind !== params.selectedKind) continue; const entry = entries[plugin.id]; if (!entry || entry.enabled !== false) { entries[plugin.id] = { ...entry, enabled: false, }; disabledIds.push(plugin.id); } } } if (disabledIds.length > 0) { warnings.push(`Disabled other "${slotKey}" slot plugins: ${disabledIds.sort().join(", ")}.`); } const changed = prevSlot !== params.selectedId || disabledIds.length > 0; if (!changed) { return { config: params.config, warnings: [], changed: false }; } return { config: { ...params.config, plugins: { ...pluginsConfig, slots, entries, }, }, warnings, changed: true, }; }