@agimon-ai/doompi-cache 0.0.1-alpha.81 → 0.0.1-alpha.82
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/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.mjs +1 -1
- package/dist/{pi-cache-optimizer-z5yQQoac.mjs → pi-cache-optimizer-BL5YIGOi.mjs} +404 -37
- package/dist/pi-cache-optimizer-BL5YIGOi.mjs.map +1 -0
- package/dist/{pi-cache-optimizer-VJG1vKKU.cjs → pi-cache-optimizer-DSED41mZ.cjs} +404 -37
- package/dist/pi-cache-optimizer-DSED41mZ.cjs.map +1 -0
- package/package.json +7 -7
- package/dist/pi-cache-optimizer-VJG1vKKU.cjs.map +0 -1
- package/dist/pi-cache-optimizer-z5yQQoac.mjs.map +0 -1
|
@@ -4,7 +4,7 @@ let node_fs = require("node:fs");
|
|
|
4
4
|
let node_os = require("node:os");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
let _earendil_works_pi_coding_agent = require("@earendil-works/pi-coding-agent");
|
|
7
|
-
//#region ../../../node_modules/.pnpm/pi-cache-optimizer@2.8.
|
|
7
|
+
//#region ../../../node_modules/.pnpm/pi-cache-optimizer@2.8.16_@earendil-works+pi-coding-agent@1.0.2_@aws-sdk+credential-pro_336a3137387524f540927fd810e3b800/node_modules/pi-cache-optimizer/index.ts
|
|
8
8
|
const PI_CACHE_RETENTION_ENV = "PI_CACHE_RETENTION";
|
|
9
9
|
const LONG_CACHE_RETENTION_VALUE = "long";
|
|
10
10
|
const PI_CACHE_RETENTION_BASELINE_SYMBOL = Symbol.for("pi.cache.optimizer.retention-baseline.v1");
|
|
@@ -91,6 +91,7 @@ const NO_OPENAI_CACHE_KEY_ENV = "PI_CACHE_OPTIMIZER_NO_OPENAI_CACHE_KEY";
|
|
|
91
91
|
const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
|
|
92
92
|
const NO_SKILL_COMPRESSION_ENV = "PI_CACHE_OPTIMIZER_NO_SKILL_COMPRESSION";
|
|
93
93
|
const NO_PROMPT_REWRITE_ENV = "PI_CACHE_OPTIMIZER_NO_PROMPT_REWRITE";
|
|
94
|
+
const VIRTUAL_REWRITE_ENV = "PI_CACHE_OPTIMIZER_VIRTUAL_REWRITE";
|
|
94
95
|
const TOOL_ORDER_ENV = "PI_CACHE_OPTIMIZER_TOOL_ORDER";
|
|
95
96
|
const FOOTER_MODE_ENV = "PI_CACHE_OPTIMIZER_FOOTER_MODE";
|
|
96
97
|
const RECEIPT_COMPAT_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -104,6 +105,7 @@ const RECEIPT_COMPAT_KEYS = /* @__PURE__ */ new Set([
|
|
|
104
105
|
]);
|
|
105
106
|
const PI_ROUTING_REGISTRY_SYMBOL = Symbol.for("pi.routing.registry.v1");
|
|
106
107
|
const PI_CACHE_HINTS_SYMBOL = Symbol.for("pi.cache.hints.v1");
|
|
108
|
+
const PI_VIRTUAL_MODEL_API = "pi-virtual";
|
|
107
109
|
const PI_CACHE_HINTS_OWNER_SYMBOL = Symbol.for("pi.cache.optimizer.hints-owner.v1");
|
|
108
110
|
const ANTHROPIC_TTL_FALLBACK_SYMBOL = Symbol.for("pi.cache.optimizer.anthropic-ttl-fallback.v1");
|
|
109
111
|
const REASONING_PROTOCOL_FALLBACK_SYMBOL = Symbol.for("pi.cache.optimizer.reasoning-protocol-fallback.v1");
|
|
@@ -437,7 +439,7 @@ function formatSkillsForPromptCompressed(skills) {
|
|
|
437
439
|
* than mangle.
|
|
438
440
|
*/
|
|
439
441
|
function compressSkillsInSystemPrompt(prompt, opts) {
|
|
440
|
-
if (
|
|
442
|
+
if (!featureEnabled("skillCompression", NO_SKILL_COMPRESSION_ENV, true)) return prompt;
|
|
441
443
|
if (!opts.skills || opts.skills.length === 0) return prompt;
|
|
442
444
|
if (opts.skills.filter((skill) => !skill.disableModelInvocation).length < SKILL_COMPRESSION_MIN_COUNT) return prompt;
|
|
443
445
|
const verbose = formatSkillsForPrompt(opts.skills);
|
|
@@ -692,7 +694,7 @@ function parseRouteSnapshot(value, fallbackVirtualProvider, fallbackVirtualModel
|
|
|
692
694
|
};
|
|
693
695
|
}
|
|
694
696
|
function resolveActiveRouteSnapshot(model, ctx) {
|
|
695
|
-
if (!model) return void 0;
|
|
697
|
+
if (!model || isNativeVirtualModel(model)) return void 0;
|
|
696
698
|
const hint = ctx ? { sessionIdHash: sessionHashFromContext(ctx) } : void 0;
|
|
697
699
|
const adapter = getRoutingRegistry()?.getRouter(model.provider);
|
|
698
700
|
if (adapter) try {
|
|
@@ -713,6 +715,31 @@ function resolveActiveRouteSnapshot(model, ctx) {
|
|
|
713
715
|
return;
|
|
714
716
|
}
|
|
715
717
|
}
|
|
718
|
+
function resolveNativeVirtualCandidateModels(model, ctx) {
|
|
719
|
+
if (!isNativeVirtualModel(model)) return void 0;
|
|
720
|
+
const adapter = model ? getRoutingRegistry()?.getRouter(model.provider) : void 0;
|
|
721
|
+
if (!adapter?.resolveCandidateRoutes) return void 0;
|
|
722
|
+
try {
|
|
723
|
+
const rawSnapshots = adapter.resolveCandidateRoutes(model.id);
|
|
724
|
+
if (!Array.isArray(rawSnapshots) || rawSnapshots.length === 0) return void 0;
|
|
725
|
+
const candidates = [];
|
|
726
|
+
for (const rawSnapshot of rawSnapshots) {
|
|
727
|
+
const snapshot = parseRouteSnapshot(rawSnapshot, model.provider, model.id);
|
|
728
|
+
if (!snapshot) return void 0;
|
|
729
|
+
const candidate = findModelInRegistry(ctx?.modelRegistry, snapshot.provider, snapshot.modelId) ?? routeSnapshotToPiModel(snapshot, model);
|
|
730
|
+
if (!isNonEmptyString(candidate.api)) return void 0;
|
|
731
|
+
candidates.push(candidate);
|
|
732
|
+
}
|
|
733
|
+
return candidates;
|
|
734
|
+
} catch {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
function canRewriteNativeVirtualPrompt(model, ctx) {
|
|
739
|
+
if (!isNativeVirtualModel(model) || !featureEnabled("virtualRewrite", VIRTUAL_REWRITE_ENV, false)) return false;
|
|
740
|
+
const candidates = resolveNativeVirtualCandidateModels(model, ctx);
|
|
741
|
+
return !!candidates?.length && candidates.every((candidate) => candidate.api === "openai-completions" || candidate.api === "anthropic-messages") && candidates.every((candidate) => !isResponsesPromptRewriteBypassApi(candidate.api));
|
|
742
|
+
}
|
|
716
743
|
function routeSnapshotToPiModel(snapshot, fallback) {
|
|
717
744
|
const sameIdentity = fallback?.provider === snapshot.provider && fallback?.id === snapshot.modelId;
|
|
718
745
|
return {
|
|
@@ -769,13 +796,151 @@ function applyConfiguredTransportToModel(model, config) {
|
|
|
769
796
|
};
|
|
770
797
|
}
|
|
771
798
|
function resolveRouteModel(model, ctx) {
|
|
799
|
+
const nativeVirtualRoute = resolveNativeVirtualRouteModel(model, ctx);
|
|
800
|
+
if (nativeVirtualRoute) return nativeVirtualRoute;
|
|
772
801
|
const snapshot = resolveActiveRouteSnapshot(model, ctx);
|
|
773
802
|
if (!snapshot) return void 0;
|
|
774
803
|
return applyConfiguredTransportToModel(findModelInRegistry(ctx?.modelRegistry, snapshot.provider, snapshot.modelId) ?? routeSnapshotToPiModel(snapshot, model), readEffectiveCompatConfig());
|
|
775
804
|
}
|
|
776
805
|
function isVirtualRoutingModel(model, ctx) {
|
|
777
806
|
if (!model) return false;
|
|
778
|
-
return isRouterModel(model) || !!getRoutingRegistry()?.getRouter(model.provider) || !!resolveActiveRouteSnapshot(model, ctx);
|
|
807
|
+
return isNativeVirtualModel(model) || isRouterModel(model) || !!getRoutingRegistry()?.getRouter(model.provider) || !!resolveActiveRouteSnapshot(model, ctx);
|
|
808
|
+
}
|
|
809
|
+
function isNativeVirtualModel(model) {
|
|
810
|
+
return model?.api === PI_VIRTUAL_MODEL_API;
|
|
811
|
+
}
|
|
812
|
+
function readSessionBranch(ctx) {
|
|
813
|
+
try {
|
|
814
|
+
const manager = ctx?.sessionManager;
|
|
815
|
+
if (typeof manager?.getBranch !== "function") return [];
|
|
816
|
+
const branch = manager.getBranch();
|
|
817
|
+
return Array.isArray(branch) ? branch : [];
|
|
818
|
+
} catch {
|
|
819
|
+
return [];
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Physical models that answered on the current session branch, newest first:
|
|
824
|
+
* the latest successful response (Pi's `request.previous`) and the latest
|
|
825
|
+
* response of any outcome (a failed attempt that a retry may reuse). The
|
|
826
|
+
* catalog id in `message.model` is preferred over the echoed `responseModel`
|
|
827
|
+
* because it is the id Pi dispatched and the registry knows.
|
|
828
|
+
*/
|
|
829
|
+
function findNativeVirtualDispatches(ctx) {
|
|
830
|
+
const branch = readSessionBranch(ctx);
|
|
831
|
+
let latestSuccessful;
|
|
832
|
+
let latestAny;
|
|
833
|
+
for (let index = branch.length - 1; index >= 0 && !latestSuccessful; index--) {
|
|
834
|
+
const entry = asRecord(branch[index]);
|
|
835
|
+
if (entry?.type !== "message") continue;
|
|
836
|
+
const message = getAssistantRecord(entry.message);
|
|
837
|
+
if (!message || isNativeVirtualModel(message)) continue;
|
|
838
|
+
const dispatch = nativeVirtualDispatchFromMessage(message);
|
|
839
|
+
if (!dispatch) continue;
|
|
840
|
+
latestAny ??= dispatch;
|
|
841
|
+
if (message.stopReason !== "error" && message.stopReason !== "aborted") latestSuccessful = dispatch;
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
latestSuccessful,
|
|
845
|
+
latestAny
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function nativeVirtualDispatchFromMessage(message) {
|
|
849
|
+
const record = getAssistantRecord(message);
|
|
850
|
+
if (!record || isNativeVirtualModel(record)) return void 0;
|
|
851
|
+
const provider = firstNonEmptyString(record.provider);
|
|
852
|
+
const id = firstNonEmptyString(record.model, record.responseModel);
|
|
853
|
+
return provider && id ? {
|
|
854
|
+
provider,
|
|
855
|
+
id,
|
|
856
|
+
api: firstNonEmptyString(record.api) ?? ""
|
|
857
|
+
} : void 0;
|
|
858
|
+
}
|
|
859
|
+
function nativeVirtualDispatchToModel(dispatch, ctx) {
|
|
860
|
+
const registered = findModelInRegistry(ctx?.modelRegistry, dispatch.provider, dispatch.id);
|
|
861
|
+
return applyConfiguredTransportToModel(registered && !isNativeVirtualModel(registered) ? registered : {
|
|
862
|
+
provider: dispatch.provider,
|
|
863
|
+
id: dispatch.id,
|
|
864
|
+
name: dispatch.id,
|
|
865
|
+
api: dispatch.api,
|
|
866
|
+
baseUrl: "",
|
|
867
|
+
reasoning: false,
|
|
868
|
+
input: ["text"],
|
|
869
|
+
cost: {
|
|
870
|
+
input: 0,
|
|
871
|
+
output: 0,
|
|
872
|
+
cacheRead: 0,
|
|
873
|
+
cacheWrite: 0
|
|
874
|
+
},
|
|
875
|
+
contextWindow: 0,
|
|
876
|
+
maxTokens: 0,
|
|
877
|
+
[ROUTED_FALLBACK_MODEL_SYMBOL]: true
|
|
878
|
+
}, readEffectiveCompatConfig());
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Physical model behind a native virtual selection for pre-request UX (footer,
|
|
882
|
+
* doctor, compat, stats, reset, fix): the model that answered last on this
|
|
883
|
+
* session branch, matching Pi's own routed-model display and context limits.
|
|
884
|
+
*/
|
|
885
|
+
function resolveNativeVirtualRouteModel(model, ctx) {
|
|
886
|
+
if (!isNativeVirtualModel(model)) return void 0;
|
|
887
|
+
const { latestSuccessful, latestAny } = findNativeVirtualDispatches(ctx);
|
|
888
|
+
const dispatch = latestSuccessful ?? latestAny;
|
|
889
|
+
return dispatch ? nativeVirtualDispatchToModel(dispatch, ctx) : void 0;
|
|
890
|
+
}
|
|
891
|
+
function getProviderPayloadModelId(payload) {
|
|
892
|
+
const record = asRecord(payload);
|
|
893
|
+
return firstNonEmptyString(record?.model, record?.modelId);
|
|
894
|
+
}
|
|
895
|
+
function physicalModelsWithId(candidates, id) {
|
|
896
|
+
return (candidates ?? []).filter((candidate) => candidate.id === id && !isNativeVirtualModel(candidate) && !isRouterModel(candidate) && !getRoutingRegistry()?.getRouter(candidate.provider));
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Physical model of one native-virtual request. `before_provider_request`
|
|
900
|
+
* carries only the payload and `ctx.model` stays virtual, so the payload's
|
|
901
|
+
* dispatched model id is matched against credentialed physical models (a
|
|
902
|
+
* router may only route to those). A unique provider match wins. An id shared
|
|
903
|
+
* by several credentialed providers is used only when every candidate gets the
|
|
904
|
+
* same request treatment (`requestPolicyKey`); the identity then stays
|
|
905
|
+
* ambiguous so response evidence is never pinned to a guessed provider.
|
|
906
|
+
* Differing policies return undefined so identity-dependent request mutations
|
|
907
|
+
* fail closed. Without a credentialed match, the sticky branch candidates and
|
|
908
|
+
* then the full catalog are consulted.
|
|
909
|
+
*/
|
|
910
|
+
function resolveNativeVirtualRequestModel(model, payload, ctx, requestPolicyKey) {
|
|
911
|
+
if (!isNativeVirtualModel(model)) return void 0;
|
|
912
|
+
const payloadModelId = getProviderPayloadModelId(payload);
|
|
913
|
+
if (!payloadModelId) return void 0;
|
|
914
|
+
const config = readEffectiveCompatConfig();
|
|
915
|
+
const pick = (matches) => {
|
|
916
|
+
if (matches.length === 0) return null;
|
|
917
|
+
const configured = matches.map((candidate) => applyConfiguredTransportToModel(candidate, config));
|
|
918
|
+
if (new Set(configured.map((candidate) => candidate.provider)).size === 1) return {
|
|
919
|
+
model: configured[0],
|
|
920
|
+
identityAmbiguous: false
|
|
921
|
+
};
|
|
922
|
+
return (requestPolicyKey ? new Set(configured.map(requestPolicyKey)) : void 0)?.size === 1 ? {
|
|
923
|
+
model: configured[0],
|
|
924
|
+
identityAmbiguous: true
|
|
925
|
+
} : void 0;
|
|
926
|
+
};
|
|
927
|
+
try {
|
|
928
|
+
const credentialed = pick(physicalModelsWithId(ctx?.modelRegistry?.getAvailable?.(), payloadModelId));
|
|
929
|
+
if (credentialed !== null) return credentialed;
|
|
930
|
+
const { latestSuccessful, latestAny } = findNativeVirtualDispatches(ctx);
|
|
931
|
+
for (const dispatch of [latestSuccessful, latestAny]) if (dispatch?.id === payloadModelId) return {
|
|
932
|
+
model: nativeVirtualDispatchToModel(dispatch, ctx),
|
|
933
|
+
identityAmbiguous: false
|
|
934
|
+
};
|
|
935
|
+
return pick(physicalModelsWithId(ctx?.modelRegistry?.getAll?.(), payloadModelId)) ?? void 0;
|
|
936
|
+
} catch {
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function describeNativeVirtualRouteNote(selected, effective) {
|
|
941
|
+
if (!selected || !isNativeVirtualModel(selected)) return void 0;
|
|
942
|
+
if (!effective || isNativeVirtualModel(effective)) return void 0;
|
|
943
|
+
return `🔀 Native virtual model ${modelKey(selected)} → latest routed physical model ${modelKey(effective)}. The diagnostics below apply to that physical model; Pi may route later requests elsewhere.`;
|
|
779
944
|
}
|
|
780
945
|
function isCacheHintsServiceV1(value) {
|
|
781
946
|
const record = asRecord(value);
|
|
@@ -1152,8 +1317,15 @@ function isEnabledEnv(value) {
|
|
|
1152
1317
|
const normalized = value.trim().toLowerCase();
|
|
1153
1318
|
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
|
1154
1319
|
}
|
|
1320
|
+
function featureEnabled(feature, envName, defaultValue, env = process.env, config = persistedCacheOptimizerConfig) {
|
|
1321
|
+
const configured = config.features?.[feature];
|
|
1322
|
+
if (configured !== void 0) return configured;
|
|
1323
|
+
if (feature === "virtualRewrite") return isEnabledEnv(env[envName]);
|
|
1324
|
+
if (feature === "promptRewrite" || feature === "skillCompression" || feature === "openAICacheKey") return !isEnabledEnv(env[envName]);
|
|
1325
|
+
return isEnabledEnv(env[envName]) || defaultValue;
|
|
1326
|
+
}
|
|
1155
1327
|
function isToolOrderEnabled(env = process.env) {
|
|
1156
|
-
return runtimeOptimizerEnabled &&
|
|
1328
|
+
return runtimeOptimizerEnabled && featureEnabled("toolOrder", TOOL_ORDER_ENV, false);
|
|
1157
1329
|
}
|
|
1158
1330
|
function parseFooterStatsMode(value) {
|
|
1159
1331
|
if (typeof value !== "string") return void 0;
|
|
@@ -1171,12 +1343,35 @@ const CACHE_OPTIMIZER_COMMANDS = [
|
|
|
1171
1343
|
"fix",
|
|
1172
1344
|
"rollback"
|
|
1173
1345
|
];
|
|
1174
|
-
const CACHE_OPTIMIZER_CONFIG_ARGUMENTS = [
|
|
1346
|
+
const CACHE_OPTIMIZER_CONFIG_ARGUMENTS = [
|
|
1347
|
+
"footer-mode",
|
|
1348
|
+
"prompt-rewrite",
|
|
1349
|
+
"virtual-rewrite",
|
|
1350
|
+
"skill-compression",
|
|
1351
|
+
"openai-cache-key",
|
|
1352
|
+
"tool-order",
|
|
1353
|
+
"reset"
|
|
1354
|
+
];
|
|
1355
|
+
const CACHE_OPTIMIZER_FEATURE_COMMANDS = [
|
|
1356
|
+
"prompt-rewrite",
|
|
1357
|
+
"virtual-rewrite",
|
|
1358
|
+
"skill-compression",
|
|
1359
|
+
"openai-cache-key",
|
|
1360
|
+
"tool-order"
|
|
1361
|
+
];
|
|
1362
|
+
const CACHE_OPTIMIZER_FEATURE_VALUES = ["on", "off"];
|
|
1175
1363
|
const CACHE_OPTIMIZER_FOOTER_MODES = [
|
|
1176
1364
|
"total",
|
|
1177
1365
|
"session",
|
|
1178
1366
|
"process"
|
|
1179
1367
|
];
|
|
1368
|
+
const FEATURE_COMMAND_MAP = {
|
|
1369
|
+
"prompt-rewrite": "promptRewrite",
|
|
1370
|
+
"virtual-rewrite": "virtualRewrite",
|
|
1371
|
+
"skill-compression": "skillCompression",
|
|
1372
|
+
"openai-cache-key": "openAICacheKey",
|
|
1373
|
+
"tool-order": "toolOrder"
|
|
1374
|
+
};
|
|
1180
1375
|
const CACHE_OPTIMIZER_STATS_ARGUMENTS = ["all", "contributors"];
|
|
1181
1376
|
const CACHE_OPTIMIZER_FIX_ARGUMENTS = ["prompt-cache-key"];
|
|
1182
1377
|
function filterCommandCompletionItems(values, prefix, argumentPath = "") {
|
|
@@ -1210,15 +1405,21 @@ function getCacheOptimizerArgumentCompletions(argumentPrefix) {
|
|
|
1210
1405
|
return filterCommandCompletionItems(CACHE_OPTIMIZER_CONFIG_ARGUMENTS, parts[1], "config");
|
|
1211
1406
|
}
|
|
1212
1407
|
if (parts.length === 3 && parts[1].toLowerCase() === "footer-mode") return filterCommandCompletionItems(CACHE_OPTIMIZER_FOOTER_MODES, parts[2], "config footer-mode");
|
|
1408
|
+
if (parts.length === 3 && CACHE_OPTIMIZER_FEATURE_COMMANDS.includes(parts[1])) return filterCommandCompletionItems(CACHE_OPTIMIZER_FEATURE_VALUES, parts[2], `config ${parts[1]}`);
|
|
1213
1409
|
return null;
|
|
1214
1410
|
}
|
|
1215
1411
|
function parsePersistedCacheOptimizerConfig(value) {
|
|
1216
1412
|
const record = asRecord(value);
|
|
1217
|
-
if (!record || record.version !== 1 && record.version !== 2) return void 0;
|
|
1218
|
-
const allowedTopLevel = new Set(record.version === 1 ? ["version", "footerMode"] : [
|
|
1413
|
+
if (!record || record.version !== 1 && record.version !== 2 && record.version !== 3) return void 0;
|
|
1414
|
+
const allowedTopLevel = new Set(record.version === 1 ? ["version", "footerMode"] : record.version === 2 ? [
|
|
1219
1415
|
"version",
|
|
1220
1416
|
"footerMode",
|
|
1221
1417
|
"promptCacheKey"
|
|
1418
|
+
] : [
|
|
1419
|
+
"version",
|
|
1420
|
+
"footerMode",
|
|
1421
|
+
"promptCacheKey",
|
|
1422
|
+
"features"
|
|
1222
1423
|
]);
|
|
1223
1424
|
if (Object.keys(record).some((key) => !allowedTopLevel.has(key))) return void 0;
|
|
1224
1425
|
const footerMode = parseFooterStatsMode(record.footerMode);
|
|
@@ -1227,6 +1428,17 @@ function parsePersistedCacheOptimizerConfig(value) {
|
|
|
1227
1428
|
version: 1,
|
|
1228
1429
|
...footerMode ? { footerMode } : {}
|
|
1229
1430
|
};
|
|
1431
|
+
const rawFeatures = record.version === 3 ? record.features : void 0;
|
|
1432
|
+
if (rawFeatures !== void 0 && !asRecord(rawFeatures)) return void 0;
|
|
1433
|
+
const featuresRecord = asRecord(rawFeatures);
|
|
1434
|
+
const featureNames = /* @__PURE__ */ new Set([
|
|
1435
|
+
"promptRewrite",
|
|
1436
|
+
"virtualRewrite",
|
|
1437
|
+
"skillCompression",
|
|
1438
|
+
"openAICacheKey",
|
|
1439
|
+
"toolOrder"
|
|
1440
|
+
]);
|
|
1441
|
+
if (featuresRecord && Object.keys(featuresRecord).some((key) => !featureNames.has(key) || typeof featuresRecord[key] !== "boolean")) return void 0;
|
|
1230
1442
|
const rawPromptCacheKey = record.promptCacheKey;
|
|
1231
1443
|
if (rawPromptCacheKey !== void 0 && !asRecord(rawPromptCacheKey)) return void 0;
|
|
1232
1444
|
const promptCacheKey = asRecord(rawPromptCacheKey);
|
|
@@ -1236,16 +1448,20 @@ function parsePersistedCacheOptimizerConfig(value) {
|
|
|
1236
1448
|
const stringOmit = omit;
|
|
1237
1449
|
const uniqueOmit = stringOmit ? [...new Set(stringOmit.map((value) => value.trim()))].sort() : void 0;
|
|
1238
1450
|
return {
|
|
1239
|
-
version: 2,
|
|
1451
|
+
version: record.version === 3 ? 3 : 2,
|
|
1240
1452
|
...footerMode ? { footerMode } : {},
|
|
1241
|
-
...uniqueOmit && uniqueOmit.length > 0 ? { promptCacheKey: { omit: uniqueOmit } } : {}
|
|
1453
|
+
...uniqueOmit && uniqueOmit.length > 0 ? { promptCacheKey: { omit: uniqueOmit } } : {},
|
|
1454
|
+
...featuresRecord ? { features: Object.fromEntries(Object.entries(featuresRecord)) } : {}
|
|
1242
1455
|
};
|
|
1243
1456
|
}
|
|
1244
1457
|
function normalizePersistedCacheOptimizerConfig(value) {
|
|
1245
1458
|
if (!value) return { version: 2 };
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1459
|
+
const features = value.version === 3 ? value.features : void 0;
|
|
1460
|
+
return {
|
|
1461
|
+
version: features ? 3 : 2,
|
|
1462
|
+
...value.footerMode ? { footerMode: value.footerMode } : {},
|
|
1463
|
+
...value.version !== 1 && value.promptCacheKey ? { promptCacheKey: value.promptCacheKey } : {},
|
|
1464
|
+
...features ? { features } : {}
|
|
1249
1465
|
};
|
|
1250
1466
|
}
|
|
1251
1467
|
function readPersistedCacheOptimizerConfig(configPath = CONFIG_FILE_PATH) {
|
|
@@ -1295,7 +1511,7 @@ async function writePersistedFooterModeUnlocked(mode, configPath) {
|
|
|
1295
1511
|
raw = parsePersistedCacheOptimizerConfig(JSON.parse((0, node_fs.readFileSync)(configPath, "utf8")));
|
|
1296
1512
|
targetExists = true;
|
|
1297
1513
|
if (!raw) throw new Error("invalid footer config schema");
|
|
1298
|
-
version = raw.version === 2 ? 2 : 1;
|
|
1514
|
+
version = raw.version === 3 ? 3 : raw.version === 2 ? 2 : 1;
|
|
1299
1515
|
} catch (error) {
|
|
1300
1516
|
if (getErrorCode(error) !== "ENOENT") throw new Error("invalid footer config schema");
|
|
1301
1517
|
}
|
|
@@ -1320,13 +1536,25 @@ async function writePersistedFooterModeUnlocked(mode, configPath) {
|
|
|
1320
1536
|
}
|
|
1321
1537
|
await writePersistedCacheOptimizerConfigUnlocked({
|
|
1322
1538
|
...current,
|
|
1323
|
-
version:
|
|
1539
|
+
version: 3,
|
|
1324
1540
|
footerMode: mode
|
|
1325
1541
|
}, configPath);
|
|
1326
1542
|
}
|
|
1327
1543
|
async function writePersistedFooterMode(mode, configPath = CONFIG_FILE_PATH) {
|
|
1328
1544
|
await withModelsJsonTransactionLock(() => writePersistedFooterModeUnlocked(mode, configPath));
|
|
1329
1545
|
}
|
|
1546
|
+
async function writePersistedFeature(feature, enabled) {
|
|
1547
|
+
const current = readPersistedCacheOptimizerConfig();
|
|
1548
|
+
await writePersistedCacheOptimizerConfig({
|
|
1549
|
+
...current,
|
|
1550
|
+
version: 3,
|
|
1551
|
+
features: {
|
|
1552
|
+
...current.features ?? {},
|
|
1553
|
+
[feature]: enabled
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1556
|
+
setPersistedCacheOptimizerConfig(readPersistedCacheOptimizerConfig());
|
|
1557
|
+
}
|
|
1330
1558
|
function configReceiptBackupPath(receipt, receiptPath = CONFIG_RECEIPT_PATH) {
|
|
1331
1559
|
return (0, node_path.join)((0, node_path.dirname)(receiptPath), receipt.backupFile);
|
|
1332
1560
|
}
|
|
@@ -1706,7 +1934,7 @@ function isDisabledEnv(value) {
|
|
|
1706
1934
|
}
|
|
1707
1935
|
function shouldInjectOpenAIPromptCacheKey() {
|
|
1708
1936
|
if (!runtimeOptimizerEnabled) return false;
|
|
1709
|
-
if (
|
|
1937
|
+
if (!featureEnabled("openAICacheKey", NO_OPENAI_CACHE_KEY_ENV, true)) return false;
|
|
1710
1938
|
if (isDisabledEnv(process.env[OPENAI_CACHE_KEY_ENV])) return false;
|
|
1711
1939
|
return true;
|
|
1712
1940
|
}
|
|
@@ -1722,16 +1950,60 @@ function getOptimizerRuntimeModeLines() {
|
|
|
1722
1950
|
const state = runtimeOptimizerEnabled ? "enabled" : "disabled";
|
|
1723
1951
|
const lines = [];
|
|
1724
1952
|
lines.push(`Runtime state: ${state}`);
|
|
1725
|
-
lines.push(`• Prompt rewrite: ${runtimeOptimizerEnabled &&
|
|
1953
|
+
lines.push(`• Prompt rewrite: ${runtimeOptimizerEnabled && featureEnabled("promptRewrite", NO_PROMPT_REWRITE_ENV, true) ? "on" : "off"}`);
|
|
1954
|
+
lines.push(`• Native virtual rewrite: ${featureEnabled("virtualRewrite", VIRTUAL_REWRITE_ENV, false) ? "opt-in" : "off"}`);
|
|
1955
|
+
lines.push(`• Skill compression: ${featureEnabled("skillCompression", NO_SKILL_COMPRESSION_ENV, true) ? "on" : "off"}`);
|
|
1726
1956
|
lines.push(`• Deterministic tool ordering: ${isToolOrderEnabled() ? "on (verified built-in payloads, opt-in)" : "off"}`);
|
|
1727
1957
|
lines.push(`• OpenAI prompt_cache_key fallback: ${shouldInjectOpenAIPromptCacheKey() ? "on" : "off"}`);
|
|
1728
1958
|
lines.push(`• Footer cache stats: on${runtimeOptimizerEnabled ? "" : " (comparison mode)"}`);
|
|
1729
1959
|
lines.push(`• Compat warnings: ${runtimeOptimizerEnabled ? "on" : "off"}`);
|
|
1730
1960
|
lines.push(`• ${PI_CACHE_RETENTION_ENV}: ${process.env[PI_CACHE_RETENTION_ENV] ?? "(unset)"}`);
|
|
1961
|
+
lines.push(`• Persistent feature overrides: ${Object.keys(persistedCacheOptimizerConfig.features ?? {}).length > 0 ? "configured" : "none"}`);
|
|
1731
1962
|
if (!runtimeOptimizerEnabled) lines.push("This is a current-process switch. Run /reload or restart Pi to return to startup behavior.");
|
|
1732
|
-
else if (
|
|
1963
|
+
else if (!featureEnabled("promptRewrite", NO_PROMPT_REWRITE_ENV, true) || !shouldInjectOpenAIPromptCacheKey()) lines.push("Some features are still disabled by environment variables.");
|
|
1733
1964
|
return lines;
|
|
1734
1965
|
}
|
|
1966
|
+
function formatPersistentFeatureConfig() {
|
|
1967
|
+
const features = persistedCacheOptimizerConfig.features ?? {};
|
|
1968
|
+
const lines = ["Persistent feature configuration:"];
|
|
1969
|
+
const entries = [
|
|
1970
|
+
[
|
|
1971
|
+
"Prompt rewrite",
|
|
1972
|
+
"promptRewrite",
|
|
1973
|
+
NO_PROMPT_REWRITE_ENV,
|
|
1974
|
+
true
|
|
1975
|
+
],
|
|
1976
|
+
[
|
|
1977
|
+
"Native virtual rewrite",
|
|
1978
|
+
"virtualRewrite",
|
|
1979
|
+
VIRTUAL_REWRITE_ENV,
|
|
1980
|
+
false
|
|
1981
|
+
],
|
|
1982
|
+
[
|
|
1983
|
+
"Skill compression",
|
|
1984
|
+
"skillCompression",
|
|
1985
|
+
NO_SKILL_COMPRESSION_ENV,
|
|
1986
|
+
true
|
|
1987
|
+
],
|
|
1988
|
+
[
|
|
1989
|
+
"OpenAI cache key",
|
|
1990
|
+
"openAICacheKey",
|
|
1991
|
+
NO_OPENAI_CACHE_KEY_ENV,
|
|
1992
|
+
true
|
|
1993
|
+
],
|
|
1994
|
+
[
|
|
1995
|
+
"Tool ordering",
|
|
1996
|
+
"toolOrder",
|
|
1997
|
+
TOOL_ORDER_ENV,
|
|
1998
|
+
false
|
|
1999
|
+
]
|
|
2000
|
+
];
|
|
2001
|
+
for (const [label, feature, envName, defaultValue] of entries) {
|
|
2002
|
+
const source = features[feature] !== void 0 ? "config" : process.env[envName] !== void 0 ? "env" : "default";
|
|
2003
|
+
lines.push(`• ${label}: ${featureEnabled(feature, envName, defaultValue) ? "on" : "off"} (${source})`);
|
|
2004
|
+
}
|
|
2005
|
+
return lines.join("\n");
|
|
2006
|
+
}
|
|
1735
2007
|
function formatOptimizerRuntimeMode() {
|
|
1736
2008
|
return getOptimizerRuntimeModeLines().join("\n");
|
|
1737
2009
|
}
|
|
@@ -1776,14 +2048,14 @@ function isOpenAICompatibleProxyApi(api) {
|
|
|
1776
2048
|
function isPiBuiltInLlamaCppModel(model) {
|
|
1777
2049
|
if (lower(model?.provider) !== "llama.cpp" || !isOpenAICompatibleProxyApi(model?.api)) return false;
|
|
1778
2050
|
const compat = getCompat(model);
|
|
1779
|
-
return compat.supportsStore === false && compat.supportsDeveloperRole === false && compat.supportsReasoningEffort === false && compat.
|
|
2051
|
+
return compat.supportsStore === false && compat.supportsDeveloperRole === false && compat.supportsReasoningEffort === false && compat.supportsStrictMode === false && compat.maxTokensField === "max_tokens" && compat.sendSessionAffinityHeaders === void 0 && compat.sessionAffinityFormat === void 0 && compat.supportsLongCacheRetention === void 0;
|
|
1780
2052
|
}
|
|
1781
2053
|
function shouldInjectOpenAIPromptCacheKeyForModel(model) {
|
|
1782
2054
|
return isOpenAICompatibleApi(model?.api);
|
|
1783
2055
|
}
|
|
1784
2056
|
function isPromptCacheKeyOmittedForModel(model, config = persistedCacheOptimizerConfig) {
|
|
1785
2057
|
if (!model || !isOpenAICompatibleApi(model.api)) return false;
|
|
1786
|
-
return config.promptCacheKey?.omit?.includes(modelKey(model)) === true;
|
|
2058
|
+
return "promptCacheKey" in config && config.promptCacheKey?.omit?.includes(modelKey(model)) === true;
|
|
1787
2059
|
}
|
|
1788
2060
|
function setPersistedCacheOptimizerConfig(config) {
|
|
1789
2061
|
persistedCacheOptimizerConfig = normalizePersistedCacheOptimizerConfig(config);
|
|
@@ -2512,6 +2784,13 @@ function snapshotProviderRequestModel(model) {
|
|
|
2512
2784
|
maxTokens: model.maxTokens ?? 0
|
|
2513
2785
|
};
|
|
2514
2786
|
}
|
|
2787
|
+
const MAX_PROVIDER_REQUEST_STATES = 32;
|
|
2788
|
+
function pruneProviderRequestStates(states, max = MAX_PROVIDER_REQUEST_STATES) {
|
|
2789
|
+
while (states.length > max) {
|
|
2790
|
+
const completed = states.findIndex((state) => state.responseReceived);
|
|
2791
|
+
states.splice(completed >= 0 ? completed : 0, 1);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2515
2794
|
function keyForModelExt(model) {
|
|
2516
2795
|
return `${model.provider}/${model.id}`;
|
|
2517
2796
|
}
|
|
@@ -3998,6 +4277,7 @@ const CACHE_PROVIDER_ADAPTERS = [
|
|
|
3998
4277
|
}
|
|
3999
4278
|
];
|
|
4000
4279
|
function selectAdapterForModel(model) {
|
|
4280
|
+
if (isNativeVirtualModel(model)) return void 0;
|
|
4001
4281
|
return CACHE_PROVIDER_ADAPTERS.find((adapter) => adapter.matchesModel(model));
|
|
4002
4282
|
}
|
|
4003
4283
|
function selectAdapterForAssistantMessage(message, model) {
|
|
@@ -4959,6 +5239,7 @@ function describeRouterChannelDiagnostics(model) {
|
|
|
4959
5239
|
}
|
|
4960
5240
|
function getCompatCheckNotApplicableLines(model) {
|
|
4961
5241
|
const api = lower(model.api);
|
|
5242
|
+
if (isNativeVirtualModel(model)) return ["ℹ️ Compat check not applicable for this model.", " Native virtual model: Pi routes each request to a physical model and none has answered on this session branch yet. Send a prompt, then rerun to diagnose the physical model that answered."];
|
|
4962
5243
|
if (isMistralConversationsApi(api)) return ["ℹ️ Compat check not applicable for this model.", " Native Mistral `mistral-conversations` uses provider-native transport; OpenAI-compatible proxy compat flags do not apply."];
|
|
4963
5244
|
if (api === "azure-openai-responses") return ["ℹ️ Compat check not applicable for this model.", " Native Azure OpenAI Responses uses the Responses transport; OpenAI-compatible proxy compat flags do not apply."];
|
|
4964
5245
|
if (api === "openai-codex-responses" || api === "openai-responses" && isOfficialOpenAIBaseUrl(model)) return ["ℹ️ Compat check not applicable for this model.", " Native Responses transports already use Pi core request handling; OpenAI-compatible proxy compat flags do not apply."];
|
|
@@ -7135,6 +7416,8 @@ const __internals_for_tests = {
|
|
|
7135
7416
|
SKILL_COMPRESSION_MIN_COUNT,
|
|
7136
7417
|
NO_PROMPT_REWRITE_ENV,
|
|
7137
7418
|
isEnabledEnv,
|
|
7419
|
+
featureEnabled,
|
|
7420
|
+
writePersistedFeature,
|
|
7138
7421
|
addOpenAIPromptCacheKey,
|
|
7139
7422
|
clampPromptCacheKey,
|
|
7140
7423
|
hasEffectivePromptCacheKey,
|
|
@@ -7152,6 +7435,8 @@ const __internals_for_tests = {
|
|
|
7152
7435
|
normalizeAnthropicCacheControlTtlOrder,
|
|
7153
7436
|
isPiBuiltInLlamaCppModel,
|
|
7154
7437
|
isResponsesPromptRewriteBypassApi,
|
|
7438
|
+
canRewriteNativeVirtualPrompt,
|
|
7439
|
+
VIRTUAL_REWRITE_ENV,
|
|
7155
7440
|
isMistralConversationsApi,
|
|
7156
7441
|
isOpenAIFamilyModel,
|
|
7157
7442
|
isOpenAIFamilyAssistantMessage,
|
|
@@ -7392,6 +7677,16 @@ const __internals_for_tests = {
|
|
|
7392
7677
|
applyConfiguredTransportToModel,
|
|
7393
7678
|
resolveRouteModel,
|
|
7394
7679
|
isVirtualRoutingModel,
|
|
7680
|
+
PI_VIRTUAL_MODEL_API,
|
|
7681
|
+
isNativeVirtualModel,
|
|
7682
|
+
findNativeVirtualDispatches,
|
|
7683
|
+
resolveNativeVirtualRouteModel,
|
|
7684
|
+
resolveNativeVirtualRequestModel,
|
|
7685
|
+
getProviderPayloadModelId,
|
|
7686
|
+
getCompatCheckNotApplicableLines,
|
|
7687
|
+
describeNativeVirtualRouteNote,
|
|
7688
|
+
pruneProviderRequestStates,
|
|
7689
|
+
MAX_PROVIDER_REQUEST_STATES,
|
|
7395
7690
|
installCacheHintsService,
|
|
7396
7691
|
getCacheHintsService,
|
|
7397
7692
|
markOptimizerOwnedCacheHintsService,
|
|
@@ -7895,6 +8190,23 @@ function pi_cache_optimizer_default(pi) {
|
|
|
7895
8190
|
function hasExplicitLongRetentionOptIn(model) {
|
|
7896
8191
|
return hasExplicitLongRetentionOptInFromConfig(readEffectiveCompatConfig(), model.provider, model.id);
|
|
7897
8192
|
}
|
|
8193
|
+
/**
|
|
8194
|
+
* Request treatment that before_provider_request derives from a model's
|
|
8195
|
+
* identity. A native virtual request whose dispatched id matches several
|
|
8196
|
+
* credentialed providers is resolved only when this key agrees for all of
|
|
8197
|
+
* them, so no provider-specific decision is applied on a guess.
|
|
8198
|
+
*/
|
|
8199
|
+
function requestPolicyKey(model) {
|
|
8200
|
+
const key = modelKey(model);
|
|
8201
|
+
return JSON.stringify([
|
|
8202
|
+
model.api ?? "",
|
|
8203
|
+
isOfficialOpenAIBaseUrl(model),
|
|
8204
|
+
hasExplicitLongRetentionOptIn(model),
|
|
8205
|
+
promptCacheRetention400Models.has(key),
|
|
8206
|
+
anthropicTtlOrderErrorModels.has(key),
|
|
8207
|
+
isPromptCacheKeyOmittedForModel(model)
|
|
8208
|
+
]);
|
|
8209
|
+
}
|
|
7898
8210
|
pi.on("session_start", async (event, ctx) => {
|
|
7899
8211
|
if (runtimeOptimizerEnabled) requestLongCacheRetention();
|
|
7900
8212
|
await restoreCacheStats(event.reason, ctx);
|
|
@@ -7904,7 +8216,8 @@ function pi_cache_optimizer_default(pi) {
|
|
|
7904
8216
|
} catch {}
|
|
7905
8217
|
await publishStatus(ctx);
|
|
7906
8218
|
});
|
|
7907
|
-
pi.on("tool_execution_end", async (
|
|
8219
|
+
pi.on("tool_execution_end", async (event, ctx) => {
|
|
8220
|
+
if (isNonEmptyString(event?.parentToolCallId)) return;
|
|
7908
8221
|
await refreshShardAggregate();
|
|
7909
8222
|
await publishStatus(ctx);
|
|
7910
8223
|
});
|
|
@@ -7938,8 +8251,9 @@ function pi_cache_optimizer_default(pi) {
|
|
|
7938
8251
|
const routeSnapshot = resolveActiveRouteSnapshot(_ctx.model, _ctx);
|
|
7939
8252
|
const model = (routeSnapshot ? findModelInRegistry(_ctx.modelRegistry, routeSnapshot.provider, routeSnapshot.modelId) ?? routeSnapshotToPiModel(routeSnapshot, _ctx.model) : void 0) ?? _ctx.model;
|
|
7940
8253
|
if (model && isResponsesPromptRewriteBypassApi(model.api)) return {};
|
|
8254
|
+
if (isNativeVirtualModel(_ctx.model) && !canRewriteNativeVirtualPrompt(_ctx.model, _ctx)) return {};
|
|
7941
8255
|
if (!runtimeOptimizerEnabled) return {};
|
|
7942
|
-
if (
|
|
8256
|
+
if (!featureEnabled("promptRewrite", NO_PROMPT_REWRITE_ENV, true)) return {};
|
|
7943
8257
|
const strippedPrompt = stripSessionOverviewChurn(event.systemPrompt);
|
|
7944
8258
|
const compressedPrompt = compressSkillsInSystemPrompt(strippedPrompt, event.systemPromptOptions);
|
|
7945
8259
|
const optimized = optimizeSystemPrompt(compressedPrompt, event.systemPromptOptions);
|
|
@@ -7978,17 +8292,23 @@ function pi_cache_optimizer_default(pi) {
|
|
|
7978
8292
|
return {};
|
|
7979
8293
|
});
|
|
7980
8294
|
pi.on("before_provider_headers", (event, ctx) => {
|
|
8295
|
+
if (isNativeVirtualModel(ctx.model)) return;
|
|
7981
8296
|
const requestModel = resolveRouteModel(ctx.model, ctx) ?? ctx.model;
|
|
7982
8297
|
addEffectiveSessionAffinityHeaders(event.headers, requestModel, ctx.sessionManager.getSessionId());
|
|
7983
8298
|
});
|
|
7984
8299
|
pi.on("before_provider_request", (event, ctx) => {
|
|
7985
|
-
const
|
|
8300
|
+
const nativeVirtualRequest = resolveNativeVirtualRequestModel(ctx.model, event.payload, ctx, requestPolicyKey);
|
|
8301
|
+
const requestModel = isNativeVirtualModel(ctx.model) ? nativeVirtualRequest?.model ?? ctx.model : resolveRouteModel(ctx.model, ctx) ?? ctx.model;
|
|
7986
8302
|
const snapshot = snapshotProviderRequestModel(requestModel);
|
|
7987
|
-
if (snapshot)
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
8303
|
+
if (snapshot) {
|
|
8304
|
+
providerRequestStates.push({
|
|
8305
|
+
model: snapshot,
|
|
8306
|
+
responseReceived: false,
|
|
8307
|
+
correlationAmbiguous: false,
|
|
8308
|
+
identityAmbiguous: isNativeVirtualModel(ctx.model) && (!nativeVirtualRequest || nativeVirtualRequest.identityAmbiguous)
|
|
8309
|
+
});
|
|
8310
|
+
pruneProviderRequestStates(providerRequestStates);
|
|
8311
|
+
}
|
|
7992
8312
|
let requestPayload = event.payload;
|
|
7993
8313
|
let toolOrderChanged = false;
|
|
7994
8314
|
if (isToolOrderEnabled() && isToolOrderingEligibleModel(requestModel)) {
|
|
@@ -8021,7 +8341,7 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8021
8341
|
else for (const state of pendingStates) state.correlationAmbiguous = true;
|
|
8022
8342
|
}
|
|
8023
8343
|
if (responseState) responseState.responseReceived = true;
|
|
8024
|
-
const model = responseState
|
|
8344
|
+
const model = responseState ? responseState.identityAmbiguous ? void 0 : responseState.model : pendingStates.length === 0 && !isNativeVirtualModel(ctx.model) ? resolveRouteModel(ctx.model, ctx) ?? ctx.model : void 0;
|
|
8025
8345
|
if (!runtimeOptimizerEnabled || !model) return;
|
|
8026
8346
|
if (isReasoningProtocolRejectionSignalApplicable(model) && event.status === 400 && hasReasoningProtocolRejectionSignal(event.headers)) await notifyReasoningProtocolObservation(model, ctx, reasoningProtocolRejectedModels, warnedReasoningProtocolRejectedModels);
|
|
8027
8347
|
if (event.status === 400 && isPromptCacheKeyUnsupportedApplicable(model) && hasPromptCacheKeyUnsupportedSignal(event.headers)) {
|
|
@@ -8073,9 +8393,10 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8073
8393
|
model: void 0,
|
|
8074
8394
|
ambiguous: false
|
|
8075
8395
|
};
|
|
8396
|
+
const ambiguous = (state.correlationAmbiguous || state.identityAmbiguous === true) && explicitIndex < 0;
|
|
8076
8397
|
return {
|
|
8077
|
-
model:
|
|
8078
|
-
ambiguous
|
|
8398
|
+
model: ambiguous ? void 0 : state.model,
|
|
8399
|
+
ambiguous
|
|
8079
8400
|
};
|
|
8080
8401
|
})() : {
|
|
8081
8402
|
model: void 0,
|
|
@@ -8127,12 +8448,15 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8127
8448
|
}
|
|
8128
8449
|
}
|
|
8129
8450
|
}
|
|
8130
|
-
const
|
|
8451
|
+
const nativeVirtualDispatch = isNativeVirtualModel(ctx.model) ? nativeVirtualDispatchFromMessage(event.message) : void 0;
|
|
8452
|
+
const nativeVirtualMessageModel = nativeVirtualDispatch ? nativeVirtualDispatchToModel(nativeVirtualDispatch, ctx) : void 0;
|
|
8453
|
+
const adapter = selectAdapterForAssistantMessage(event.message, nativeVirtualMessageModel ?? ctx.model);
|
|
8131
8454
|
if (!adapter) return;
|
|
8132
8455
|
if (msgRecord?.stopReason === "error" || msgRecord?.stopReason === "aborted") return;
|
|
8133
8456
|
const usage = adapter.normalizeUsage(event.message);
|
|
8134
8457
|
let statsModel = modelFromAssistantMessage(event.message, ctx.model) ?? ctx.model;
|
|
8135
8458
|
statsModel = consolidateDirectProviderStatsModel(statsModel, ctx.model, ctx);
|
|
8459
|
+
if (nativeVirtualMessageModel) statsModel = nativeVirtualMessageModel;
|
|
8136
8460
|
let routedModelChanged = false;
|
|
8137
8461
|
if (isVirtualRoutingModel(ctx.model, ctx) && statsModel && !isVirtualRoutingModel(statsModel, ctx)) {
|
|
8138
8462
|
const nextRoutedModel = {
|
|
@@ -8217,7 +8541,11 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8217
8541
|
const adapter = selectAdapterForModel(model);
|
|
8218
8542
|
const sk = model ? sessionModelKey(model) : void 0;
|
|
8219
8543
|
const lowHitLines = buildLowHitDiagnosis(model, adapter, model ? cacheStatsTotalsByModel[modelKey(model)] : void 0, sk ? getRecentSamples(sk) : []);
|
|
8220
|
-
const fullDiagnosis =
|
|
8544
|
+
const fullDiagnosis = [
|
|
8545
|
+
describeNativeVirtualRouteNote(selectedModel, model),
|
|
8546
|
+
diagnosis,
|
|
8547
|
+
...lowHitLines
|
|
8548
|
+
].filter((line) => line !== void 0).join("\n");
|
|
8221
8549
|
cmdCtx.ui.notify(fullDiagnosis, "info");
|
|
8222
8550
|
} else if (subcommand === "stats") {
|
|
8223
8551
|
const aggregate = await refreshShardAggregate();
|
|
@@ -8232,13 +8560,48 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8232
8560
|
} else if (subcommand === "config") {
|
|
8233
8561
|
const configKey = commandParts[1];
|
|
8234
8562
|
const requestedMode = commandParts[2];
|
|
8563
|
+
const feature = configKey ? FEATURE_COMMAND_MAP[configKey] : void 0;
|
|
8564
|
+
if (feature && (requestedMode === "on" || requestedMode === "off")) {
|
|
8565
|
+
try {
|
|
8566
|
+
await writePersistedFeature(feature, requestedMode === "on");
|
|
8567
|
+
lastStatusText = void 0;
|
|
8568
|
+
await publishStatus(cmdCtx, model);
|
|
8569
|
+
cmdCtx.ui.notify(`✅ ${configKey} set to ${requestedMode}. Persistent config overrides its environment variable.`, "info");
|
|
8570
|
+
} catch (error) {
|
|
8571
|
+
cmdCtx.ui.notify(`❌ Could not update ${configKey}: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
8572
|
+
}
|
|
8573
|
+
return;
|
|
8574
|
+
}
|
|
8575
|
+
if (configKey === "reset") {
|
|
8576
|
+
try {
|
|
8577
|
+
await writePersistedCacheOptimizerConfig({
|
|
8578
|
+
version: 2,
|
|
8579
|
+
footerMode: persistedFooterStatsMode,
|
|
8580
|
+
promptCacheKey: persistedCacheOptimizerConfig.promptCacheKey
|
|
8581
|
+
});
|
|
8582
|
+
setPersistedCacheOptimizerConfig(readPersistedCacheOptimizerConfig());
|
|
8583
|
+
cmdCtx.ui.notify("✅ Feature configuration reset. Environment variables now apply again.", "info");
|
|
8584
|
+
} catch (error) {
|
|
8585
|
+
cmdCtx.ui.notify(`❌ Could not reset feature configuration: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
8586
|
+
}
|
|
8587
|
+
return;
|
|
8588
|
+
}
|
|
8589
|
+
if (!configKey) {
|
|
8590
|
+
cmdCtx.ui.notify(formatPersistentFeatureConfig() + `\n• Footer mode: ${resolveFooterStatsMode(persistedFooterStatsMode).mode}
|
|
8591
|
+
|
|
8592
|
+
Usage: /cache-optimizer config <feature> on|off | footer-mode total|session|process | reset`, "info");
|
|
8593
|
+
return;
|
|
8594
|
+
}
|
|
8235
8595
|
if (configKey !== "footer-mode" || !requestedMode || ![
|
|
8236
8596
|
"session",
|
|
8237
8597
|
"total",
|
|
8238
8598
|
"process"
|
|
8239
8599
|
].includes(requestedMode)) {
|
|
8240
8600
|
const resolved = resolveFooterStatsMode(persistedFooterStatsMode);
|
|
8241
|
-
cmdCtx.ui.notify(`Usage: /cache-optimizer config footer-mode total|session|process
|
|
8601
|
+
cmdCtx.ui.notify(`Usage: /cache-optimizer config footer-mode total|session|process
|
|
8602
|
+
/cache-optimizer config prompt-rewrite|virtual-rewrite|skill-compression|openai-cache-key|tool-order on|off
|
|
8603
|
+
/cache-optimizer config reset
|
|
8604
|
+
Current footer mode: ${resolved.mode} (${resolved.source})`, "info");
|
|
8242
8605
|
return;
|
|
8243
8606
|
}
|
|
8244
8607
|
const nextMode = requestedMode;
|
|
@@ -8258,8 +8621,10 @@ function pi_cache_optimizer_default(pi) {
|
|
|
8258
8621
|
return;
|
|
8259
8622
|
}
|
|
8260
8623
|
const compatResult = buildCompatDiagnosis(model);
|
|
8261
|
-
|
|
8262
|
-
|
|
8624
|
+
const compatRouteNote = describeNativeVirtualRouteNote(selectedModel, model);
|
|
8625
|
+
const withRouteNote = (text) => compatRouteNote ? `${compatRouteNote}\n${text}` : text;
|
|
8626
|
+
if (compatResult) cmdCtx.ui.notify(withRouteNote(compatResult), "warning");
|
|
8627
|
+
else cmdCtx.ui.notify(withRouteNote(isAdaptiveThinkingCompatApplicable(model) || isDeepSeekCompatCheckApplicable(model) || isCompatCheckApplicable(model) ? "✅ Compat fully configured." : getCompatCheckNotApplicableLines(model).join("\n")), "info");
|
|
8263
8628
|
} else if (subcommand === "rollback") {
|
|
8264
8629
|
if (!model) {
|
|
8265
8630
|
cmdCtx.ui.notify("No active model selected. Select a model first with /model or pi --model.", "warning");
|
|
@@ -8677,7 +9042,9 @@ Run /cache-optimizer fix prompt-cache-key in Pi's interactive UI for ${modelKey(
|
|
|
8677
9042
|
diagnosis.push(" stats all — Show detailed totals for every model across all local sessions");
|
|
8678
9043
|
diagnosis.push(" stats contributors — Show per-session contributors for the active model");
|
|
8679
9044
|
diagnosis.push(" compat — Show compat suggestion with edit location");
|
|
9045
|
+
diagnosis.push(" config prompt-rewrite|virtual-rewrite|skill-compression|openai-cache-key|tool-order on|off — Persist feature settings");
|
|
8680
9046
|
diagnosis.push(" config footer-mode total|session|process — Persist the footer stats mode");
|
|
9047
|
+
diagnosis.push(" config reset — Remove persistent feature overrides");
|
|
8681
9048
|
diagnosis.push(" fix — Auto-fix compat issues (writes models.json or extension config, requires UI)");
|
|
8682
9049
|
diagnosis.push(" fix prompt-cache-key — Explicitly omit prompt_cache_key for the active model");
|
|
8683
9050
|
diagnosis.push(" rollback — Undo the latest confirmed fix (requires UI confirmation)");
|
|
@@ -8713,4 +9080,4 @@ Run /cache-optimizer fix prompt-cache-key in Pi's interactive UI for ${modelKey(
|
|
|
8713
9080
|
exports.__internals_for_tests = __internals_for_tests;
|
|
8714
9081
|
exports.default = pi_cache_optimizer_default;
|
|
8715
9082
|
|
|
8716
|
-
//# sourceMappingURL=pi-cache-optimizer-
|
|
9083
|
+
//# sourceMappingURL=pi-cache-optimizer-DSED41mZ.cjs.map
|