@caupulican/pi-adaptative 0.81.26 → 0.81.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +4 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +19 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +30 -12
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +128 -36
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +6 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +35 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +59 -19
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +2 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +31 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -0
- package/dist/core/autonomy/lane-tool-surface.js +96 -0
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -0
- package/dist/core/autonomy/lane-tracker.d.ts +5 -0
- package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tracker.js +14 -3
- package/dist/core/autonomy/lane-tracker.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +28 -4
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +237 -28
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/billing-failover-controller.d.ts.map +1 -1
- package/dist/core/billing-failover-controller.js +1 -1
- package/dist/core/billing-failover-controller.js.map +1 -1
- package/dist/core/context/current-work-memory.d.ts +9 -0
- package/dist/core/context/current-work-memory.d.ts.map +1 -0
- package/dist/core/context/current-work-memory.js +61 -0
- package/dist/core/context/current-work-memory.js.map +1 -0
- package/dist/core/context/file-store-memory-provider.d.ts +9 -0
- package/dist/core/context/file-store-memory-provider.d.ts.map +1 -0
- package/dist/core/context/file-store-memory-provider.js +106 -0
- package/dist/core/context/file-store-memory-provider.js.map +1 -0
- package/dist/core/context/long-term-memory-trigger.d.ts +15 -0
- package/dist/core/context/long-term-memory-trigger.d.ts.map +1 -0
- package/dist/core/context/long-term-memory-trigger.js +39 -0
- package/dist/core/context/long-term-memory-trigger.js.map +1 -0
- package/dist/core/context/memory-prompt-block.d.ts +3 -1
- package/dist/core/context/memory-prompt-block.d.ts.map +1 -1
- package/dist/core/context/memory-prompt-block.js +20 -3
- package/dist/core/context/memory-prompt-block.js.map +1 -1
- package/dist/core/context/memory-prompt-budget.d.ts +17 -0
- package/dist/core/context/memory-prompt-budget.d.ts.map +1 -0
- package/dist/core/context/memory-prompt-budget.js +64 -0
- package/dist/core/context/memory-prompt-budget.js.map +1 -0
- package/dist/core/context/memory-provider-contract.d.ts.map +1 -1
- package/dist/core/context/memory-provider-contract.js +2 -5
- package/dist/core/context/memory-provider-contract.js.map +1 -1
- package/dist/core/context/memory-tier-composer.d.ts +27 -0
- package/dist/core/context/memory-tier-composer.d.ts.map +1 -0
- package/dist/core/context/memory-tier-composer.js +79 -0
- package/dist/core/context/memory-tier-composer.js.map +1 -0
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +2 -0
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +5 -3
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +15 -5
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/cost/cost-summary.d.ts +3 -1
- package/dist/core/cost/cost-summary.d.ts.map +1 -1
- package/dist/core/cost/cost-summary.js +3 -3
- package/dist/core/cost/cost-summary.js.map +1 -1
- package/dist/core/cost-guard.d.ts +17 -7
- package/dist/core/cost-guard.d.ts.map +1 -1
- package/dist/core/cost-guard.js +33 -10
- package/dist/core/cost-guard.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts +9 -0
- package/dist/core/default-tool-surface.d.ts.map +1 -0
- package/dist/core/default-tool-surface.js +18 -0
- package/dist/core/default-tool-surface.js.map +1 -0
- package/dist/core/delegation/worker-result.d.ts.map +1 -1
- package/dist/core/delegation/worker-result.js +3 -0
- package/dist/core/delegation/worker-result.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +11 -5
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +77 -16
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +15 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +7 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/failure-corpus.d.ts.map +1 -1
- package/dist/core/failure-corpus.js +2 -4
- package/dist/core/failure-corpus.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +9 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +4 -3
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +12 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +42 -4
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +16 -0
- package/dist/core/local-runtime-controller.d.ts.map +1 -1
- package/dist/core/local-runtime-controller.js +107 -28
- package/dist/core/local-runtime-controller.js.map +1 -1
- package/dist/core/memory/memory-manager.d.ts +8 -3
- package/dist/core/memory/memory-manager.d.ts.map +1 -1
- package/dist/core/memory/memory-manager.js +27 -11
- package/dist/core/memory/memory-manager.js.map +1 -1
- package/dist/core/memory/memory-provider.d.ts +5 -1
- package/dist/core/memory/memory-provider.d.ts.map +1 -1
- package/dist/core/memory/memory-provider.js.map +1 -1
- package/dist/core/memory/providers/file-store.d.ts +3 -1
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +7 -2
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/memory/providers/transcript-recall.d.ts +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +4 -7
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +36 -10
- package/dist/core/memory-controller.d.ts.map +1 -1
- package/dist/core/memory-controller.js +137 -21
- package/dist/core/memory-controller.js.map +1 -1
- package/dist/core/model-registry.d.ts +25 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +91 -8
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +30 -11
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +33 -29
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/model-selection-controller.d.ts +3 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -1
- package/dist/core/model-selection-controller.js +8 -1
- package/dist/core/model-selection-controller.js.map +1 -1
- package/dist/core/models/local-runtime.d.ts +2 -0
- package/dist/core/models/local-runtime.d.ts.map +1 -1
- package/dist/core/models/local-runtime.js +10 -4
- package/dist/core/models/local-runtime.js.map +1 -1
- package/dist/core/models/perf-profile.d.ts.map +1 -1
- package/dist/core/models/perf-profile.js +95 -33
- package/dist/core/models/perf-profile.js.map +1 -1
- package/dist/core/models/runtime-arbiter.d.ts +11 -0
- package/dist/core/models/runtime-arbiter.d.ts.map +1 -1
- package/dist/core/models/runtime-arbiter.js +35 -13
- package/dist/core/models/runtime-arbiter.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +11 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -1
- package/dist/core/profile-filter-controller.js +56 -11
- package/dist/core/profile-filter-controller.js.map +1 -1
- package/dist/core/profile-registry.d.ts +2 -2
- package/dist/core/profile-registry.d.ts.map +1 -1
- package/dist/core/profile-registry.js +58 -7
- package/dist/core/profile-registry.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +9 -7
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +81 -12
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/research/research-runner.d.ts +2 -2
- package/dist/core/research/research-runner.d.ts.map +1 -1
- package/dist/core/research/research-runner.js +8 -6
- package/dist/core/research/research-runner.js.map +1 -1
- package/dist/core/resource-loader.d.ts +4 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +11 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +30 -3
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +140 -40
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -7
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +38 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/security/secret-text.d.ts +3 -0
- package/dist/core/security/secret-text.d.ts.map +1 -0
- package/dist/core/security/secret-text.js +26 -0
- package/dist/core/security/secret-text.js.map +1 -0
- package/dist/core/settings-manager.d.ts +59 -17
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +300 -51
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +7 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +23 -1
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/tool-gate-controller.d.ts +3 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -1
- package/dist/core/tool-gate-controller.js +20 -15
- package/dist/core/tool-gate-controller.js.map +1 -1
- package/dist/core/tool-selection/expected-utility.d.ts +51 -0
- package/dist/core/tool-selection/expected-utility.d.ts.map +1 -0
- package/dist/core/tool-selection/expected-utility.js +85 -0
- package/dist/core/tool-selection/expected-utility.js.map +1 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts +82 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -0
- package/dist/core/tool-selection/tool-performance-store.js +249 -0
- package/dist/core/tool-selection/tool-performance-store.js.map +1 -0
- package/dist/core/tool-selection/tool-selection-controller.d.ts +41 -0
- package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -0
- package/dist/core/tool-selection/tool-selection-controller.js +199 -0
- package/dist/core/tool-selection/tool-selection-controller.js.map +1 -0
- package/dist/core/tools/delegate-status.d.ts +9 -0
- package/dist/core/tools/delegate-status.d.ts.map +1 -0
- package/dist/core/tools/delegate-status.js +52 -0
- package/dist/core/tools/delegate-status.js.map +1 -0
- package/dist/core/tools/delegate.d.ts +10 -0
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +36 -13
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/run-toolkit-script.d.ts +3 -0
- package/dist/core/tools/run-toolkit-script.d.ts.map +1 -1
- package/dist/core/tools/run-toolkit-script.js +17 -7
- package/dist/core/tools/run-toolkit-script.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +69 -29
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +7 -1
- package/dist/modes/interactive/config-backup.d.ts.map +1 -1
- package/dist/modes/interactive/config-backup.js +196 -32
- package/dist/modes/interactive/config-backup.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +22 -28
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +2 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/dist/modes/interactive/profile-menu-controller.d.ts +6 -4
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
- package/dist/modes/interactive/profile-menu-controller.js +248 -65
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
- package/dist/modes/interactive/report-commands.d.ts.map +1 -1
- package/dist/modes/interactive/report-commands.js +8 -2
- package/dist/modes/interactive/report-commands.js.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.js +8 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +3 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/docs/extensions.md +32 -0
- package/docs/integration-sweep-builder-blueprint-2026-07-09.md +365 -0
- package/docs/integration-sweep-resume-2026-07-09.md +407 -0
- package/docs/resources.md +15 -7
- package/docs/settings.md +56 -5
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +44 -35
- package/package.json +4 -4
|
@@ -9,7 +9,7 @@ import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
|
9
9
|
import { DEFAULT_GOAL_AUTO_CONTINUE, DEFAULT_GOAL_AUTO_CONTINUE_DELAY_MS, DEFAULT_GOAL_CONTINUE_MAX_STALL_TURNS, DEFAULT_GOAL_CONTINUE_MAX_TURNS, DEFAULT_GOAL_CONTINUE_MAX_WALL_CLOCK_MINUTES, MAX_GOAL_AUTO_CONTINUE_DELAY_MS, MAX_GOAL_CONTINUE_MAX_STALL_TURNS, MAX_GOAL_CONTINUE_MAX_TURNS, MAX_GOAL_CONTINUE_MAX_WALL_CLOCK_MINUTES, } from "./goals/goal-continuation-defaults.js";
|
|
10
10
|
import { DEFAULT_HTTP_IDLE_TIMEOUT_MS, parseHttpIdleTimeoutMs } from "./http-dispatcher.js";
|
|
11
11
|
import { ProfileRegistry } from "./profile-registry.js";
|
|
12
|
-
import { mergeResourceProfileMap } from "./resource-profile-blocks.js";
|
|
12
|
+
import { mergeResourceProfileMap, mergeResourceProfileSettings } from "./resource-profile-blocks.js";
|
|
13
13
|
import { validateSkillName } from "./skills.js";
|
|
14
14
|
export const MEMORY_RETRIEVAL_MAX_RESULTS_MIN = 1;
|
|
15
15
|
export const MEMORY_RETRIEVAL_MAX_RESULTS_MAX = 20;
|
|
@@ -35,7 +35,7 @@ export const MAX_RESEARCH_LANE_MAX_FINDINGS = 50;
|
|
|
35
35
|
export const MAX_RESEARCH_LANE_MAX_WALL_CLOCK_MS = 3_600_000;
|
|
36
36
|
export const MAX_RESEARCH_LANE_IDLE_DELAY_MS = 300_000;
|
|
37
37
|
export const MAX_RESEARCH_LANE_MAX_RUNS_PER_SESSION = 100;
|
|
38
|
-
export const DEFAULT_WORKER_DELEGATION_ENABLED =
|
|
38
|
+
export const DEFAULT_WORKER_DELEGATION_ENABLED = true;
|
|
39
39
|
export const DEFAULT_WORKER_DELEGATION_MAX_USD = 0.5;
|
|
40
40
|
export const DEFAULT_WORKER_DELEGATION_MAX_WALL_CLOCK_MS = 120_000;
|
|
41
41
|
export const MAX_WORKER_DELEGATION_MAX_USD = 5;
|
|
@@ -144,9 +144,17 @@ function normalizeResourceProfileNames(value) {
|
|
|
144
144
|
function hasExplicitActiveResourceProfileSelection(settings) {
|
|
145
145
|
return Object.hasOwn(settings, "activeResourceProfiles") || Object.hasOwn(settings, "activeResourceProfile");
|
|
146
146
|
}
|
|
147
|
+
function hasExplicitEmptyActiveResourceProfileSelection(settings) {
|
|
148
|
+
return (Object.hasOwn(settings, "activeResourceProfiles") &&
|
|
149
|
+
normalizeResourceProfileNames(settings.activeResourceProfiles).length === 0);
|
|
150
|
+
}
|
|
147
151
|
function normalizeActiveResourceProfiles(settings) {
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
// The array form is canonical when present, including an explicit empty array. Falling through
|
|
153
|
+
// from `activeResourceProfiles: []` to the scalar alias would resurrect a lower-precedence or
|
|
154
|
+
// legacy selection and makes it impossible to persist a durable "none" choice.
|
|
155
|
+
const values = Object.hasOwn(settings, "activeResourceProfiles")
|
|
156
|
+
? normalizeResourceProfileNames(settings.activeResourceProfiles)
|
|
157
|
+
: normalizeResourceProfileNames(settings.activeResourceProfile);
|
|
150
158
|
if (values.length === 0 &&
|
|
151
159
|
!hasExplicitActiveResourceProfileSelection(settings) &&
|
|
152
160
|
settings.resourceProfiles?.default) {
|
|
@@ -205,7 +213,7 @@ function sanitizeNumberSetting(value, fallback, min, max) {
|
|
|
205
213
|
return fallback;
|
|
206
214
|
return value;
|
|
207
215
|
}
|
|
208
|
-
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
|
|
216
|
+
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
209
217
|
function isThinkingLevel(value) {
|
|
210
218
|
return typeof value === "string" && VALID_THINKING_LEVELS.includes(value);
|
|
211
219
|
}
|
|
@@ -275,12 +283,12 @@ function normalizeModelRouterSettings(value) {
|
|
|
275
283
|
}
|
|
276
284
|
return Object.keys(settings).length > 0 ? settings : undefined;
|
|
277
285
|
}
|
|
278
|
-
function parseProfileFileDefinition(content) {
|
|
286
|
+
function parseProfileFileDefinition(content, fallbackName) {
|
|
279
287
|
const parsed = JSON.parse(content);
|
|
280
288
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
281
289
|
throw new Error("profile file must contain a JSON object");
|
|
282
290
|
}
|
|
283
|
-
const name = typeof parsed.name === "string" ? parsed.name.trim() : undefined;
|
|
291
|
+
const name = (typeof parsed.name === "string" ? parsed.name.trim() : undefined) || fallbackName;
|
|
284
292
|
if (!name) {
|
|
285
293
|
throw new Error("profile name is required");
|
|
286
294
|
}
|
|
@@ -296,6 +304,7 @@ function parseProfileFileDefinition(content) {
|
|
|
296
304
|
};
|
|
297
305
|
}
|
|
298
306
|
export class FileSettingsStorage {
|
|
307
|
+
profileResolutionBaseDir;
|
|
299
308
|
globalSettingsPath;
|
|
300
309
|
projectSettingsPath;
|
|
301
310
|
directoryProfileInfo;
|
|
@@ -303,6 +312,7 @@ export class FileSettingsStorage {
|
|
|
303
312
|
constructor(cwd, agentDir) {
|
|
304
313
|
const resolvedCwd = resolvePath(cwd);
|
|
305
314
|
const resolvedAgentDir = resolvePath(agentDir);
|
|
315
|
+
this.profileResolutionBaseDir = resolvedCwd;
|
|
306
316
|
this.globalSettingsPath = join(resolvedAgentDir, "settings.json");
|
|
307
317
|
this.projectSettingsPath = join(resolvedCwd, CONFIG_DIR_NAME, "settings.json");
|
|
308
318
|
this.directoryProfileInfo = getDirectoryResourceProfileInfo(resolvedCwd, resolvedAgentDir);
|
|
@@ -314,6 +324,9 @@ export class FileSettingsStorage {
|
|
|
314
324
|
getProfilesDir() {
|
|
315
325
|
return this.profilesDir;
|
|
316
326
|
}
|
|
327
|
+
getProfileResolutionBaseDir() {
|
|
328
|
+
return this.profileResolutionBaseDir;
|
|
329
|
+
}
|
|
317
330
|
readDirectoryResourceProfile() {
|
|
318
331
|
const path = this.directoryProfileInfo.path;
|
|
319
332
|
return existsSync(path) ? readFileSync(path, "utf-8") : undefined;
|
|
@@ -454,9 +467,15 @@ export class SettingsManager {
|
|
|
454
467
|
// Mirror getActiveResourceProfileNames()'s source precedence (runtime profiles from
|
|
455
468
|
// --resource-profile take priority) so a bad runtime profile name still surfaces a
|
|
456
469
|
// "profile not found" diagnostic instead of silently applying zero filtering.
|
|
457
|
-
if (this.runtimeResourceProfiles
|
|
470
|
+
if (this.runtimeResourceProfiles !== undefined) {
|
|
458
471
|
return normalizeResourceProfileNames(this.runtimeResourceProfiles);
|
|
459
472
|
}
|
|
473
|
+
// `/profiles none` is persisted globally as an explicit empty array. It is a durable
|
|
474
|
+
// user-level off switch and must dominate project/directory/default/external fallbacks until
|
|
475
|
+
// the user explicitly selects another profile.
|
|
476
|
+
if (hasExplicitEmptyActiveResourceProfileSelection(this.globalSettings)) {
|
|
477
|
+
return [];
|
|
478
|
+
}
|
|
460
479
|
const explicitProfiles = this.settings.activeResourceProfiles && this.settings.activeResourceProfiles.length > 0
|
|
461
480
|
? this.settings.activeResourceProfiles
|
|
462
481
|
: this.settings.activeResourceProfile
|
|
@@ -492,16 +511,24 @@ export class SettingsManager {
|
|
|
492
511
|
this.reportProfileDiagnostic("global", `Profile diagnostic${path}: ${diagnostic.message}`);
|
|
493
512
|
}
|
|
494
513
|
for (const profileName of this.getActiveProfileNamesForDiagnostics()) {
|
|
495
|
-
if (!this.profileRegistry
|
|
514
|
+
if (!this.resolveProfileFromRegistry(this.profileRegistry, profileName)) {
|
|
496
515
|
this.reportProfileDiagnostic("global", `Active profile not found: ${profileName}`);
|
|
497
516
|
}
|
|
498
517
|
}
|
|
499
518
|
}
|
|
519
|
+
resolveProfileFromRegistry(registry, profileRef) {
|
|
520
|
+
return profileRef.startsWith("./") || profileRef.startsWith("../")
|
|
521
|
+
? registry.resolveProfileRef(profileRef, this.storage.getProfileResolutionBaseDir?.() ?? process.cwd())
|
|
522
|
+
: registry.getProfile(profileRef);
|
|
523
|
+
}
|
|
500
524
|
mergeEffectiveSettings() {
|
|
501
525
|
let merged = deepMergeSettings(this.globalSettings, this.projectSettings);
|
|
502
526
|
merged = deepMergeSettings(merged, this.directoryProfileSettings);
|
|
503
|
-
if (this.runtimeResourceProfiles) {
|
|
504
|
-
merged = deepMergeSettings(merged, {
|
|
527
|
+
if (this.runtimeResourceProfiles !== undefined) {
|
|
528
|
+
merged = deepMergeSettings(merged, {
|
|
529
|
+
activeResourceProfile: this.runtimeResourceProfiles,
|
|
530
|
+
activeResourceProfiles: this.runtimeResourceProfiles,
|
|
531
|
+
});
|
|
505
532
|
}
|
|
506
533
|
return merged;
|
|
507
534
|
}
|
|
@@ -643,16 +670,22 @@ export class SettingsManager {
|
|
|
643
670
|
return this.profileRegistry;
|
|
644
671
|
}
|
|
645
672
|
getActiveResourceProfileNames() {
|
|
646
|
-
if (this.runtimeResourceProfiles
|
|
673
|
+
if (this.runtimeResourceProfiles !== undefined) {
|
|
647
674
|
return [...this.runtimeResourceProfiles];
|
|
648
675
|
}
|
|
676
|
+
if (hasExplicitEmptyActiveResourceProfileSelection(this.globalSettings)) {
|
|
677
|
+
return [];
|
|
678
|
+
}
|
|
649
679
|
const names = normalizeActiveResourceProfiles(this.settings);
|
|
650
680
|
return names.length > 0 || hasExplicitActiveResourceProfileSelection(this.settings)
|
|
651
681
|
? names
|
|
652
682
|
: this.getExternalRootActiveResourceProfileNames();
|
|
653
683
|
}
|
|
654
684
|
hasExplicitActiveResourceProfileSelection() {
|
|
655
|
-
|
|
685
|
+
// An explicit empty runtime/settings selection means "no profile", not an invalid profile
|
|
686
|
+
// whose authority should collapse to deny-all. Non-empty unresolved refs remain explicit and
|
|
687
|
+
// are diagnosed/strictly denied through the normal active-profile path.
|
|
688
|
+
return this.getActiveResourceProfileNames().length > 0;
|
|
656
689
|
}
|
|
657
690
|
/**
|
|
658
691
|
* Aggregate ONLY the active profiles' contribution to a resource kind's filter — the user's own
|
|
@@ -673,7 +706,7 @@ export class SettingsManager {
|
|
|
673
706
|
if (seenProfiles.has(profileName))
|
|
674
707
|
continue;
|
|
675
708
|
seenProfiles.add(profileName);
|
|
676
|
-
const kindFilter =
|
|
709
|
+
const kindFilter = this.resolveProfileFromRegistry(registry, profileName)?.resources[kind];
|
|
677
710
|
if (kindFilter && ((kindFilter.allow?.length ?? 0) > 0 || (kindFilter.block?.length ?? 0) > 0)) {
|
|
678
711
|
kindMentionedByProfile = true;
|
|
679
712
|
}
|
|
@@ -713,7 +746,7 @@ export class SettingsManager {
|
|
|
713
746
|
const registry = this.getProfileRegistry();
|
|
714
747
|
const conflicts = new Set();
|
|
715
748
|
for (const profileName of this.getActiveResourceProfileNames()) {
|
|
716
|
-
const filter =
|
|
749
|
+
const filter = this.resolveProfileFromRegistry(registry, profileName)?.resources[kind];
|
|
717
750
|
for (const allowEntry of filter?.allow ?? []) {
|
|
718
751
|
if (allowEntry === "*")
|
|
719
752
|
continue;
|
|
@@ -763,7 +796,7 @@ export class SettingsManager {
|
|
|
763
796
|
if (seen.has(profileName))
|
|
764
797
|
continue;
|
|
765
798
|
seen.add(profileName);
|
|
766
|
-
const soul =
|
|
799
|
+
const soul = this.resolveProfileFromRegistry(registry, profileName)?.soul?.trim();
|
|
767
800
|
if (soul)
|
|
768
801
|
return soul;
|
|
769
802
|
}
|
|
@@ -827,18 +860,69 @@ export class SettingsManager {
|
|
|
827
860
|
}
|
|
828
861
|
this.recomputeSettings();
|
|
829
862
|
}
|
|
863
|
+
/** Capture the complete in-memory settings generation before runtime reload mutates it. */
|
|
864
|
+
createReloadSnapshot() {
|
|
865
|
+
return {
|
|
866
|
+
globalSettings: structuredClone(this.globalSettings),
|
|
867
|
+
projectSettings: structuredClone(this.projectSettings),
|
|
868
|
+
directoryProfileSettings: structuredClone(this.directoryProfileSettings),
|
|
869
|
+
runtimeResourceProfiles: this.runtimeResourceProfiles === undefined ? undefined : [...this.runtimeResourceProfiles],
|
|
870
|
+
inlineResourceProfileDefinitions: structuredClone(this.inlineResourceProfileDefinitions),
|
|
871
|
+
discoveredResourceProfileDefinitions: structuredClone(this.discoveredResourceProfileDefinitions),
|
|
872
|
+
effectiveSettings: structuredClone(this.settings),
|
|
873
|
+
projectTrusted: this.projectTrusted,
|
|
874
|
+
modifiedFields: new Set(this.modifiedFields),
|
|
875
|
+
modifiedNestedFields: this.cloneModifiedNestedFields(this.modifiedNestedFields),
|
|
876
|
+
modifiedProjectFields: new Set(this.modifiedProjectFields),
|
|
877
|
+
modifiedProjectNestedFields: this.cloneModifiedNestedFields(this.modifiedProjectNestedFields),
|
|
878
|
+
globalSettingsLoadError: this.globalSettingsLoadError,
|
|
879
|
+
projectSettingsLoadError: this.projectSettingsLoadError,
|
|
880
|
+
directoryProfileInfo: this.directoryProfileInfo ? { ...this.directoryProfileInfo } : null,
|
|
881
|
+
errors: [...this.errors],
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
/** Restore a failed runtime reload without changing the on-disk settings generation. */
|
|
885
|
+
restoreReloadSnapshot(snapshot) {
|
|
886
|
+
this.globalSettings = structuredClone(snapshot.globalSettings);
|
|
887
|
+
this.projectSettings = structuredClone(snapshot.projectSettings);
|
|
888
|
+
this.directoryProfileSettings = structuredClone(snapshot.directoryProfileSettings);
|
|
889
|
+
this.runtimeResourceProfiles =
|
|
890
|
+
snapshot.runtimeResourceProfiles === undefined ? undefined : [...snapshot.runtimeResourceProfiles];
|
|
891
|
+
this.inlineResourceProfileDefinitions = structuredClone(snapshot.inlineResourceProfileDefinitions);
|
|
892
|
+
this.discoveredResourceProfileDefinitions = structuredClone(snapshot.discoveredResourceProfileDefinitions);
|
|
893
|
+
this.settings = structuredClone(snapshot.effectiveSettings);
|
|
894
|
+
this.projectTrusted = snapshot.projectTrusted;
|
|
895
|
+
this.modifiedFields = new Set(snapshot.modifiedFields);
|
|
896
|
+
this.modifiedNestedFields = this.cloneModifiedNestedFields(snapshot.modifiedNestedFields);
|
|
897
|
+
this.modifiedProjectFields = new Set(snapshot.modifiedProjectFields);
|
|
898
|
+
this.modifiedProjectNestedFields = this.cloneModifiedNestedFields(snapshot.modifiedProjectNestedFields);
|
|
899
|
+
this.globalSettingsLoadError = snapshot.globalSettingsLoadError;
|
|
900
|
+
this.projectSettingsLoadError = snapshot.projectSettingsLoadError;
|
|
901
|
+
this.directoryProfileInfo = snapshot.directoryProfileInfo ? { ...snapshot.directoryProfileInfo } : null;
|
|
902
|
+
this.errors = [...snapshot.errors];
|
|
903
|
+
this.refreshProfileRegistry();
|
|
904
|
+
}
|
|
830
905
|
/** Apply additional overrides on top of current settings */
|
|
831
906
|
applyOverrides(overrides) {
|
|
832
907
|
this.settings = deepMergeSettings(this.settings, overrides);
|
|
833
908
|
}
|
|
834
909
|
/** Select runtime-only resource profiles, e.g. from CLI/subagent launch options. */
|
|
835
910
|
setRuntimeResourceProfiles(profileNames) {
|
|
836
|
-
this.runtimeResourceProfiles = profileNames
|
|
911
|
+
this.runtimeResourceProfiles = normalizeResourceProfileNames(profileNames);
|
|
837
912
|
this.recomputeSettings();
|
|
838
913
|
}
|
|
839
914
|
/** Add one-shot profile definitions from CLI/SDK/ephemeral agent launch input. Never writes to disk. */
|
|
840
915
|
addInlineResourceProfileDefinitions(profiles) {
|
|
841
|
-
|
|
916
|
+
const next = { ...this.inlineResourceProfileDefinitions };
|
|
917
|
+
for (const [name, input] of Object.entries(profiles)) {
|
|
918
|
+
const existing = next[name];
|
|
919
|
+
const definition = Object.hasOwn(input, "resources")
|
|
920
|
+
? input
|
|
921
|
+
: { resources: input };
|
|
922
|
+
const resources = mergeResourceProfileSettings(existing?.resources, definition.resources);
|
|
923
|
+
next[name] = this.mergeProfileDefinition(name, definition, resources, existing);
|
|
924
|
+
}
|
|
925
|
+
this.inlineResourceProfileDefinitions = next;
|
|
842
926
|
this.refreshProfileRegistry();
|
|
843
927
|
}
|
|
844
928
|
/** Replace profile definitions discovered inside loaded resource files. Never writes to disk. */
|
|
@@ -862,6 +946,13 @@ export class SettingsManager {
|
|
|
862
946
|
}
|
|
863
947
|
return trimmed;
|
|
864
948
|
}
|
|
949
|
+
normalizeProfileSelection(profileName) {
|
|
950
|
+
const trimmed = profileName.trim();
|
|
951
|
+
if (trimmed.startsWith("./") || trimmed.startsWith("../")) {
|
|
952
|
+
return trimmed;
|
|
953
|
+
}
|
|
954
|
+
return this.normalizeProfileName(trimmed);
|
|
955
|
+
}
|
|
865
956
|
sanitizeProfileResources(resources) {
|
|
866
957
|
const result = {};
|
|
867
958
|
for (const kind of ["extensions", "skills", "prompts", "themes", "agents", "tools"]) {
|
|
@@ -876,15 +967,94 @@ export class SettingsManager {
|
|
|
876
967
|
}
|
|
877
968
|
return result;
|
|
878
969
|
}
|
|
970
|
+
decodeStoredProfileDefinition(name, stored) {
|
|
971
|
+
if (stored && Object.hasOwn(stored, "resources")) {
|
|
972
|
+
const definition = stored;
|
|
973
|
+
return { ...definition, name, resources: this.sanitizeProfileResources(definition.resources) };
|
|
974
|
+
}
|
|
975
|
+
return {
|
|
976
|
+
name,
|
|
977
|
+
resources: this.sanitizeProfileResources(stored ?? {}),
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
mergeProfileDefinition(name, definition, resources, existing) {
|
|
981
|
+
const previous = this.decodeStoredProfileDefinition(name, existing);
|
|
982
|
+
return {
|
|
983
|
+
...previous,
|
|
984
|
+
name,
|
|
985
|
+
resources,
|
|
986
|
+
description: definition.description ?? previous.description,
|
|
987
|
+
model: definition.model ?? previous.model,
|
|
988
|
+
thinking: definition.thinking ?? previous.thinking,
|
|
989
|
+
modelRouter: definition.modelRouter ?? previous.modelRouter,
|
|
990
|
+
soul: definition.soul ?? previous.soul,
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
encodeStoredProfileDefinition(definition) {
|
|
994
|
+
const hasMetadata = Boolean(definition.description || definition.model || definition.thinking || definition.modelRouter || definition.soul);
|
|
995
|
+
if (hasMetadata)
|
|
996
|
+
return definition;
|
|
997
|
+
return Object.keys(definition.resources).length > 0 ? definition.resources : undefined;
|
|
998
|
+
}
|
|
879
999
|
setActiveProfileInSettings(settings, profileName) {
|
|
880
1000
|
if (profileName) {
|
|
881
1001
|
settings.activeResourceProfile = profileName;
|
|
882
1002
|
settings.activeResourceProfiles = [profileName];
|
|
883
1003
|
return;
|
|
884
1004
|
}
|
|
885
|
-
|
|
1005
|
+
settings.activeResourceProfiles = [];
|
|
886
1006
|
delete settings.activeResourceProfile;
|
|
887
1007
|
}
|
|
1008
|
+
rewriteActiveProfileReference(settings, oldName, newName) {
|
|
1009
|
+
let changed = false;
|
|
1010
|
+
const rewrite = (values) => {
|
|
1011
|
+
const next = values.flatMap((value) => {
|
|
1012
|
+
if (value !== oldName)
|
|
1013
|
+
return [value];
|
|
1014
|
+
changed = true;
|
|
1015
|
+
return newName ? [newName] : [];
|
|
1016
|
+
});
|
|
1017
|
+
return [...new Set(next)];
|
|
1018
|
+
};
|
|
1019
|
+
if (settings.activeResourceProfiles !== undefined) {
|
|
1020
|
+
const next = rewrite(normalizeResourceProfileNames(settings.activeResourceProfiles));
|
|
1021
|
+
if (next.length > 0)
|
|
1022
|
+
settings.activeResourceProfiles = next;
|
|
1023
|
+
else
|
|
1024
|
+
delete settings.activeResourceProfiles;
|
|
1025
|
+
}
|
|
1026
|
+
if (settings.activeResourceProfile !== undefined) {
|
|
1027
|
+
const next = rewrite(normalizeResourceProfileNames(settings.activeResourceProfile));
|
|
1028
|
+
if (next.length === 0)
|
|
1029
|
+
delete settings.activeResourceProfile;
|
|
1030
|
+
else
|
|
1031
|
+
settings.activeResourceProfile =
|
|
1032
|
+
Array.isArray(settings.activeResourceProfile) || next.length > 1 ? next : next[0];
|
|
1033
|
+
}
|
|
1034
|
+
return changed;
|
|
1035
|
+
}
|
|
1036
|
+
rewriteReusableProfileSelections(oldName, newName) {
|
|
1037
|
+
if (this.runtimeResourceProfiles?.includes(oldName)) {
|
|
1038
|
+
this.runtimeResourceProfiles = [
|
|
1039
|
+
...new Set(this.runtimeResourceProfiles.flatMap((profile) => profile === oldName ? (newName ? [newName] : []) : [profile])),
|
|
1040
|
+
];
|
|
1041
|
+
}
|
|
1042
|
+
if (this.rewriteActiveProfileReference(this.globalSettings, oldName, newName)) {
|
|
1043
|
+
this.markModified("activeResourceProfile");
|
|
1044
|
+
this.markModified("activeResourceProfiles");
|
|
1045
|
+
this.save();
|
|
1046
|
+
}
|
|
1047
|
+
const projectSettings = structuredClone(this.projectSettings);
|
|
1048
|
+
if (this.rewriteActiveProfileReference(projectSettings, oldName, newName)) {
|
|
1049
|
+
this.markProjectModified("activeResourceProfile");
|
|
1050
|
+
this.markProjectModified("activeResourceProfiles");
|
|
1051
|
+
this.saveProjectSettings(projectSettings);
|
|
1052
|
+
}
|
|
1053
|
+
if (this.rewriteActiveProfileReference(this.directoryProfileSettings, oldName, newName)) {
|
|
1054
|
+
this.persistDirectoryProfiles(() => { });
|
|
1055
|
+
}
|
|
1056
|
+
this.recomputeSettings();
|
|
1057
|
+
}
|
|
888
1058
|
persistDirectoryProfiles(update) {
|
|
889
1059
|
const next = structuredClone(this.directoryProfileSettings);
|
|
890
1060
|
update(next);
|
|
@@ -932,8 +1102,9 @@ export class SettingsManager {
|
|
|
932
1102
|
const resources = this.sanitizeProfileResources(definition.resources);
|
|
933
1103
|
if (scope === "session") {
|
|
934
1104
|
const next = { ...this.inlineResourceProfileDefinitions };
|
|
935
|
-
|
|
936
|
-
|
|
1105
|
+
const payload = this.mergeProfileDefinition(name, definition, resources, next[name]);
|
|
1106
|
+
if (this.encodeStoredProfileDefinition(payload)) {
|
|
1107
|
+
next[name] = payload;
|
|
937
1108
|
}
|
|
938
1109
|
else {
|
|
939
1110
|
delete next[name];
|
|
@@ -945,8 +1116,9 @@ export class SettingsManager {
|
|
|
945
1116
|
if (scope === "global") {
|
|
946
1117
|
const next = structuredClone(this.globalSettings);
|
|
947
1118
|
next.resourceProfiles = { ...(next.resourceProfiles ?? {}) };
|
|
948
|
-
|
|
949
|
-
|
|
1119
|
+
const stored = this.encodeStoredProfileDefinition(this.mergeProfileDefinition(name, definition, resources, next.resourceProfiles[name]));
|
|
1120
|
+
if (stored) {
|
|
1121
|
+
next.resourceProfiles[name] = stored;
|
|
950
1122
|
}
|
|
951
1123
|
else {
|
|
952
1124
|
delete next.resourceProfiles[name];
|
|
@@ -962,8 +1134,9 @@ export class SettingsManager {
|
|
|
962
1134
|
if (scope === "project") {
|
|
963
1135
|
this.updateProjectSettings("resourceProfiles", (settings) => {
|
|
964
1136
|
const next = structuredClone(settings.resourceProfiles ?? {});
|
|
965
|
-
|
|
966
|
-
|
|
1137
|
+
const stored = this.encodeStoredProfileDefinition(this.mergeProfileDefinition(name, definition, resources, next[name]));
|
|
1138
|
+
if (stored) {
|
|
1139
|
+
next[name] = stored;
|
|
967
1140
|
}
|
|
968
1141
|
else {
|
|
969
1142
|
delete next[name];
|
|
@@ -980,8 +1153,9 @@ export class SettingsManager {
|
|
|
980
1153
|
if (scope === "directory") {
|
|
981
1154
|
this.persistDirectoryProfiles((current) => {
|
|
982
1155
|
const next = { ...(current.resourceProfiles ?? {}) };
|
|
983
|
-
|
|
984
|
-
|
|
1156
|
+
const stored = this.encodeStoredProfileDefinition(this.mergeProfileDefinition(name, definition, resources, next[name]));
|
|
1157
|
+
if (stored) {
|
|
1158
|
+
next[name] = stored;
|
|
985
1159
|
}
|
|
986
1160
|
else {
|
|
987
1161
|
delete next[name];
|
|
@@ -997,17 +1171,9 @@ export class SettingsManager {
|
|
|
997
1171
|
}
|
|
998
1172
|
const path = this.getProfileFilePath(name);
|
|
999
1173
|
const existing = existsSync(path)
|
|
1000
|
-
? parseProfileFileDefinition(readFileSync(path, "utf-8"))
|
|
1174
|
+
? parseProfileFileDefinition(readFileSync(path, "utf-8"), name)
|
|
1001
1175
|
: { name, resources: {} };
|
|
1002
|
-
const payload =
|
|
1003
|
-
...existing,
|
|
1004
|
-
name,
|
|
1005
|
-
resources,
|
|
1006
|
-
description: definition.description ?? existing.description,
|
|
1007
|
-
model: definition.model ?? existing.model,
|
|
1008
|
-
thinking: definition.thinking ?? existing.thinking,
|
|
1009
|
-
modelRouter: definition.modelRouter ?? existing.modelRouter,
|
|
1010
|
-
};
|
|
1176
|
+
const payload = this.mergeProfileDefinition(name, definition, resources, existing);
|
|
1011
1177
|
mkdirSync(dirname(path), { recursive: true });
|
|
1012
1178
|
writeFileSync(path, JSON.stringify(payload, null, 2), "utf-8");
|
|
1013
1179
|
}
|
|
@@ -1097,6 +1263,7 @@ export class SettingsManager {
|
|
|
1097
1263
|
throw new Error(`Profile not found: ${name}`);
|
|
1098
1264
|
}
|
|
1099
1265
|
rmSync(profilePath, { force: true });
|
|
1266
|
+
this.rewriteReusableProfileSelections(name, undefined);
|
|
1100
1267
|
}
|
|
1101
1268
|
renameProfile(profileName, newProfileName, scope) {
|
|
1102
1269
|
const oldName = this.normalizeProfileName(profileName);
|
|
@@ -1191,16 +1358,17 @@ export class SettingsManager {
|
|
|
1191
1358
|
if (existsSync(newPath)) {
|
|
1192
1359
|
throw new Error(`Profile already exists: ${newName}`);
|
|
1193
1360
|
}
|
|
1194
|
-
const parsed = parseProfileFileDefinition(readFileSync(oldPath, "utf-8"));
|
|
1361
|
+
const parsed = parseProfileFileDefinition(readFileSync(oldPath, "utf-8"), oldName);
|
|
1195
1362
|
parsed.name = newName;
|
|
1196
1363
|
writeFileSync(newPath, JSON.stringify(parsed, null, 2), "utf-8");
|
|
1197
1364
|
rmSync(oldPath, { force: true });
|
|
1365
|
+
this.rewriteReusableProfileSelections(oldName, newName);
|
|
1198
1366
|
}
|
|
1199
1367
|
/**
|
|
1200
1368
|
* Set active profile selection in the selected scope.
|
|
1201
1369
|
*/
|
|
1202
1370
|
setActiveProfile(profileName, scope) {
|
|
1203
|
-
const name = profileName ? this.
|
|
1371
|
+
const name = profileName ? this.normalizeProfileSelection(profileName) : undefined;
|
|
1204
1372
|
if (scope === "session") {
|
|
1205
1373
|
if (name) {
|
|
1206
1374
|
this.setRuntimeResourceProfiles([name]);
|
|
@@ -1217,7 +1385,7 @@ export class SettingsManager {
|
|
|
1217
1385
|
}
|
|
1218
1386
|
else {
|
|
1219
1387
|
delete this.globalSettings.activeResourceProfile;
|
|
1220
|
-
|
|
1388
|
+
this.globalSettings.activeResourceProfiles = [];
|
|
1221
1389
|
}
|
|
1222
1390
|
this.markModified("activeResourceProfile");
|
|
1223
1391
|
this.markModified("activeResourceProfiles");
|
|
@@ -1234,6 +1402,67 @@ export class SettingsManager {
|
|
|
1234
1402
|
this.setActiveProfileInSettings(current, name);
|
|
1235
1403
|
});
|
|
1236
1404
|
}
|
|
1405
|
+
/** Atomically replace the global profile/authority fields used by config restore and rollback. */
|
|
1406
|
+
replaceGlobalResourceProfileConfiguration(configuration) {
|
|
1407
|
+
const next = structuredClone(this.globalSettings);
|
|
1408
|
+
const replace = (key) => {
|
|
1409
|
+
const value = configuration[key];
|
|
1410
|
+
if (value === undefined) {
|
|
1411
|
+
delete next[key];
|
|
1412
|
+
}
|
|
1413
|
+
else {
|
|
1414
|
+
next[key] = structuredClone(value);
|
|
1415
|
+
}
|
|
1416
|
+
this.markModified(key);
|
|
1417
|
+
};
|
|
1418
|
+
replace("resourceProfiles");
|
|
1419
|
+
replace("activeResourceProfile");
|
|
1420
|
+
replace("activeResourceProfiles");
|
|
1421
|
+
replace("externalResourceRoots");
|
|
1422
|
+
replace("trustedResourceRoots");
|
|
1423
|
+
this.globalSettings = next;
|
|
1424
|
+
this.save();
|
|
1425
|
+
}
|
|
1426
|
+
/** Restore one profile definition's persistent owner after a post-doctor commit failure. */
|
|
1427
|
+
restoreProfileDefinitionFromReloadSnapshot(profileName, scope, snapshot) {
|
|
1428
|
+
const name = this.normalizeProfileName(profileName);
|
|
1429
|
+
if (scope === "session") {
|
|
1430
|
+
const previous = snapshot.inlineResourceProfileDefinitions[name];
|
|
1431
|
+
if (previous)
|
|
1432
|
+
this.inlineResourceProfileDefinitions[name] = structuredClone(previous);
|
|
1433
|
+
else
|
|
1434
|
+
delete this.inlineResourceProfileDefinitions[name];
|
|
1435
|
+
this.refreshProfileRegistry();
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
const restoreDefinition = (settings, previous) => {
|
|
1439
|
+
const definitions = structuredClone(settings.resourceProfiles ?? {});
|
|
1440
|
+
const oldDefinition = previous.resourceProfiles?.[name];
|
|
1441
|
+
if (oldDefinition)
|
|
1442
|
+
definitions[name] = structuredClone(oldDefinition);
|
|
1443
|
+
else
|
|
1444
|
+
delete definitions[name];
|
|
1445
|
+
if (Object.keys(definitions).length > 0)
|
|
1446
|
+
settings.resourceProfiles = definitions;
|
|
1447
|
+
else
|
|
1448
|
+
delete settings.resourceProfiles;
|
|
1449
|
+
};
|
|
1450
|
+
if (scope === "global") {
|
|
1451
|
+
restoreDefinition(this.globalSettings, snapshot.globalSettings);
|
|
1452
|
+
this.markModified("resourceProfiles");
|
|
1453
|
+
this.save();
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1456
|
+
if (scope === "project") {
|
|
1457
|
+
this.updateProjectSettings("resourceProfiles", (settings) => {
|
|
1458
|
+
restoreDefinition(settings, snapshot.projectSettings);
|
|
1459
|
+
});
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
this.persistDirectoryProfiles((settings) => {
|
|
1463
|
+
restoreDefinition(settings, snapshot.directoryProfileSettings);
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1237
1466
|
/** Mark a global field as modified during this session */
|
|
1238
1467
|
markModified(field, nestedKey) {
|
|
1239
1468
|
this.modifiedFields.add(field);
|
|
@@ -1479,7 +1708,7 @@ export class SettingsManager {
|
|
|
1479
1708
|
}
|
|
1480
1709
|
/**
|
|
1481
1710
|
* Proactive per-turn cost guard (#34). Default ON in WARN-only mode with a high anomaly-catching
|
|
1482
|
-
*
|
|
1711
|
+
* projection threshold so an unusually expensive turn surfaces a visible footer notice without silently
|
|
1483
1712
|
* changing behavior. Set `maxTurnUsd: 0` to disable, or `action: "downgrade"` to also auto-reduce
|
|
1484
1713
|
* reasoning effort over the ceiling.
|
|
1485
1714
|
*/
|
|
@@ -1496,14 +1725,19 @@ export class SettingsManager {
|
|
|
1496
1725
|
const activeProfileNames = this.getActiveResourceProfileNames();
|
|
1497
1726
|
if (activeProfileNames.length === 0)
|
|
1498
1727
|
return undefined;
|
|
1728
|
+
const registry = this.getProfileRegistry();
|
|
1499
1729
|
const merged = {};
|
|
1500
1730
|
for (let index = activeProfileNames.length - 1; index >= 0; index--) {
|
|
1501
|
-
const profile = this.
|
|
1731
|
+
const profile = this.resolveProfileFromRegistry(registry, activeProfileNames[index]);
|
|
1502
1732
|
const router = profile?.modelRouter;
|
|
1503
1733
|
if (!router)
|
|
1504
1734
|
continue;
|
|
1505
1735
|
if (router.enabled !== undefined)
|
|
1506
1736
|
merged.enabled = router.enabled;
|
|
1737
|
+
if (router.judgeEnabled !== undefined)
|
|
1738
|
+
merged.judgeEnabled = router.judgeEnabled;
|
|
1739
|
+
if (router.fitnessGate !== undefined)
|
|
1740
|
+
merged.fitnessGate = router.fitnessGate;
|
|
1507
1741
|
if (router.cheapModel !== undefined)
|
|
1508
1742
|
merged.cheapModel = router.cheapModel;
|
|
1509
1743
|
if (router.mediumModel !== undefined)
|
|
@@ -1512,6 +1746,20 @@ export class SettingsManager {
|
|
|
1512
1746
|
merged.expensiveModel = router.expensiveModel;
|
|
1513
1747
|
if (router.learningModel !== undefined)
|
|
1514
1748
|
merged.learningModel = router.learningModel;
|
|
1749
|
+
if (router.judgeModel !== undefined)
|
|
1750
|
+
merged.judgeModel = router.judgeModel;
|
|
1751
|
+
if (router.executorModel !== undefined)
|
|
1752
|
+
merged.executorModel = router.executorModel;
|
|
1753
|
+
if (router.cheapThinking !== undefined)
|
|
1754
|
+
merged.cheapThinking = router.cheapThinking;
|
|
1755
|
+
if (router.mediumThinking !== undefined)
|
|
1756
|
+
merged.mediumThinking = router.mediumThinking;
|
|
1757
|
+
if (router.expensiveThinking !== undefined)
|
|
1758
|
+
merged.expensiveThinking = router.expensiveThinking;
|
|
1759
|
+
if (router.executorThinking !== undefined)
|
|
1760
|
+
merged.executorThinking = router.executorThinking;
|
|
1761
|
+
if (router.judgeThinking !== undefined)
|
|
1762
|
+
merged.judgeThinking = router.judgeThinking;
|
|
1515
1763
|
}
|
|
1516
1764
|
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
1517
1765
|
}
|
|
@@ -1527,8 +1775,6 @@ export class SettingsManager {
|
|
|
1527
1775
|
fitnessGate: this.settings.modelRouter?.fitnessGate ?? false,
|
|
1528
1776
|
judgeModel: this.settings.modelRouter?.judgeModel?.trim() || undefined,
|
|
1529
1777
|
executorModel: this.settings.modelRouter?.executorModel?.trim() || undefined,
|
|
1530
|
-
// Not yet profile-overridable (same as judgeModel/executorModel above): validated here so a
|
|
1531
|
-
// corrupt/hand-edited value on disk never reaches the routed-turn swap in agent-session.ts.
|
|
1532
1778
|
cheapThinking: isThinkingLevel(this.settings.modelRouter?.cheapThinking)
|
|
1533
1779
|
? this.settings.modelRouter?.cheapThinking
|
|
1534
1780
|
: undefined,
|
|
@@ -1555,11 +1801,11 @@ export class SettingsManager {
|
|
|
1555
1801
|
fitnessGate: profileSettings?.fitnessGate ?? settings.fitnessGate,
|
|
1556
1802
|
judgeModel: profileSettings?.judgeModel?.trim() || settings.judgeModel,
|
|
1557
1803
|
executorModel: profileSettings?.executorModel?.trim() || settings.executorModel,
|
|
1558
|
-
cheapThinking: settings.cheapThinking,
|
|
1559
|
-
mediumThinking: settings.mediumThinking,
|
|
1560
|
-
expensiveThinking: settings.expensiveThinking,
|
|
1561
|
-
executorThinking: settings.executorThinking,
|
|
1562
|
-
judgeThinking: settings.judgeThinking,
|
|
1804
|
+
cheapThinking: profileSettings?.cheapThinking ?? settings.cheapThinking,
|
|
1805
|
+
mediumThinking: profileSettings?.mediumThinking ?? settings.mediumThinking,
|
|
1806
|
+
expensiveThinking: profileSettings?.expensiveThinking ?? settings.expensiveThinking,
|
|
1807
|
+
executorThinking: profileSettings?.executorThinking ?? settings.executorThinking,
|
|
1808
|
+
judgeThinking: profileSettings?.judgeThinking ?? settings.judgeThinking,
|
|
1563
1809
|
};
|
|
1564
1810
|
}
|
|
1565
1811
|
setModelRouterSettings(settings, scope = "global") {
|
|
@@ -1641,6 +1887,7 @@ export class SettingsManager {
|
|
|
1641
1887
|
"automata_graph_pointer_pack",
|
|
1642
1888
|
"learning_query_memory",
|
|
1643
1889
|
"subagent",
|
|
1890
|
+
"delegate",
|
|
1644
1891
|
"task_steps",
|
|
1645
1892
|
"task_background",
|
|
1646
1893
|
"task_goal",
|
|
@@ -1710,9 +1957,10 @@ export class SettingsManager {
|
|
|
1710
1957
|
}
|
|
1711
1958
|
getMemoryRetrievalSettings() {
|
|
1712
1959
|
return {
|
|
1713
|
-
enabled: this.settings.contextPolicy?.memory?.enabled ??
|
|
1960
|
+
enabled: this.settings.contextPolicy?.memory?.enabled ?? true,
|
|
1714
1961
|
maxResults: clampMemoryRetrievalMaxResults(this.settings.contextPolicy?.memory?.maxResults ?? MEMORY_RETRIEVAL_MAX_RESULTS_DEFAULT),
|
|
1715
|
-
includeInPrompt: this.settings.contextPolicy?.memory?.includeInPrompt ??
|
|
1962
|
+
includeInPrompt: this.settings.contextPolicy?.memory?.includeInPrompt ?? true,
|
|
1963
|
+
allowExternalEgress: this.settings.contextPolicy?.memory?.allowExternalEgress === true,
|
|
1716
1964
|
};
|
|
1717
1965
|
}
|
|
1718
1966
|
setMemoryRetrievalSettings(settings, scope = "global") {
|
|
@@ -1720,6 +1968,7 @@ export class SettingsManager {
|
|
|
1720
1968
|
enabled: settings.enabled,
|
|
1721
1969
|
maxResults: settings.maxResults === undefined ? undefined : clampMemoryRetrievalMaxResults(settings.maxResults),
|
|
1722
1970
|
includeInPrompt: settings.includeInPrompt,
|
|
1971
|
+
allowExternalEgress: settings.allowExternalEgress,
|
|
1723
1972
|
};
|
|
1724
1973
|
if (scope === "project") {
|
|
1725
1974
|
const projectSettings = structuredClone(this.projectSettings);
|