
























@@ -1,5 +1,7 @@
11import fs from "node:fs";
22import { createSubsystemLogger } from "../../logging/subsystem.js";
3+import { isPluginJsonValue, type PluginJsonValue } from "../../plugins/host-hook-json.js";
4+import { normalizeSessionEntrySlotKey } from "../../plugins/session-entry-slot-keys.js";
35import {
46normalizeDeliveryContext,
57normalizeSessionDeliveryFields,
@@ -59,6 +61,11 @@ function normalizeOptionalStringOrNull(value: unknown): string | null | undefine
5961return undefined;
6062}
616364+function normalizeRecordKey(value: string): string | undefined {
65+const key = value.trim();
66+return key.length > 0 ? key : undefined;
67+}
68+6269function normalizeOptionalDeliveryContext(
6370value: unknown,
6471): SessionEntry["pendingFinalDeliveryContext"] {
@@ -138,6 +145,111 @@ function normalizePendingFinalDeliveryFields(entry: SessionEntry): SessionEntry
138145return next;
139146}
140147148+function normalizePluginExtensions(entry: SessionEntry): SessionEntry {
149+if (entry.pluginExtensions === undefined) {
150+return entry;
151+}
152+if (!isRecord(entry.pluginExtensions)) {
153+const next = { ...entry };
154+delete next.pluginExtensions;
155+return next;
156+}
157+158+let changed = false;
159+const normalizedExtensions: Record<string, Record<string, PluginJsonValue>> = {};
160+for (const [rawPluginId, rawPluginState] of Object.entries(entry.pluginExtensions)) {
161+const pluginId = normalizeRecordKey(rawPluginId);
162+if (!pluginId || !isRecord(rawPluginState)) {
163+changed = true;
164+continue;
165+}
166+if (pluginId !== rawPluginId) {
167+changed = true;
168+}
169+const normalizedPluginState: Record<string, PluginJsonValue> = {};
170+for (const [rawNamespace, rawValue] of Object.entries(rawPluginState)) {
171+const namespace = normalizeRecordKey(rawNamespace);
172+if (!namespace || !isPluginJsonValue(rawValue)) {
173+changed = true;
174+continue;
175+}
176+if (namespace !== rawNamespace) {
177+changed = true;
178+}
179+normalizedPluginState[namespace] = rawValue;
180+}
181+if (Object.keys(normalizedPluginState).length === 0) {
182+changed = true;
183+continue;
184+}
185+normalizedExtensions[pluginId] = normalizedPluginState;
186+}
187+188+if (!changed) {
189+return entry;
190+}
191+const next = { ...entry };
192+if (Object.keys(normalizedExtensions).length > 0) {
193+next.pluginExtensions = normalizedExtensions;
194+} else {
195+delete next.pluginExtensions;
196+}
197+return next;
198+}
199+200+function normalizePluginExtensionSlotKeys(entry: SessionEntry): SessionEntry {
201+if (entry.pluginExtensionSlotKeys === undefined) {
202+return entry;
203+}
204+if (!isRecord(entry.pluginExtensionSlotKeys)) {
205+const next = { ...entry };
206+delete next.pluginExtensionSlotKeys;
207+return next;
208+}
209+210+let changed = false;
211+const normalizedSlotKeys: Record<string, Record<string, string>> = {};
212+for (const [rawPluginId, rawPluginSlots] of Object.entries(entry.pluginExtensionSlotKeys)) {
213+const pluginId = normalizeRecordKey(rawPluginId);
214+if (!pluginId || !isRecord(rawPluginSlots)) {
215+changed = true;
216+continue;
217+}
218+if (pluginId !== rawPluginId) {
219+changed = true;
220+}
221+const normalizedPluginSlots: Record<string, string> = {};
222+for (const [rawNamespace, rawSlotKey] of Object.entries(rawPluginSlots)) {
223+const namespace = normalizeRecordKey(rawNamespace);
224+const slotKey = normalizeSessionEntrySlotKey(rawSlotKey);
225+if (!namespace || !slotKey.ok) {
226+changed = true;
227+continue;
228+}
229+if (namespace !== rawNamespace || slotKey.key !== rawSlotKey) {
230+changed = true;
231+}
232+normalizedPluginSlots[namespace] = slotKey.key;
233+}
234+if (Object.keys(normalizedPluginSlots).length === 0) {
235+changed = true;
236+continue;
237+}
238+normalizedSlotKeys[pluginId] = normalizedPluginSlots;
239+}
240+241+if (!changed) {
242+return entry;
243+}
244+const next = { ...entry };
245+if (Object.keys(normalizedSlotKeys).length > 0) {
246+next.pluginExtensionSlotKeys = normalizedSlotKeys;
247+} else {
248+delete next.pluginExtensionSlotKeys;
249+}
250+return next;
251+}
252+141253function normalizeSessionEntryDelivery(entry: SessionEntry): SessionEntry {
142254const normalized = normalizeSessionDeliveryFields({
143255channel: entry.channel,
@@ -195,8 +307,12 @@ export function normalizeSessionStore(store: Record<string, SessionEntry>): bool
195307continue;
196308}
197309const normalized = stripPersistedSkillsCache(
198-normalizePendingFinalDeliveryFields(
199-normalizeSessionEntryDelivery(normalizeSessionRuntimeModelFields(entry)),
310+normalizePluginExtensionSlotKeys(
311+normalizePluginExtensions(
312+normalizePendingFinalDeliveryFields(
313+normalizeSessionEntryDelivery(normalizeSessionRuntimeModelFields(entry)),
314+),
315+),
200316),
201317);
202318if (normalized !== entry) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。