





















@@ -123,6 +123,115 @@ function setPathValue(value: unknown, path: string[], nextValue: unknown): unkno
123123};
124124}
125125126+function pathStartsWith(path: string[], prefix: string[]): boolean {
127+return prefix.length <= path.length && prefix.every((segment, index) => path[index] === segment);
128+}
129+130+function pathOverlapsAny(path: string[], candidates: readonly string[][] | undefined): boolean {
131+return Boolean(
132+candidates?.some(
133+(candidate) => pathStartsWith(path, candidate) || pathStartsWith(candidate, path),
134+),
135+);
136+}
137+138+function isIncludeOwnedPath(rootAuthoredConfig: unknown, path: string[]): boolean {
139+return collectIncludeOwnedPaths(rootAuthoredConfig).some(
140+(includePath) => pathStartsWith(path, includePath) || pathStartsWith(includePath, path),
141+);
142+}
143+144+function setPathValueCreatingParents(value: unknown, path: string[], nextValue: unknown): unknown {
145+if (path.length === 0) {
146+return cloneUnknown(nextValue);
147+}
148+const [head, ...tail] = path;
149+const record = isRecord(value) ? value : {};
150+return {
151+ ...record,
152+[head]: setPathValueCreatingParents(record[head], tail, nextValue),
153+};
154+}
155+156+function preserveSourceValueAtPath(params: {
157+persistedCandidate: unknown;
158+sourceConfig: unknown;
159+nextConfig: unknown;
160+rootAuthoredConfig: unknown;
161+unsetPaths?: readonly string[][];
162+path: string[];
163+sourceValue?: unknown;
164+}): unknown {
165+if (pathOverlapsAny(params.path, params.unsetPaths)) {
166+return params.persistedCandidate;
167+}
168+if (isIncludeOwnedPath(params.rootAuthoredConfig, params.path)) {
169+return params.persistedCandidate;
170+}
171+if (getPathValue(params.nextConfig, params.path) !== undefined) {
172+return params.persistedCandidate;
173+}
174+const sourceValue = params.sourceValue ?? getPathValue(params.sourceConfig, params.path);
175+if (
176+sourceValue === undefined ||
177+getPathValue(params.persistedCandidate, params.path) !== undefined
178+) {
179+return params.persistedCandidate;
180+}
181+return setPathValueCreatingParents(params.persistedCandidate, params.path, sourceValue);
182+}
183+184+function preserveAuthoredAgentParams(params: {
185+persistedCandidate: unknown;
186+sourceConfig: unknown;
187+nextConfig: unknown;
188+rootAuthoredConfig: unknown;
189+unsetPaths?: readonly string[][];
190+}): unknown {
191+const defaults = getPathValue(params.sourceConfig, ["agents", "defaults"]);
192+if (!isRecord(defaults)) {
193+return params.persistedCandidate;
194+}
195+196+let next = params.persistedCandidate;
197+if (Object.prototype.hasOwnProperty.call(defaults, "params")) {
198+next = preserveSourceValueAtPath({
199+ ...params,
200+persistedCandidate: next,
201+path: ["agents", "defaults", "params"],
202+sourceValue: defaults.params,
203+});
204+}
205+206+const models = defaults.models;
207+if (!isRecord(models)) {
208+return next;
209+}
210+for (const [modelId, modelEntry] of Object.entries(models)) {
211+if (!isRecord(modelEntry) || !Object.prototype.hasOwnProperty.call(modelEntry, "params")) {
212+continue;
213+}
214+const modelPath = ["agents", "defaults", "models", modelId];
215+const paramsPath = [...modelPath, "params"];
216+if (getPathValue(next, modelPath) === undefined) {
217+next = preserveSourceValueAtPath({
218+ ...params,
219+persistedCandidate: next,
220+path: modelPath,
221+sourceValue: modelEntry,
222+});
223+continue;
224+}
225+next = preserveSourceValueAtPath({
226+ ...params,
227+persistedCandidate: next,
228+path: paramsPath,
229+sourceValue: modelEntry.params,
230+});
231+}
232+return next;
233+}
234+126235function preserveUntouchedIncludes(params: {
127236patch: unknown;
128237rootAuthoredConfig: unknown;
@@ -147,19 +256,28 @@ export function resolvePersistCandidateForWrite(params: {
147256sourceConfig: unknown;
148257nextConfig: unknown;
149258rootAuthoredConfig?: unknown;
259+unsetPaths?: readonly string[][];
150260}): unknown {
151261const patch = createMergePatch(params.runtimeConfig, params.nextConfig);
152262const projectedSource = projectSourceOntoRuntimeShape(params.sourceConfig, params.runtimeConfig);
263+const rootAuthoredConfig = params.rootAuthoredConfig ?? params.sourceConfig;
153264const persisted = preserveUntouchedIncludes({
154265 patch,
155-rootAuthoredConfig: params.rootAuthoredConfig ?? params.sourceConfig,
266+ rootAuthoredConfig,
156267persistedCandidate: applyMergePatch(projectedSource, patch),
157268});
158-return preserveRootSchemaUri({
159-rootAuthoredConfig: params.rootAuthoredConfig ?? params.sourceConfig,
269+const withSchema = preserveRootSchemaUri({
270+ rootAuthoredConfig,
160271nextConfig: params.nextConfig,
161272persistedCandidate: persisted,
162273});
274+return preserveAuthoredAgentParams({
275+sourceConfig: params.sourceConfig,
276+nextConfig: params.nextConfig,
277+ rootAuthoredConfig,
278+persistedCandidate: withSchema,
279+unsetPaths: params.unsetPaths,
280+});
163281}
164282165283function readRootSchemaUri(value: unknown): string | undefined {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。