@hassangameryt/freeflow 0.7.1 → 0.7.3
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +153 -128
- package/capabilities/cognitive-routing/SKILL.md +126 -274
- package/command-surface.json +7 -1
- package/gemini-extension.json +1 -1
- package/package.json +4 -4
- package/pi-extension/dist/cognitive-routing-v2/budget.js +42 -0
- package/pi-extension/dist/cognitive-routing-v2/config.js +136 -0
- package/pi-extension/dist/cognitive-routing-v2/projection.js +330 -0
- package/pi-extension/dist/cognitive-routing-v2/render.js +252 -0
- package/pi-extension/dist/cognitive-routing-v2/runtime.js +2181 -0
- package/pi-extension/dist/cognitive-routing-v2/schemas.js +173 -0
- package/pi-extension/dist/cognitive-routing-v2/state.js +828 -0
- package/pi-extension/dist/cognitive-routing-v2/tools.js +60 -0
- package/pi-extension/dist/cognitive-routing-v2/types.js +48 -0
- package/pi-extension/dist/context-virtualization/runtime.js +29 -7
- package/pi-extension/dist/freeflow-context/tool.js +12 -6
- package/pi-extension/dist/index.js +302 -626
- package/pi-extension/dist/provider-support/astra/adapter.js +110 -0
- package/pi-extension/dist/provider-support/astra/history.js +125 -0
- package/pi-extension/dist/provider-support/astra/index.js +11 -0
- package/pi-extension/dist/provider-support/astra/session-state.js +114 -0
- package/pi-extension/dist/provider-support/index.js +4 -0
- package/pi-extension/dist/runtime/request-history.js +216 -0
- package/pi-extension/dist/runtime/runtime-context.js +85 -16
- package/pi-extension/dist/session-sources/events.js +217 -0
- package/pi-extension/dist/session-sources/provenance.js +32 -0
- package/pi-extension/dist/session-sources/read-only-session.js +148 -0
- package/pi-extension/dist/session-sources/sources.js +277 -0
- package/pi-extension/dist/settings/settings-ui.js +274 -147
- package/pi-extension/src/cognitive-routing-v2/budget.ts +42 -0
- package/pi-extension/src/cognitive-routing-v2/config.ts +173 -0
- package/pi-extension/src/cognitive-routing-v2/projection.ts +375 -0
- package/pi-extension/src/cognitive-routing-v2/render.ts +277 -0
- package/pi-extension/src/cognitive-routing-v2/runtime.ts +2241 -0
- package/pi-extension/src/cognitive-routing-v2/schemas.ts +180 -0
- package/pi-extension/src/cognitive-routing-v2/state.ts +839 -0
- package/pi-extension/src/cognitive-routing-v2/tools.ts +62 -0
- package/pi-extension/src/cognitive-routing-v2/types.ts +254 -0
- package/pi-extension/src/context-virtualization/runtime.ts +30 -8
- package/pi-extension/src/freeflow-context/tool.ts +12 -6
- package/pi-extension/src/index.ts +308 -675
- package/pi-extension/src/provider-support/astra/adapter.ts +108 -0
- package/pi-extension/src/provider-support/astra/history.ts +145 -0
- package/pi-extension/src/provider-support/astra/index.ts +12 -0
- package/pi-extension/src/provider-support/astra/session-state.ts +113 -0
- package/pi-extension/src/provider-support/index.ts +5 -0
- package/pi-extension/src/runtime/request-history.ts +243 -0
- package/pi-extension/src/runtime/runtime-context.ts +100 -17
- package/pi-extension/src/session-sources/events.ts +230 -0
- package/pi-extension/src/session-sources/provenance.ts +39 -0
- package/pi-extension/src/session-sources/read-only-session.ts +170 -0
- package/pi-extension/src/session-sources/sources.ts +334 -0
- package/pi-extension/src/settings/settings-ui.ts +311 -158
- package/pi-extension/tests/cache-reuse/history.test.js +117 -0
- package/pi-extension/tests/cache-reuse/native.test.js +91 -0
- package/pi-extension/tests/cache-reuse/settings.test.js +211 -0
- package/pi-extension/tests/cognitive-routing-v2/communication.test.js +577 -0
- package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +183 -0
- package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +557 -0
- package/pi-extension/tests/cognitive-routing-v2/native.test.js +474 -0
- package/pi-extension/tests/cognitive-routing-v2/performance.test.js +87 -0
- package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +300 -0
- package/pi-extension/tests/cognitive-routing-v2/projection.test.js +241 -0
- package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +1034 -0
- package/pi-extension/tests/cognitive-routing-v2/render.test.js +244 -0
- package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +423 -0
- package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +521 -0
- package/pi-extension/tests/cognitive-routing-v2/state.test.js +586 -0
- package/pi-extension/tests/context-virtualization/extension.test.js +33 -7
- package/pi-extension/tests/context-virtualization/runtime.test.js +17 -3
- package/pi-extension/tests/fixtures/routing-native.js +191 -0
- package/pi-extension/tests/integration/mode-free-core.test.js +6 -4
- package/pi-extension/tests/integration/pi-extension.test.js +655 -59
- package/pi-extension/tests/integration/prompt-architecture.test.js +127 -30
- package/pi-extension/tests/integration/unaffected-regressions.test.js +78 -11
- package/pi-extension/tests/provider-support/astra-boundaries.test.js +75 -0
- package/pi-extension/tests/provider-support/astra.test.js +306 -0
- package/pi-extension/tests/provider-support/cli.test.js +92 -0
- package/pi-extension/tests/provider-support/native.test.js +183 -0
- package/plugin.json +1 -1
- package/runtime/prompts/cognitive-routing.md +4 -5
- package/runtime/prompts/core.md +51 -45
- package/runtime/prompts/interaction-contract.md +5 -5
- package/skills/action-selection/SKILL.md +57 -97
- package/skills/design-for-depth/SKILL.md +58 -193
- package/skills/design-for-depth/references/implementation-decisions.md +76 -0
- package/skills/diagnose-failure/SKILL.md +64 -196
- package/skills/discuss/SKILL.md +64 -123
- package/skills/discuss/references/discussion-continuity.md +7 -3
- package/skills/execute-work/SKILL.md +69 -88
- package/skills/execute-work/references/execute-work-edges.md +9 -3
- package/skills/handoff/SKILL.md +44 -54
- package/skills/handoff/references/handoff-templates.md +15 -6
- package/skills/review-artifact/SKILL.md +80 -127
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +1 -1
- package/skills/review-work/SKILL.md +65 -115
- package/skills/review-work/references/independent-work-reviewer-contract.md +1 -1
- package/skills/simplify-code/SKILL.md +47 -100
- package/skills/track-work/SKILL.md +128 -119
- package/skills/track-work/references/working-record-format.md +14 -2
- package/skills/verify-work/SKILL.md +58 -62
- package/skills/verify-work/references/integration-evidence.md +4 -2
- package/skills/verify-work/references/test-design.md +89 -0
- package/skills/workflow/SKILL.md +73 -119
- package/skills/write-plan/SKILL.md +46 -77
- package/skills/write-plan/references/plan-shapes.md +5 -5
- package/skills/write-spec/SKILL.md +51 -63
- package/skills/write-spec/references/artifact-standards.md +2 -2
- package/skills/write-spec/references/decision-records.md +3 -2
- package/skills/write-spec/references/spec-shapes.md +15 -0
- package/pi-extension/dist/cognitive-routing/commands.js +0 -96
- package/pi-extension/dist/cognitive-routing/config.js +0 -232
- package/pi-extension/dist/cognitive-routing/controller.js +0 -1292
- package/pi-extension/dist/cognitive-routing/history.js +0 -451
- package/pi-extension/dist/cognitive-routing/host.js +0 -188
- package/pi-extension/dist/cognitive-routing/pi-routing-session.js +0 -414
- package/pi-extension/dist/cognitive-routing/pi-session-control.js +0 -320
- package/pi-extension/dist/cognitive-routing/runtime.js +0 -43
- package/pi-extension/dist/cognitive-routing/tool.js +0 -212
- package/pi-extension/dist/cognitive-routing/types.js +0 -6
- package/pi-extension/src/cognitive-routing/commands.ts +0 -129
- package/pi-extension/src/cognitive-routing/config.ts +0 -303
- package/pi-extension/src/cognitive-routing/controller.ts +0 -1628
- package/pi-extension/src/cognitive-routing/history.ts +0 -650
- package/pi-extension/src/cognitive-routing/host.ts +0 -266
- package/pi-extension/src/cognitive-routing/pi-routing-session.ts +0 -538
- package/pi-extension/src/cognitive-routing/pi-session-control.ts +0 -444
- package/pi-extension/src/cognitive-routing/runtime.ts +0 -57
- package/pi-extension/src/cognitive-routing/tool.ts +0 -273
- package/pi-extension/src/cognitive-routing/types.ts +0 -89
- package/pi-extension/tests/cognitive-routing/commands.test.js +0 -134
- package/pi-extension/tests/cognitive-routing/controller.test.js +0 -1128
- package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +0 -1142
- package/pi-extension/tests/cognitive-routing/history.test.js +0 -274
- package/pi-extension/tests/cognitive-routing/host-identity.test.js +0 -63
- package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +0 -434
- package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +0 -174
- package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +0 -91
- package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +0 -279
- package/pi-extension/tests/cognitive-routing/tool.test.js +0 -230
- package/skills/tdd/SKILL.md +0 -143
- package/skills/tdd/references/test-design.md +0 -96
- /package/pi-extension/tests/{cognitive-routing/host-fixture.js → fixtures/pi-host.js} +0 -0
|
@@ -19,14 +19,15 @@ import {
|
|
|
19
19
|
type SettingsWizard,
|
|
20
20
|
type SettingsWizardStep,
|
|
21
21
|
} from "./settings-tui.js";
|
|
22
|
-
import { supportsPiSessionModelStateApi } from "../cognitive-routing/pi-session-control.js";
|
|
23
22
|
import { isPiFlowHost } from "../runtime/runtime-identity.js";
|
|
24
23
|
import type {
|
|
25
24
|
CognitiveRoutingCapabilityState,
|
|
25
|
+
CognitiveRoutingDelegationMode,
|
|
26
26
|
CognitiveRoutingProfile,
|
|
27
27
|
CognitiveRoutingProfileName,
|
|
28
28
|
CognitiveRoutingThinkingLevel,
|
|
29
|
-
} from "../cognitive-routing/
|
|
29
|
+
} from "../cognitive-routing-v2/config.js";
|
|
30
|
+
import { isWorkerProfile, workersForDelegation } from "../cognitive-routing-v2/types.js";
|
|
30
31
|
|
|
31
32
|
const DEFAULT_FREEFLOW_ENABLED = true;
|
|
32
33
|
const DEFAULT_CONTEXT_VIRTUALIZATION_ENABLED = false;
|
|
@@ -68,10 +69,26 @@ type SettingsItem = {
|
|
|
68
69
|
transient?: boolean;
|
|
69
70
|
};
|
|
70
71
|
|
|
72
|
+
type SessionRoutingPair = {
|
|
73
|
+
provider: string;
|
|
74
|
+
modelId: string;
|
|
75
|
+
thinking: CognitiveRoutingThinkingLevel;
|
|
76
|
+
};
|
|
77
|
+
|
|
71
78
|
type CognitiveRoutingSettingsController = {
|
|
72
79
|
state(): { effective: boolean; controlMode: string; activeProfile?: string };
|
|
73
|
-
|
|
80
|
+
sessionProfileOverrides(): Partial<Record<CognitiveRoutingProfileName, SessionRoutingPair>>;
|
|
81
|
+
setManualProfile(
|
|
82
|
+
profile: CognitiveRoutingProfileName,
|
|
83
|
+
mechanism?: string,
|
|
84
|
+
): Promise<{ status: string; reason?: string }>;
|
|
74
85
|
setAutomaticControl(mechanism?: string): Promise<{ status: string; reason?: string }>;
|
|
86
|
+
setSessionProfileOverride(
|
|
87
|
+
profile: CognitiveRoutingProfileName,
|
|
88
|
+
override: SessionRoutingPair | null,
|
|
89
|
+
mechanism?: string,
|
|
90
|
+
): Promise<{ status: string; reason?: string }>;
|
|
91
|
+
resetSessionProfileOverrides(mechanism?: string): Promise<{ status: string; reason?: string }>;
|
|
75
92
|
};
|
|
76
93
|
|
|
77
94
|
type AfterChangeOptions = {
|
|
@@ -184,7 +201,7 @@ function effectiveItemValue(item: SettingsItem): SettingsValue | undefined {
|
|
|
184
201
|
function formatCoreValue(value: unknown): string {
|
|
185
202
|
if (typeof value === "boolean") return booleanValue(value);
|
|
186
203
|
if (isRecord(value) && typeof value.provider === "string" && typeof value.model === "string") {
|
|
187
|
-
const effort = typeof value.
|
|
204
|
+
const effort = typeof value.thinking === "string" ? ` · ${value.thinking}` : "";
|
|
188
205
|
return `${value.provider}/${value.model}${effort}`;
|
|
189
206
|
}
|
|
190
207
|
return String(value ?? "");
|
|
@@ -291,6 +308,79 @@ function createScopedBooleanItem(options: ScopedBooleanItemOptions): SettingsIte
|
|
|
291
308
|
return item;
|
|
292
309
|
}
|
|
293
310
|
|
|
311
|
+
function createScopedDelegationItem(options: {
|
|
312
|
+
scope: Exclude<ConfigScope, "session">;
|
|
313
|
+
rawConfig: Record<string, unknown>;
|
|
314
|
+
localConfig: Record<string, unknown>;
|
|
315
|
+
effectiveValue: CognitiveRoutingDelegationMode;
|
|
316
|
+
effectiveSource: ConfigSource;
|
|
317
|
+
}): SettingsItem {
|
|
318
|
+
const path = ["cognitiveRouting", "delegation"];
|
|
319
|
+
const repositoryValue = getPath(options.rawConfig, path);
|
|
320
|
+
const inheritedValue: CognitiveRoutingDelegationMode = ["executor", "helper", "both"].includes(
|
|
321
|
+
repositoryValue as string,
|
|
322
|
+
)
|
|
323
|
+
? (repositoryValue as CognitiveRoutingDelegationMode)
|
|
324
|
+
: "executor";
|
|
325
|
+
const inheritedSource: ConfigSource = repositoryValue === undefined ? "builtin" : "repository";
|
|
326
|
+
const localValue = getPath(options.localConfig, path);
|
|
327
|
+
const descriptions = {
|
|
328
|
+
executor: "Coordinator delegates assignments to Executor.",
|
|
329
|
+
helper: "Coordinator delegates supporting assignments to Helper and keeps production implementation.",
|
|
330
|
+
both: "Coordinator chooses Helper or Executor for each assignment.",
|
|
331
|
+
};
|
|
332
|
+
const item: SettingsItem =
|
|
333
|
+
options.scope === "local"
|
|
334
|
+
? {
|
|
335
|
+
id: "freeflow.cognitiveRouting.delegation",
|
|
336
|
+
label: "Delegation method",
|
|
337
|
+
description:
|
|
338
|
+
"Choose enabled workers for automatic routing. Inherit uses the repository value; this setting does not rank model presets.",
|
|
339
|
+
path,
|
|
340
|
+
kind: "enum",
|
|
341
|
+
value: ["executor", "helper", "both"].includes(localValue as string) ? localValue : LOCAL_INHERIT,
|
|
342
|
+
values: [LOCAL_INHERIT, "executor", "helper", "both"],
|
|
343
|
+
valueLabels: {
|
|
344
|
+
inherit: "Inherit repository",
|
|
345
|
+
executor: "Executor only",
|
|
346
|
+
helper: "Helper only",
|
|
347
|
+
both: "Helper and Executor",
|
|
348
|
+
},
|
|
349
|
+
valueDescriptions: {
|
|
350
|
+
inherit: `Use ${inheritedValue} from ${inheritedSource}.`,
|
|
351
|
+
...descriptions,
|
|
352
|
+
},
|
|
353
|
+
configScope: "local",
|
|
354
|
+
configValues: { inherit: undefined, executor: "executor", helper: "helper", both: "both" },
|
|
355
|
+
effectiveValue: options.effectiveValue,
|
|
356
|
+
effectiveSource: options.effectiveSource,
|
|
357
|
+
inheritedValue,
|
|
358
|
+
inheritedSource,
|
|
359
|
+
}
|
|
360
|
+
: {
|
|
361
|
+
id: "freeflow.cognitiveRouting.delegation",
|
|
362
|
+
label: "Delegation method",
|
|
363
|
+
description: "Choose enabled workers for automatic routing. This edits shared .freeflow/config.json.",
|
|
364
|
+
path,
|
|
365
|
+
kind: "enum",
|
|
366
|
+
value: inheritedValue,
|
|
367
|
+
values: ["executor", "helper", "both"],
|
|
368
|
+
valueLabels: {
|
|
369
|
+
executor: "Executor only",
|
|
370
|
+
helper: "Helper only",
|
|
371
|
+
both: "Helper and Executor",
|
|
372
|
+
},
|
|
373
|
+
valueDescriptions: descriptions,
|
|
374
|
+
defaultValue: "executor",
|
|
375
|
+
configScope: "repository",
|
|
376
|
+
effectiveValue: options.effectiveValue,
|
|
377
|
+
effectiveSource: options.effectiveSource,
|
|
378
|
+
localOverrideValue: ["executor", "helper", "both"].includes(localValue as string) ? localValue : undefined,
|
|
379
|
+
};
|
|
380
|
+
item.displaySuffix = coreDisplaySuffix(item);
|
|
381
|
+
return item;
|
|
382
|
+
}
|
|
383
|
+
|
|
294
384
|
function resolveSettingsCoreView(
|
|
295
385
|
rawConfig: Record<string, unknown>,
|
|
296
386
|
layers?: Awaited<ReturnType<typeof readFreeflowConfigLayers>>,
|
|
@@ -369,6 +459,7 @@ function createSessionBooleanItem(options: {
|
|
|
369
459
|
function sessionFreeflowItems(
|
|
370
460
|
state: Awaited<ReturnType<typeof readCapabilityState>>,
|
|
371
461
|
cognitiveRoutingController?: CognitiveRoutingSettingsController,
|
|
462
|
+
ctx?: any,
|
|
372
463
|
): SettingsItem[] {
|
|
373
464
|
const sessionOverrides = state.sessionOverrides as Record<string, boolean>;
|
|
374
465
|
const configured = state.configuredCoreConfig;
|
|
@@ -422,48 +513,79 @@ function sessionFreeflowItems(
|
|
|
422
513
|
conversationHistoryItem.inactive = freeflowInactive;
|
|
423
514
|
|
|
424
515
|
const cognitiveRoutingState = cognitiveRoutingController?.state();
|
|
516
|
+
const delegation = state.cognitiveRouting?.delegation ?? "executor";
|
|
517
|
+
const heldProfile = cognitiveRoutingState?.controlMode.startsWith("manual-")
|
|
518
|
+
? cognitiveRoutingState.activeProfile
|
|
519
|
+
: undefined;
|
|
520
|
+
const availableProfiles: CognitiveRoutingProfileName[] = ["coordinator", ...workersForDelegation(delegation)];
|
|
521
|
+
if (heldProfile === "coordinator" || isWorkerProfile(heldProfile)) availableProfiles.push(heldProfile);
|
|
522
|
+
const manualProfiles = [...new Set(availableProfiles)];
|
|
425
523
|
const cognitiveRoutingProfile =
|
|
426
|
-
|
|
427
|
-
? "standard"
|
|
428
|
-
: cognitiveRoutingState?.controlMode === "manual-reasoning"
|
|
429
|
-
? "reasoning"
|
|
430
|
-
: "auto";
|
|
524
|
+
heldProfile && manualProfiles.includes(heldProfile as CognitiveRoutingProfileName) ? heldProfile : "auto";
|
|
431
525
|
const cognitiveRoutingItem: SettingsItem | undefined = state.cognitiveRouting
|
|
432
526
|
? {
|
|
433
527
|
id: "freeflow.cognitiveRouting.profile",
|
|
434
528
|
label: "Cognitive Routing",
|
|
435
|
-
description: "Hold
|
|
529
|
+
description: "Hold an enabled profile manually or release the hold for automatic model control.",
|
|
436
530
|
kind: "enum",
|
|
437
531
|
value: cognitiveRoutingProfile,
|
|
438
|
-
values: ["auto",
|
|
439
|
-
valueLabels:
|
|
440
|
-
auto
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
reasoning: "Hold the reasoning profile until /freeflow profile auto.",
|
|
448
|
-
},
|
|
532
|
+
values: ["auto", ...manualProfiles],
|
|
533
|
+
valueLabels: Object.fromEntries([
|
|
534
|
+
["auto", "automatic"],
|
|
535
|
+
...manualProfiles.map((profile) => [profile, `manual · ${profile}`]),
|
|
536
|
+
]),
|
|
537
|
+
valueDescriptions: Object.fromEntries([
|
|
538
|
+
["auto", "Release the manual hold and return to Coordinator reconciliation."],
|
|
539
|
+
...manualProfiles.map((profile) => [profile, `Hold the ${profile} profile until /freeflow profile auto.`]),
|
|
540
|
+
]),
|
|
449
541
|
inactive: freeflowInactive || !state.cognitiveRouting.effective || cognitiveRoutingController === undefined,
|
|
450
542
|
runtimeInactive: state.cognitiveRouting.blockingReason?.code === "runtime_disabled",
|
|
451
543
|
displaySuffix: cognitiveRoutingState?.effective ? cognitiveRoutingProfile : "unavailable",
|
|
452
544
|
}
|
|
453
545
|
: undefined;
|
|
454
546
|
|
|
547
|
+
const sessionProfiles = cognitiveRoutingController?.sessionProfileOverrides();
|
|
548
|
+
const profileItems =
|
|
549
|
+
state.cognitiveRouting && cognitiveRoutingController
|
|
550
|
+
? manualProfiles.map((name) =>
|
|
551
|
+
cognitiveRoutingProfileItem({
|
|
552
|
+
name,
|
|
553
|
+
scope: "session",
|
|
554
|
+
rawConfig: {},
|
|
555
|
+
localConfig: {},
|
|
556
|
+
capabilityState: state.cognitiveRouting as CognitiveRoutingCapabilityState,
|
|
557
|
+
ctx,
|
|
558
|
+
sessionProfiles,
|
|
559
|
+
}),
|
|
560
|
+
)
|
|
561
|
+
: [];
|
|
562
|
+
const cognitiveRoutingPresets: SettingsItem | undefined = profileItems.length
|
|
563
|
+
? {
|
|
564
|
+
id: "freeflow.cognitiveRouting.presets",
|
|
565
|
+
label: "Cognitive Routing presets",
|
|
566
|
+
description: "Temporarily choose complete model/effort pairs for profiles enabled in this Pi session.",
|
|
567
|
+
kind: "group",
|
|
568
|
+
value: profileItems.some((item) => item.value !== LOCAL_INHERIT && item.value !== undefined),
|
|
569
|
+
displaySuffix: `${profileItems.filter((item) => item.value !== LOCAL_INHERIT && item.value !== undefined).length}/${profileItems.length} session overrides`,
|
|
570
|
+
inactive: freeflowInactive || !state.cognitiveRouting?.effective || cognitiveRoutingController === undefined,
|
|
571
|
+
children: profileItems,
|
|
572
|
+
}
|
|
573
|
+
: undefined;
|
|
574
|
+
|
|
455
575
|
return [
|
|
456
576
|
freeflowItem,
|
|
457
577
|
...(cognitiveRoutingItem ? [cognitiveRoutingItem] : []),
|
|
578
|
+
...(cognitiveRoutingPresets ? [cognitiveRoutingPresets] : []),
|
|
458
579
|
{
|
|
459
580
|
id: "freeflow.session.reset",
|
|
460
581
|
label: "Reset session overrides",
|
|
461
|
-
description:
|
|
582
|
+
description:
|
|
583
|
+
"Clear Freeflow, Context Virtualization, Conversation History, and routing profile overrides for this Pi session.",
|
|
462
584
|
kind: "enum",
|
|
463
585
|
value: "available",
|
|
464
586
|
values: ["reset"],
|
|
465
587
|
valueLabels: { reset: "Reset all session overrides" },
|
|
466
|
-
valueDescriptions: { reset: "Return every session setting to its configured value." },
|
|
588
|
+
valueDescriptions: { reset: "Return every session setting and routing preset to its configured value." },
|
|
467
589
|
format: () => "available",
|
|
468
590
|
transient: true,
|
|
469
591
|
},
|
|
@@ -517,8 +639,8 @@ function isCognitiveRoutingProfile(value: unknown): value is CognitiveRoutingPro
|
|
|
517
639
|
isRecord(value) &&
|
|
518
640
|
typeof value.provider === "string" &&
|
|
519
641
|
typeof value.model === "string" &&
|
|
520
|
-
typeof value.
|
|
521
|
-
COGNITIVE_ROUTING_THINKING_LEVELS.includes(value.
|
|
642
|
+
typeof value.thinking === "string" &&
|
|
643
|
+
COGNITIVE_ROUTING_THINKING_LEVELS.includes(value.thinking as CognitiveRoutingThinkingLevel)
|
|
522
644
|
);
|
|
523
645
|
}
|
|
524
646
|
|
|
@@ -572,6 +694,7 @@ function cognitiveRoutingProfileDisplay(value: unknown): string {
|
|
|
572
694
|
}
|
|
573
695
|
|
|
574
696
|
function cognitiveRoutingSettingsSource(source: unknown): ConfigSource {
|
|
697
|
+
if (source === "session") return "session";
|
|
575
698
|
if (source === "repository") return "repository";
|
|
576
699
|
if (source === "personal" || source === "local") return "local";
|
|
577
700
|
return "builtin";
|
|
@@ -579,6 +702,7 @@ function cognitiveRoutingSettingsSource(source: unknown): ConfigSource {
|
|
|
579
702
|
|
|
580
703
|
function cognitiveRoutingProfileDisplaySuffix(source: unknown, scope: ConfigScope): string | undefined {
|
|
581
704
|
if (!source) return undefined;
|
|
705
|
+
if (source === "session") return "(session override)";
|
|
582
706
|
if (source === "personal" && scope === "repository") return "(effective personal)";
|
|
583
707
|
return `(${source})`;
|
|
584
708
|
}
|
|
@@ -603,6 +727,11 @@ function createCognitiveRoutingProfileWizard(
|
|
|
603
727
|
currentValue: unknown,
|
|
604
728
|
models: CognitiveRoutingModelOption[],
|
|
605
729
|
allowInherit: boolean,
|
|
730
|
+
inheritChoice: { label: string; description: string; summary: string } = {
|
|
731
|
+
label: "Inherit repository preset",
|
|
732
|
+
description: "Remove the personal override without changing the repository preset.",
|
|
733
|
+
summary: "inherit repository preset",
|
|
734
|
+
},
|
|
606
735
|
): SettingsWizard {
|
|
607
736
|
const currentProfile = isCognitiveRoutingProfile(currentValue) ? currentValue : undefined;
|
|
608
737
|
const currentModelKey = currentProfile
|
|
@@ -614,8 +743,8 @@ function createCognitiveRoutingProfileWizard(
|
|
|
614
743
|
{
|
|
615
744
|
key: LOCAL_INHERIT,
|
|
616
745
|
value: LOCAL_INHERIT,
|
|
617
|
-
label:
|
|
618
|
-
description:
|
|
746
|
+
label: inheritChoice.label,
|
|
747
|
+
description: inheritChoice.description,
|
|
619
748
|
},
|
|
620
749
|
]
|
|
621
750
|
: []),
|
|
@@ -650,12 +779,11 @@ function createCognitiveRoutingProfileWizard(
|
|
|
650
779
|
if (selectedValues.length === 1) {
|
|
651
780
|
const selected = selectedValues[0];
|
|
652
781
|
if (selected === LOCAL_INHERIT) {
|
|
653
|
-
return cognitiveRoutingConfirmStep(
|
|
782
|
+
return cognitiveRoutingConfirmStep(inheritChoice.summary);
|
|
654
783
|
}
|
|
655
784
|
const model = selected as CognitiveRoutingModelOption;
|
|
656
785
|
if (!model?.key || model.thinkingLevels.length === 0) return undefined;
|
|
657
|
-
const currentEffort =
|
|
658
|
-
currentProfile && currentModelKey === model.key ? currentProfile.thinkingLevel : undefined;
|
|
786
|
+
const currentEffort = currentProfile && currentModelKey === model.key ? currentProfile.thinking : undefined;
|
|
659
787
|
return {
|
|
660
788
|
title: `Choose effort · ${model.label}`,
|
|
661
789
|
choices: model.thinkingLevels.map((level) => ({
|
|
@@ -681,7 +809,7 @@ function createCognitiveRoutingProfileWizard(
|
|
|
681
809
|
return {
|
|
682
810
|
provider: model.provider,
|
|
683
811
|
model: model.model,
|
|
684
|
-
|
|
812
|
+
thinking: selectedValues[1] as CognitiveRoutingThinkingLevel,
|
|
685
813
|
} satisfies CognitiveRoutingProfile;
|
|
686
814
|
},
|
|
687
815
|
};
|
|
@@ -694,133 +822,75 @@ function cognitiveRoutingProfileItem(options: {
|
|
|
694
822
|
localConfig: Record<string, unknown>;
|
|
695
823
|
capabilityState: CognitiveRoutingCapabilityState | undefined;
|
|
696
824
|
ctx: any;
|
|
825
|
+
sessionProfiles?: Partial<Record<CognitiveRoutingProfileName, SessionRoutingPair>>;
|
|
697
826
|
}): SettingsItem {
|
|
698
827
|
const path = ["cognitiveRouting", "profiles", options.name];
|
|
699
828
|
const repositoryProfile = getPath(options.rawConfig, path);
|
|
700
829
|
const localProfile = getPath(options.localConfig, path);
|
|
701
|
-
const
|
|
830
|
+
const configuredProfile = options.capabilityState?.profiles?.[options.name] ?? repositoryProfile;
|
|
831
|
+
const sessionPair = options.sessionProfiles?.[options.name];
|
|
832
|
+
const sessionProfile = sessionPair
|
|
833
|
+
? { provider: sessionPair.provider, model: sessionPair.modelId, thinking: sessionPair.thinking }
|
|
834
|
+
: undefined;
|
|
835
|
+
const effectiveProfile = sessionProfile ?? configuredProfile;
|
|
702
836
|
const localValue = isCognitiveRoutingProfile(localProfile) ? localProfile : LOCAL_INHERIT;
|
|
703
|
-
const value =
|
|
704
|
-
|
|
837
|
+
const value =
|
|
838
|
+
options.scope === "session"
|
|
839
|
+
? (sessionProfile ?? LOCAL_INHERIT)
|
|
840
|
+
: options.scope === "local"
|
|
841
|
+
? localValue
|
|
842
|
+
: repositoryProfile;
|
|
843
|
+
const configuredSource =
|
|
705
844
|
options.capabilityState?.profileSources?.[options.name] ??
|
|
706
845
|
(isCognitiveRoutingProfile(repositoryProfile) ? "repository" : undefined);
|
|
846
|
+
const source = options.scope === "session" ? (sessionProfile ? "session" : configuredSource) : configuredSource;
|
|
707
847
|
const models = cognitiveRoutingModelOptions(options.ctx);
|
|
708
|
-
const inactive = options.scope
|
|
848
|
+
const inactive = options.scope !== "repository" && models.length === 0 && value !== LOCAL_INHERIT;
|
|
849
|
+
const inheritChoice =
|
|
850
|
+
options.scope === "session"
|
|
851
|
+
? {
|
|
852
|
+
label: "Inherit configured preset",
|
|
853
|
+
description: "Remove the session override without changing local or repository configuration.",
|
|
854
|
+
summary: "inherit configured preset",
|
|
855
|
+
}
|
|
856
|
+
: undefined;
|
|
709
857
|
|
|
710
858
|
return {
|
|
711
859
|
id: `freeflow.cognitiveRouting.${options.name}`,
|
|
712
860
|
label: `${options.name.charAt(0).toUpperCase()}${options.name.slice(1)} preset`,
|
|
713
861
|
description:
|
|
714
|
-
|
|
862
|
+
options.scope === "session"
|
|
863
|
+
? "Temporarily choose the model and effort for this profile in the current Pi session only."
|
|
864
|
+
: "Choose an authenticated available model and one effort supported by that model. Confirming writes the complete preset; cancel leaves it unchanged.",
|
|
715
865
|
path,
|
|
716
866
|
kind: "string",
|
|
717
867
|
value,
|
|
718
|
-
format:
|
|
868
|
+
format: (current) => {
|
|
869
|
+
const inherits = current === LOCAL_INHERIT || (options.scope === "session" && current === undefined);
|
|
870
|
+
return inherits
|
|
871
|
+
? options.scope === "session"
|
|
872
|
+
? "inherit configured preset"
|
|
873
|
+
: "inherit repository preset"
|
|
874
|
+
: cognitiveRoutingProfileDisplay(current);
|
|
875
|
+
},
|
|
719
876
|
configScope: options.scope,
|
|
720
877
|
effectiveValue: effectiveProfile,
|
|
721
878
|
effectiveSource: cognitiveRoutingSettingsSource(source),
|
|
722
|
-
inheritedValue: repositoryProfile,
|
|
723
|
-
inheritedSource: "
|
|
879
|
+
inheritedValue: options.scope === "session" ? configuredProfile : repositoryProfile,
|
|
880
|
+
inheritedSource: cognitiveRoutingSettingsSource(configuredSource ?? "builtin"),
|
|
724
881
|
inactive,
|
|
725
882
|
displaySuffix: cognitiveRoutingProfileDisplaySuffix(source, options.scope),
|
|
726
|
-
wizard: () => createCognitiveRoutingProfileWizard(value, models, options.scope
|
|
883
|
+
wizard: () => createCognitiveRoutingProfileWizard(value, models, options.scope !== "repository", inheritChoice),
|
|
727
884
|
};
|
|
728
885
|
}
|
|
729
886
|
|
|
730
|
-
type CognitiveRoutingSessionStartSetting = "control" | "profile";
|
|
731
|
-
|
|
732
|
-
function cognitiveRoutingSessionStartItem(options: {
|
|
733
|
-
setting: CognitiveRoutingSessionStartSetting;
|
|
734
|
-
scope: ConfigScope;
|
|
735
|
-
rawConfig: Record<string, unknown>;
|
|
736
|
-
localConfig: Record<string, unknown>;
|
|
737
|
-
capabilityState: CognitiveRoutingCapabilityState | undefined;
|
|
738
|
-
}): SettingsItem {
|
|
739
|
-
const path = ["cognitiveRouting", "sessionStart", options.setting];
|
|
740
|
-
const defaultValue = options.setting === "control" ? "automatic" : "reasoning";
|
|
741
|
-
const values = options.setting === "control" ? ["automatic", "manual"] : ["standard", "reasoning"];
|
|
742
|
-
const labels = Object.fromEntries(values.map((value) => [value, value]));
|
|
743
|
-
const descriptions =
|
|
744
|
-
options.setting === "control"
|
|
745
|
-
? {
|
|
746
|
-
automatic: "Start the new session in Reasoning; automatic delegation may use Standard during execution.",
|
|
747
|
-
manual: "Hold the selected profile for the new session until the user changes it.",
|
|
748
|
-
}
|
|
749
|
-
: {
|
|
750
|
-
standard: "Start a new manual session with the configured Standard preset.",
|
|
751
|
-
reasoning: "Start a new manual session with the configured Reasoning preset.",
|
|
752
|
-
};
|
|
753
|
-
const repositoryValue = getPath(options.rawConfig, path);
|
|
754
|
-
const localValue = getPath(options.localConfig, path);
|
|
755
|
-
const isValidValue = (value: unknown): value is string => values.includes(value as string);
|
|
756
|
-
const repositorySetting = isValidValue(repositoryValue) ? repositoryValue : undefined;
|
|
757
|
-
const localSetting = isValidValue(localValue) ? localValue : undefined;
|
|
758
|
-
const inheritedValue = repositorySetting ?? defaultValue;
|
|
759
|
-
const inheritedSource: ConfigSource = repositorySetting ? "repository" : "builtin";
|
|
760
|
-
const configuredSource =
|
|
761
|
-
options.capabilityState?.sessionStartSources?.[options.setting] ?? (repositorySetting ? "repository" : undefined);
|
|
762
|
-
const effectiveSessionStartControl =
|
|
763
|
-
options.capabilityState?.sessionStart?.control ??
|
|
764
|
-
getPath(options.localConfig, ["cognitiveRouting", "sessionStart", "control"]) ??
|
|
765
|
-
getPath(options.rawConfig, ["cognitiveRouting", "sessionStart", "control"]) ??
|
|
766
|
-
"automatic";
|
|
767
|
-
const effectiveValue =
|
|
768
|
-
options.setting === "profile" && effectiveSessionStartControl === "automatic"
|
|
769
|
-
? "reasoning"
|
|
770
|
-
: (options.capabilityState?.sessionStart?.[options.setting] ?? inheritedValue);
|
|
771
|
-
const effectiveSource = cognitiveRoutingSettingsSource(configuredSource);
|
|
772
|
-
const label = options.setting === "control" ? "Session start control" : "Manual session-start profile";
|
|
773
|
-
const description =
|
|
774
|
-
options.setting === "control"
|
|
775
|
-
? "Choose automatic or manual control for new sessions only; changing this does not alter the active session."
|
|
776
|
-
: "Choose the profile for manual session starts; automatic sessions always start in Reasoning.";
|
|
777
|
-
|
|
778
|
-
const item: SettingsItem =
|
|
779
|
-
options.scope === "local"
|
|
780
|
-
? {
|
|
781
|
-
id: `freeflow.cognitiveRouting.sessionStart.${options.setting}`,
|
|
782
|
-
label,
|
|
783
|
-
description: `${description} Choose inherit to use the repository value; use /freeflow settings repo to edit shared defaults.`,
|
|
784
|
-
path,
|
|
785
|
-
kind: "enum",
|
|
786
|
-
value: localSetting ?? LOCAL_INHERIT,
|
|
787
|
-
values: [LOCAL_INHERIT, ...values],
|
|
788
|
-
valueLabels: { inherit: "Inherit repository", ...labels },
|
|
789
|
-
valueDescriptions: {
|
|
790
|
-
inherit: `Use ${inheritedValue} from ${inheritedSource}.`,
|
|
791
|
-
...descriptions,
|
|
792
|
-
},
|
|
793
|
-
format: (value) => String(value),
|
|
794
|
-
configScope: "local",
|
|
795
|
-
configValues: { inherit: undefined },
|
|
796
|
-
effectiveValue,
|
|
797
|
-
effectiveSource,
|
|
798
|
-
inheritedValue,
|
|
799
|
-
inheritedSource,
|
|
800
|
-
}
|
|
801
|
-
: {
|
|
802
|
-
id: `freeflow.cognitiveRouting.sessionStart.${options.setting}`,
|
|
803
|
-
label,
|
|
804
|
-
description: `${description} This edits shared .freeflow/config.json.`,
|
|
805
|
-
path,
|
|
806
|
-
kind: "enum",
|
|
807
|
-
value: inheritedValue,
|
|
808
|
-
values,
|
|
809
|
-
valueLabels: labels,
|
|
810
|
-
valueDescriptions: descriptions,
|
|
811
|
-
format: (value) => String(value),
|
|
812
|
-
defaultValue,
|
|
813
|
-
configScope: "repository",
|
|
814
|
-
effectiveValue,
|
|
815
|
-
effectiveSource,
|
|
816
|
-
localOverrideValue: localSetting,
|
|
817
|
-
};
|
|
818
|
-
item.displaySuffix = coreDisplaySuffix(item);
|
|
819
|
-
return item;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
887
|
function isCognitiveRoutingRuntimeAvailable(pi: any): boolean {
|
|
823
|
-
return
|
|
888
|
+
return (
|
|
889
|
+
!isPiFlowHost(pi?.host) &&
|
|
890
|
+
typeof pi?.appendEntry === "function" &&
|
|
891
|
+
typeof pi?.setModel === "function" &&
|
|
892
|
+
typeof pi?.setThinkingLevel === "function"
|
|
893
|
+
);
|
|
824
894
|
}
|
|
825
895
|
|
|
826
896
|
function freeflowItems(
|
|
@@ -833,7 +903,7 @@ function freeflowItems(
|
|
|
833
903
|
runtimeAvailable?: boolean;
|
|
834
904
|
} = {},
|
|
835
905
|
): SettingsItem[] {
|
|
836
|
-
const scope = options.scope
|
|
906
|
+
const scope: Exclude<ConfigScope, "session"> = options.scope === "local" ? "local" : "repository";
|
|
837
907
|
const layers = options.layers;
|
|
838
908
|
const { localConfig, core, sources } = resolveSettingsCoreView(rawConfig, layers);
|
|
839
909
|
|
|
@@ -889,7 +959,7 @@ function freeflowItems(
|
|
|
889
959
|
label: "Enabled",
|
|
890
960
|
description: cognitiveRoutingRuntimeDisabled
|
|
891
961
|
? "Requires a host model-state control API; configuration is read-only on this host."
|
|
892
|
-
: "Allow Cognitive Routing to
|
|
962
|
+
: "Allow Cognitive Routing to manage explicit assignments and request native profile transitions.",
|
|
893
963
|
path: ["cognitiveRouting", "enabled"],
|
|
894
964
|
effectiveValue: cognitiveRoutingState?.enabled ?? false,
|
|
895
965
|
effectiveSource: cognitiveRoutingSettingsSource(cognitiveRoutingState?.enabledSource),
|
|
@@ -898,7 +968,33 @@ function freeflowItems(
|
|
|
898
968
|
cognitiveRoutingEnabledItem.inactive = freeflowInactive || cognitiveRoutingRuntimeDisabled;
|
|
899
969
|
cognitiveRoutingEnabledItem.runtimeInactive = cognitiveRoutingRuntimeDisabled;
|
|
900
970
|
|
|
901
|
-
const
|
|
971
|
+
const cognitiveRoutingDelegationItem = createScopedDelegationItem({
|
|
972
|
+
scope,
|
|
973
|
+
rawConfig,
|
|
974
|
+
localConfig,
|
|
975
|
+
effectiveValue: cognitiveRoutingState?.delegation ?? "executor",
|
|
976
|
+
effectiveSource: cognitiveRoutingSettingsSource(cognitiveRoutingState?.delegationSource),
|
|
977
|
+
});
|
|
978
|
+
cognitiveRoutingDelegationItem.inactive = freeflowInactive || cognitiveRoutingRuntimeDisabled;
|
|
979
|
+
cognitiveRoutingDelegationItem.runtimeInactive = cognitiveRoutingRuntimeDisabled;
|
|
980
|
+
|
|
981
|
+
const cognitiveRoutingProjectionItem = createScopedBooleanItem({
|
|
982
|
+
scope,
|
|
983
|
+
rawConfig,
|
|
984
|
+
localConfig,
|
|
985
|
+
id: "freeflow.cognitiveRouting.projection",
|
|
986
|
+
label: "Context projection",
|
|
987
|
+
description:
|
|
988
|
+
"Select worker evidence for Coordinator; disable projection to keep ordinary Pi context in all enabled profiles.",
|
|
989
|
+
path: ["cognitiveRouting", "projection"],
|
|
990
|
+
effectiveValue: cognitiveRoutingState?.projection ?? false,
|
|
991
|
+
effectiveSource: cognitiveRoutingSettingsSource(cognitiveRoutingState?.projectionSource),
|
|
992
|
+
defaultValue: false,
|
|
993
|
+
});
|
|
994
|
+
cognitiveRoutingProjectionItem.inactive = freeflowInactive || cognitiveRoutingRuntimeDisabled;
|
|
995
|
+
cognitiveRoutingProjectionItem.runtimeInactive = cognitiveRoutingRuntimeDisabled;
|
|
996
|
+
|
|
997
|
+
const cognitiveRoutingProfiles = ["coordinator", "helper", "executor"].map((name) =>
|
|
902
998
|
cognitiveRoutingProfileItem({
|
|
903
999
|
name: name as CognitiveRoutingProfileName,
|
|
904
1000
|
scope,
|
|
@@ -908,17 +1004,7 @@ function freeflowItems(
|
|
|
908
1004
|
ctx: options.ctx,
|
|
909
1005
|
}),
|
|
910
1006
|
);
|
|
911
|
-
|
|
912
|
-
(setting) =>
|
|
913
|
-
cognitiveRoutingSessionStartItem({
|
|
914
|
-
setting,
|
|
915
|
-
scope,
|
|
916
|
-
rawConfig,
|
|
917
|
-
localConfig,
|
|
918
|
-
capabilityState: cognitiveRoutingState,
|
|
919
|
-
}),
|
|
920
|
-
);
|
|
921
|
-
for (const item of [...cognitiveRoutingProfiles, ...cognitiveRoutingSessionStart]) {
|
|
1007
|
+
for (const item of cognitiveRoutingProfiles) {
|
|
922
1008
|
item.inactive ||= freeflowInactive || cognitiveRoutingRuntimeDisabled;
|
|
923
1009
|
item.runtimeInactive = cognitiveRoutingRuntimeDisabled;
|
|
924
1010
|
}
|
|
@@ -936,12 +1022,17 @@ function freeflowItems(
|
|
|
936
1022
|
label: "Cognitive Routing",
|
|
937
1023
|
description: cognitiveRoutingRuntimeDisabled
|
|
938
1024
|
? "Cognitive Routing configuration is visible for inspection but requires a host model-state control API."
|
|
939
|
-
: "Configure
|
|
1025
|
+
: "Configure Coordinator, Helper, and Executor profiles plus the workers available for delegation.",
|
|
940
1026
|
kind: "group" as const,
|
|
941
1027
|
value: cognitiveRoutingRuntimeDisabled ? false : (cognitiveRoutingState?.enabled ?? false),
|
|
942
1028
|
inactive: freeflowInactive,
|
|
943
1029
|
displaySuffix: cognitiveRoutingStatus,
|
|
944
|
-
children: [
|
|
1030
|
+
children: [
|
|
1031
|
+
cognitiveRoutingEnabledItem,
|
|
1032
|
+
cognitiveRoutingDelegationItem,
|
|
1033
|
+
...cognitiveRoutingProfiles,
|
|
1034
|
+
cognitiveRoutingProjectionItem,
|
|
1035
|
+
],
|
|
945
1036
|
} satisfies SettingsItem;
|
|
946
1037
|
})();
|
|
947
1038
|
|
|
@@ -965,6 +1056,7 @@ function pruneKnownDefaults(config: Record<string, unknown>) {
|
|
|
965
1056
|
{ path: ["enabled"], value: DEFAULT_FREEFLOW_ENABLED },
|
|
966
1057
|
{ path: ["contextVirtualization"], value: DEFAULT_CONTEXT_VIRTUALIZATION_ENABLED },
|
|
967
1058
|
{ path: ["conversationHistory"], value: DEFAULT_CONVERSATION_HISTORY_ENABLED },
|
|
1059
|
+
{ path: ["cognitiveRouting", "delegation"], value: "executor" },
|
|
968
1060
|
];
|
|
969
1061
|
|
|
970
1062
|
for (const item of defaultPaths) {
|
|
@@ -1051,7 +1143,7 @@ async function updateConfig(
|
|
|
1051
1143
|
}
|
|
1052
1144
|
|
|
1053
1145
|
function isCognitiveRoutingProfileItem(item: SettingsItem): boolean {
|
|
1054
|
-
return
|
|
1146
|
+
return ["coordinator", "helper", "executor"].some((profile) => item.id === `freeflow.cognitiveRouting.${profile}`);
|
|
1055
1147
|
}
|
|
1056
1148
|
|
|
1057
1149
|
function valueForDisplay(item: SettingsItem): string {
|
|
@@ -1095,10 +1187,13 @@ function refreshSettingsDerivedState(items: SettingsItem[]) {
|
|
|
1095
1187
|
const freeflowInactive = freeflowItem ? effectiveItemValue(freeflowItem) !== true : false;
|
|
1096
1188
|
const cognitiveRoutingGroup = findSettingsItem(items, "freeflow.cognitiveRouting");
|
|
1097
1189
|
const cognitiveRoutingEnabledItem = findSettingsItem(items, "freeflow.cognitiveRouting.enabled");
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1190
|
+
const cognitiveRoutingDelegationItem = findSettingsItem(items, "freeflow.cognitiveRouting.delegation");
|
|
1191
|
+
const delegation = (
|
|
1192
|
+
cognitiveRoutingDelegationItem ? effectiveItemValue(cognitiveRoutingDelegationItem) : "executor"
|
|
1193
|
+
) as CognitiveRoutingDelegationMode;
|
|
1194
|
+
const cognitiveRoutingProfiles = ["coordinator", ...workersForDelegation(delegation)].map((profile) =>
|
|
1195
|
+
findSettingsItem(items, `freeflow.cognitiveRouting.${profile}`),
|
|
1196
|
+
);
|
|
1102
1197
|
|
|
1103
1198
|
if (cognitiveRoutingGroup && cognitiveRoutingEnabledItem) {
|
|
1104
1199
|
const enabled = effectiveItemValue(cognitiveRoutingEnabledItem) === true;
|
|
@@ -1416,7 +1511,7 @@ export async function handleFreeflowCommand(
|
|
|
1416
1511
|
let reconcileCognitiveRouting = settingsScope === "session";
|
|
1417
1512
|
const items =
|
|
1418
1513
|
settingsScope === "session"
|
|
1419
|
-
? sessionFreeflowItems(state, cognitiveRoutingController)
|
|
1514
|
+
? sessionFreeflowItems(state, cognitiveRoutingController, ctx)
|
|
1420
1515
|
: freeflowItems(raw, {
|
|
1421
1516
|
scope: settingsScope,
|
|
1422
1517
|
layers,
|
|
@@ -1447,7 +1542,10 @@ export async function handleFreeflowCommand(
|
|
|
1447
1542
|
const result =
|
|
1448
1543
|
value === "auto"
|
|
1449
1544
|
? await cognitiveRoutingController.setAutomaticControl("profile-settings")
|
|
1450
|
-
: await cognitiveRoutingController.setManualProfile(
|
|
1545
|
+
: await cognitiveRoutingController.setManualProfile(
|
|
1546
|
+
value as CognitiveRoutingProfileName,
|
|
1547
|
+
"profile-settings",
|
|
1548
|
+
);
|
|
1451
1549
|
if ((result.status !== "automatic" && result.status !== "active") || result.reason) {
|
|
1452
1550
|
ctx.ui.notify(
|
|
1453
1551
|
`Cognitive Routing settings could not be applied: ${result.reason ?? result.status}.`,
|
|
@@ -1459,8 +1557,63 @@ export async function handleFreeflowCommand(
|
|
|
1459
1557
|
return { changed: true, reloadRequired: false };
|
|
1460
1558
|
}
|
|
1461
1559
|
if (item.id === "freeflow.session.reset") {
|
|
1462
|
-
const
|
|
1463
|
-
|
|
1560
|
+
const routingResult = cognitiveRoutingController
|
|
1561
|
+
? await cognitiveRoutingController.resetSessionProfileOverrides("Reset session overrides")
|
|
1562
|
+
: { status: "unchanged" };
|
|
1563
|
+
if (routingResult.status === "blocked" || routingResult.reason) {
|
|
1564
|
+
ctx.ui.notify(
|
|
1565
|
+
`Cognitive Routing session presets could not be reset: ${routingResult.reason ?? routingResult.status}.`,
|
|
1566
|
+
"warning",
|
|
1567
|
+
);
|
|
1568
|
+
return { changed: false, reloadRequired: false };
|
|
1569
|
+
}
|
|
1570
|
+
try {
|
|
1571
|
+
const result = await resetSessionOverrides(ctx, pi);
|
|
1572
|
+
return {
|
|
1573
|
+
changed: result.changed || routingResult.status !== "unchanged",
|
|
1574
|
+
reloadRequired: result.reloadRequired,
|
|
1575
|
+
};
|
|
1576
|
+
} catch (error) {
|
|
1577
|
+
ctx.ui.notify(
|
|
1578
|
+
`Routing presets were reset, but core/context session overrides could not be reset: ${
|
|
1579
|
+
error instanceof Error ? error.message : String(error)
|
|
1580
|
+
}`,
|
|
1581
|
+
"warning",
|
|
1582
|
+
);
|
|
1583
|
+
return {
|
|
1584
|
+
changed: routingResult.status !== "unchanged",
|
|
1585
|
+
reloadRequired: false,
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
if (item.configScope === "session" && isCognitiveRoutingProfileItem(item)) {
|
|
1590
|
+
if (!cognitiveRoutingController) {
|
|
1591
|
+
ctx.ui.notify("Cognitive Routing is unavailable for this session.", "warning");
|
|
1592
|
+
return { changed: false, reloadRequired: false };
|
|
1593
|
+
}
|
|
1594
|
+
const profile = item.id.split(".").at(-1) as CognitiveRoutingProfileName;
|
|
1595
|
+
const override =
|
|
1596
|
+
value === undefined || value === LOCAL_INHERIT
|
|
1597
|
+
? null
|
|
1598
|
+
: {
|
|
1599
|
+
provider: (value as CognitiveRoutingProfile).provider,
|
|
1600
|
+
modelId: (value as CognitiveRoutingProfile).model,
|
|
1601
|
+
thinking: (value as CognitiveRoutingProfile).thinking,
|
|
1602
|
+
};
|
|
1603
|
+
const result = await cognitiveRoutingController.setSessionProfileOverride(
|
|
1604
|
+
profile,
|
|
1605
|
+
override,
|
|
1606
|
+
"Session profile settings",
|
|
1607
|
+
);
|
|
1608
|
+
if (result.status === "blocked" || result.reason) {
|
|
1609
|
+
ctx.ui.notify(
|
|
1610
|
+
`Cognitive Routing session preset could not be applied: ${result.reason ?? result.status}.`,
|
|
1611
|
+
"warning",
|
|
1612
|
+
);
|
|
1613
|
+
return { changed: false, reloadRequired: false };
|
|
1614
|
+
}
|
|
1615
|
+
await afterChange(false);
|
|
1616
|
+
return { changed: result.status !== "unchanged", reloadRequired: false };
|
|
1464
1617
|
}
|
|
1465
1618
|
if (item.configScope === "session") {
|
|
1466
1619
|
const keyById = {
|