@agimon-ai/po-cache 0.0.0-alpha.2 → 0.0.0-alpha.4
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/env.mjs +1 -2
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.d.mts +1 -1
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/server.cjs +117 -97
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +1 -1
- package/dist/extensions/server.mjs +119 -99
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/{promptCacheTelemetry-BU1fIhb8.cjs → promptCacheTelemetry-DeN4LdSo.cjs} +6 -6
- package/dist/promptCacheTelemetry-DeN4LdSo.cjs.map +1 -0
- package/dist/{promptCacheTelemetry-CguL1ZqT.mjs → promptCacheTelemetry-LM1cAPk8.mjs} +5 -5
- package/dist/promptCacheTelemetry-LM1cAPk8.mjs.map +1 -0
- package/package.json +11 -11
- package/dist/promptCacheTelemetry-BU1fIhb8.cjs.map +0 -1
- package/dist/promptCacheTelemetry-CguL1ZqT.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region generated/server.d.ts
|
|
2
|
-
export declare const facet: import("@agimon-ai/po-core/serverFacet").
|
|
2
|
+
export declare const facet: import("@agimon-ai/po-core/serverFacet").PoServerFacet;
|
|
3
3
|
//#endregion
|
|
4
4
|
export { facet as default };
|
|
5
5
|
//# sourceMappingURL=server.d.mts.map
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { a as PO_PROMPT_CACHE_ROOT_SESSION_ENV, i as PO_PROMPT_CACHE_PARENT_NAMESPACE_ENV, r as PO_PROMPT_CACHE_CHILD_PROJECTION_ENV } from "../environment-vyw-n84h.mjs";
|
|
2
|
-
import { c as createPromptCacheModelFingerprint, h as sha256Base64Url, i as rewritePromptCacheKey, l as createRootSessionIdentity, o as createParentPromptCacheNamespace, p as PromptCacheTelemetryService, s as createPromptCacheKey, t as PromptCacheTelemetry, u as canonicalJson } from "../promptCacheTelemetry-
|
|
2
|
+
import { c as createPromptCacheModelFingerprint, h as sha256Base64Url, i as rewritePromptCacheKey, l as createRootSessionIdentity, o as createParentPromptCacheNamespace, p as PromptCacheTelemetryService, s as createPromptCacheKey, t as PromptCacheTelemetry, u as canonicalJson } from "../promptCacheTelemetry-LM1cAPk8.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import { composeServerProviderOverrides, defineServerPlugin } from "@agimon-ai/po-core/serverFacet";
|
|
5
5
|
import { composeRootHooks, defineHook, defineRoot } from "@agimon-ai/po-core/extensionFile";
|
|
6
|
+
import { BACKGROUND_CONTEXT, createSerialRunner, getOrThrow, nodeHost, readTextIfExists, requirePoFs, writeFileAtomic } from "@agimon-ai/po-core/platform";
|
|
6
7
|
import { getSessionHarnessState } from "@agimon-ai/po-config/harnessStore";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
8
|
+
import { PO_MINOR_MODE_CATALOG_SERVICE, readMinorModeCatalog } from "@agimon-ai/po-minor-mode";
|
|
9
|
+
import { join } from "node:path";
|
|
9
10
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
10
|
-
import { readFileSync, statSync } from "node:fs";
|
|
11
|
-
import { lstat, mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
11
|
//#region src/services/environment/index.ts
|
|
14
12
|
const environmentLeases = /* @__PURE__ */ new WeakMap();
|
|
15
13
|
/** Same-value session leases restore only after the final owner leaves. External writes win. */
|
|
@@ -177,7 +175,7 @@ function createCacheRuntime(dependencies, environment) {
|
|
|
177
175
|
return parentNamespace;
|
|
178
176
|
};
|
|
179
177
|
const plugin = (cordis) => {
|
|
180
|
-
cordis.inject([
|
|
178
|
+
cordis.inject([PO_MINOR_MODE_CATALOG_SERVICE], (context) => {
|
|
181
179
|
if (isProjectedChild) return void 0;
|
|
182
180
|
const catalog = readMinorModeCatalog(context);
|
|
183
181
|
if (!catalog) return void 0;
|
|
@@ -212,8 +210,19 @@ function createCacheRuntime(dependencies, environment) {
|
|
|
212
210
|
};
|
|
213
211
|
}
|
|
214
212
|
//#endregion
|
|
213
|
+
//#region src/services/agentDirectory/index.ts
|
|
214
|
+
/** Pi's agent directory, where the optimizer keeps its state; the edge build swaps in `index.edge.ts`. */
|
|
215
|
+
function defaultAgentDirectory() {
|
|
216
|
+
return getAgentDir();
|
|
217
|
+
}
|
|
218
|
+
//#endregion
|
|
215
219
|
//#region src/services/optimizerSupport/index.ts
|
|
216
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Optimizer state under `STATE_DIR`, read and written through the injected file system. Synchronous
|
|
222
|
+
* readers (`getCompat`, `footerStatsMode`) use the files as of the last `refreshFileConfig()`.
|
|
223
|
+
*/
|
|
224
|
+
function createOptimizerSupport(STATE_DIR, environment, fs) {
|
|
225
|
+
const io = BACKGROUND_CONTEXT;
|
|
217
226
|
const MODELS_JSON_PATH = join(STATE_DIR, "models.json");
|
|
218
227
|
function isVirtualRoutingModel(model) {
|
|
219
228
|
return !!model && (isNativeVirtualModel(model) || model.provider.toLowerCase() === "router");
|
|
@@ -492,21 +501,20 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
492
501
|
}
|
|
493
502
|
return true;
|
|
494
503
|
}
|
|
504
|
+
/** Keyed by the file text, so an unchanged models.json is not parsed again. */
|
|
495
505
|
let modelsConfigCache;
|
|
496
|
-
function
|
|
506
|
+
async function refreshModelsConfig() {
|
|
507
|
+
let text;
|
|
497
508
|
try {
|
|
498
|
-
|
|
499
|
-
return `${info.dev}:${info.ino}:${info.size}:${info.mtimeMs}:${info.ctimeMs}`;
|
|
509
|
+
text = await readTextIfExists(fs, MODELS_JSON_PATH, io);
|
|
500
510
|
} catch {
|
|
501
|
-
|
|
511
|
+
text = void 0;
|
|
502
512
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const signature = getModelsConfigSignature();
|
|
506
|
-
if (modelsConfigCache?.signature === signature) return modelsConfigCache.value;
|
|
513
|
+
const signature = text ?? "missing";
|
|
514
|
+
if (modelsConfigCache?.signature === signature) return;
|
|
507
515
|
let value;
|
|
508
|
-
if (
|
|
509
|
-
const parsed = parseJsonc(
|
|
516
|
+
if (text !== void 0) try {
|
|
517
|
+
const parsed = parseJsonc(text);
|
|
510
518
|
value = isValidModelsConfigForEffectiveCompat(parsed) ? parsed : void 0;
|
|
511
519
|
} catch {
|
|
512
520
|
value = void 0;
|
|
@@ -515,17 +523,24 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
515
523
|
signature,
|
|
516
524
|
value
|
|
517
525
|
};
|
|
518
|
-
|
|
526
|
+
}
|
|
527
|
+
/** The models.json compat config as of the last refresh. */
|
|
528
|
+
function effectiveCompatConfig() {
|
|
529
|
+
return modelsConfigCache?.value;
|
|
530
|
+
}
|
|
531
|
+
async function readEffectiveCompatConfig() {
|
|
532
|
+
await refreshModelsConfig();
|
|
533
|
+
return effectiveCompatConfig();
|
|
519
534
|
}
|
|
520
535
|
function getCompat(model) {
|
|
521
536
|
if (!model) return {};
|
|
522
|
-
return resolveEffectiveCompatFromConfig(model,
|
|
537
|
+
return resolveEffectiveCompatFromConfig(model, effectiveCompatConfig());
|
|
523
538
|
}
|
|
524
539
|
function joinDisplayPath(base, child, platform = process.platform) {
|
|
525
540
|
const sep = platform.startsWith("win") ? "\\" : "/";
|
|
526
541
|
return `${base.replace(/[\\/]+$/, "")}${sep}${child}`;
|
|
527
542
|
}
|
|
528
|
-
function getAgentDirDisplayPath(platform = process.platform, agentDir = STATE_DIR, homeDir =
|
|
543
|
+
function getAgentDirDisplayPath(platform = process.platform, agentDir = STATE_DIR, homeDir = nodeHost.homeDirectory()) {
|
|
529
544
|
const sep = platform.startsWith("win") ? "\\" : "/";
|
|
530
545
|
const normalizedAgentDir = agentDir.replace(/[\\/]+/g, sep);
|
|
531
546
|
const normalizedHomeDir = homeDir.replace(/[\\/]+/g, sep).replace(/[\\/]+$/, "");
|
|
@@ -537,7 +552,7 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
537
552
|
}
|
|
538
553
|
return normalizedAgentDir;
|
|
539
554
|
}
|
|
540
|
-
function getModelsJsonDisplayPath(platform = process.platform, agentDir = STATE_DIR, homeDir =
|
|
555
|
+
function getModelsJsonDisplayPath(platform = process.platform, agentDir = STATE_DIR, homeDir = nodeHost.homeDirectory()) {
|
|
541
556
|
return joinDisplayPath(getAgentDirDisplayPath(platform, agentDir, homeDir), "models.json", platform);
|
|
542
557
|
}
|
|
543
558
|
function parseFooterStatsMode(value) {
|
|
@@ -601,11 +616,13 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
601
616
|
...features ? { features } : {}
|
|
602
617
|
};
|
|
603
618
|
}
|
|
604
|
-
function readPersistedCacheOptimizerConfig(configPath = CONFIG_FILE_PATH) {
|
|
619
|
+
async function readPersistedCacheOptimizerConfig(configPath = CONFIG_FILE_PATH) {
|
|
605
620
|
try {
|
|
606
|
-
|
|
621
|
+
const text = await readTextIfExists(fs, configPath, io);
|
|
622
|
+
if (text === void 0) return { version: 2 };
|
|
623
|
+
return normalizePersistedCacheOptimizerConfig(parsePersistedCacheOptimizerConfig(JSON.parse(text)));
|
|
607
624
|
} catch (error) {
|
|
608
|
-
|
|
625
|
+
console.warn(`${LOG_PREFIX}: failed to read optimizer config; using defaults`, error);
|
|
609
626
|
return { version: 2 };
|
|
610
627
|
}
|
|
611
628
|
}
|
|
@@ -626,7 +643,17 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
626
643
|
function footerStatsMode(env = environment, configuredMode = persistedFooterStatsMode) {
|
|
627
644
|
return resolveFooterStatsMode(configuredMode, env).mode;
|
|
628
645
|
}
|
|
629
|
-
|
|
646
|
+
/** Read once, on the first refresh, like the original read at construction. */
|
|
647
|
+
let persistedConfigLoaded = false;
|
|
648
|
+
let persistedFooterStatsMode;
|
|
649
|
+
/** Loads the persisted optimizer config once and rereads models.json; call before the synchronous readers. */
|
|
650
|
+
async function refreshFileConfig() {
|
|
651
|
+
if (!persistedConfigLoaded) {
|
|
652
|
+
persistedConfigLoaded = true;
|
|
653
|
+
persistedFooterStatsMode = (await readPersistedCacheOptimizerConfig()).footerMode;
|
|
654
|
+
}
|
|
655
|
+
await refreshModelsConfig();
|
|
656
|
+
}
|
|
630
657
|
function isAssistantMessage(message) {
|
|
631
658
|
return asRecord(message)?.role === "assistant";
|
|
632
659
|
}
|
|
@@ -1254,7 +1281,7 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
1254
1281
|
baseUrl: "",
|
|
1255
1282
|
[ROUTED_FALLBACK_MODEL_SYMBOL]: true
|
|
1256
1283
|
};
|
|
1257
|
-
const provider = asRecord(asRecord(asRecord(
|
|
1284
|
+
const provider = asRecord(asRecord(asRecord(effectiveCompatConfig())?.providers)?.[model.provider]);
|
|
1258
1285
|
const customModel = findLastExactModelDefinition(Array.isArray(provider?.models) ? provider.models : void 0, model.id);
|
|
1259
1286
|
const configuredApi = customModel?.api ?? provider?.api;
|
|
1260
1287
|
const configuredBaseUrl = customModel?.baseUrl ?? provider?.baseUrl;
|
|
@@ -2779,14 +2806,6 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
2779
2806
|
stats: best.stats
|
|
2780
2807
|
} : void 0;
|
|
2781
2808
|
}
|
|
2782
|
-
function createSerializedAsyncRunner() {
|
|
2783
|
-
let tail = Promise.resolve();
|
|
2784
|
-
return (operation) => {
|
|
2785
|
-
const result = tail.then(operation);
|
|
2786
|
-
tail = result.catch(() => void 0);
|
|
2787
|
-
return result;
|
|
2788
|
-
};
|
|
2789
|
-
}
|
|
2790
2809
|
function modelEpochPath(modelKeyValue) {
|
|
2791
2810
|
return join(SHARD_MODEL_EPOCH_DIR, `${createHash("sha256").update(modelKeyValue).digest("hex")}.json`);
|
|
2792
2811
|
}
|
|
@@ -2799,7 +2818,7 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
2799
2818
|
}
|
|
2800
2819
|
async function readEpochFile(path, fallback) {
|
|
2801
2820
|
try {
|
|
2802
|
-
return parseEpochRecord(JSON.parse(await
|
|
2821
|
+
return parseEpochRecord(JSON.parse(getOrThrow(await fs.readTextFile(path, io)))) ?? fallback;
|
|
2803
2822
|
} catch {
|
|
2804
2823
|
return fallback;
|
|
2805
2824
|
}
|
|
@@ -2811,14 +2830,11 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
2811
2830
|
return readEpochFile(modelEpochPath(modelKeyValue), initialEpoch(`model:${modelKeyValue}`));
|
|
2812
2831
|
}
|
|
2813
2832
|
async function writeStatsEpoch(path, epoch) {
|
|
2814
|
-
await
|
|
2815
|
-
const tempPath = `${path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
|
|
2816
|
-
await writeFile(tempPath, JSON.stringify({
|
|
2833
|
+
await writeFileAtomic(fs, path, JSON.stringify({
|
|
2817
2834
|
version: 1,
|
|
2818
2835
|
epoch,
|
|
2819
2836
|
createdAt: Date.now()
|
|
2820
|
-
}, null, 2) + "\n",
|
|
2821
|
-
await rename(tempPath, path);
|
|
2837
|
+
}, null, 2) + "\n", io);
|
|
2822
2838
|
}
|
|
2823
2839
|
async function advanceGlobalStatsEpoch() {
|
|
2824
2840
|
const epoch = `${Date.now()}-${randomUUID()}`;
|
|
@@ -2874,27 +2890,34 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
2874
2890
|
};
|
|
2875
2891
|
}
|
|
2876
2892
|
async function writeStatsShardV7(path, shard) {
|
|
2877
|
-
await
|
|
2878
|
-
const tempPath = `${path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
|
|
2879
|
-
await writeFile(tempPath, JSON.stringify(shard, null, 2) + "\n", "utf8");
|
|
2880
|
-
await rename(tempPath, path);
|
|
2893
|
+
await writeFileAtomic(fs, path, JSON.stringify(shard, null, 2) + "\n", io);
|
|
2881
2894
|
}
|
|
2882
|
-
|
|
2883
|
-
|
|
2895
|
+
/** Entries of `directory`, or undefined when it does not exist. Entries removed while listing are skipped. */
|
|
2896
|
+
async function listDirectoryEntries(directory) {
|
|
2897
|
+
const opened = await fs.openDirReader(directory, io);
|
|
2898
|
+
if (!opened.ok && opened.error.code === "not_found") return void 0;
|
|
2899
|
+
const reader = getOrThrow(opened);
|
|
2884
2900
|
try {
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2901
|
+
const entries = [];
|
|
2902
|
+
for (;;) {
|
|
2903
|
+
const page = getOrThrow(await reader.next(256, io));
|
|
2904
|
+
entries.push(...page.entries);
|
|
2905
|
+
if (page.done) return entries;
|
|
2906
|
+
}
|
|
2907
|
+
} finally {
|
|
2908
|
+
await reader.close(io);
|
|
2889
2909
|
}
|
|
2910
|
+
}
|
|
2911
|
+
async function readValidStatsShardsV7(directory = SHARD_FILES_DIR) {
|
|
2912
|
+
const entries = await listDirectoryEntries(directory);
|
|
2913
|
+
if (!entries) return [];
|
|
2890
2914
|
const shards = [];
|
|
2891
|
-
for (const name of
|
|
2915
|
+
for (const { name, kind } of entries) {
|
|
2892
2916
|
if (!/^[0-9a-f-]+\.json$/i.test(name)) continue;
|
|
2893
2917
|
const path = join(directory, name);
|
|
2894
2918
|
try {
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
const parsed = parsePersistedStatsShardV7(JSON.parse(await readFile(path, "utf8")));
|
|
2919
|
+
if (kind !== "file") continue;
|
|
2920
|
+
const parsed = parsePersistedStatsShardV7(JSON.parse(getOrThrow(await fs.readTextFile(path, io))));
|
|
2898
2921
|
const filenameInstanceId = name.slice(0, -5);
|
|
2899
2922
|
if (parsed && parsed.instanceId === filenameInstanceId) shards.push(parsed);
|
|
2900
2923
|
} catch {}
|
|
@@ -2965,73 +2988,63 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
2965
2988
|
}
|
|
2966
2989
|
}
|
|
2967
2990
|
async function removeLegacyStatsFiles() {
|
|
2968
|
-
for (const path of [STATE_FILE_PATH, LEGACY_STATE_FILE_PATH])
|
|
2969
|
-
await
|
|
2970
|
-
|
|
2971
|
-
if (getErrorCode(error) !== "ENOENT") console.warn(`${LOG_PREFIX}: failed to remove obsolete stats file ${path}`, error);
|
|
2991
|
+
for (const path of [STATE_FILE_PATH, LEGACY_STATE_FILE_PATH]) {
|
|
2992
|
+
const removed = await fs.remove(path, { force: true }, io);
|
|
2993
|
+
if (!removed.ok) console.warn(`${LOG_PREFIX}: failed to remove obsolete stats file ${path}`, removed.error);
|
|
2972
2994
|
}
|
|
2973
2995
|
}
|
|
2974
2996
|
async function cleanupStatsShardsV7(now = Date.now(), directory = SHARD_FILES_DIR) {
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
names = await readdir(directory);
|
|
2978
|
-
} catch (error) {
|
|
2979
|
-
return getErrorCode(error) === "ENOENT" ? 0 : Promise.reject(error);
|
|
2980
|
-
}
|
|
2997
|
+
const entries = await listDirectoryEntries(directory);
|
|
2998
|
+
if (!entries) return 0;
|
|
2981
2999
|
const today = currentLocalDay();
|
|
2982
3000
|
let removed = 0;
|
|
2983
|
-
for (const
|
|
3001
|
+
for (const info of entries) {
|
|
3002
|
+
const { name } = info;
|
|
2984
3003
|
const isShard = /^[0-9a-f-]+\.json$/i.test(name);
|
|
2985
3004
|
const isTemp = name.endsWith(".tmp");
|
|
2986
3005
|
if (!isShard && !isTemp) continue;
|
|
2987
3006
|
const path = join(directory, name);
|
|
2988
3007
|
try {
|
|
2989
|
-
|
|
2990
|
-
if (!info.isFile() || info.isSymbolicLink()) continue;
|
|
3008
|
+
if (info.kind !== "file") continue;
|
|
2991
3009
|
if (isTemp) {
|
|
2992
3010
|
if (now - info.mtimeMs < SHARD_TEMP_RETENTION_MS) continue;
|
|
2993
3011
|
} else {
|
|
2994
|
-
const parsed = parsePersistedStatsShardV7(JSON.parse(await
|
|
3012
|
+
const parsed = parsePersistedStatsShardV7(JSON.parse(getOrThrow(await fs.readTextFile(path, io))));
|
|
2995
3013
|
if (parsed?.day === today) continue;
|
|
2996
3014
|
if (now - (parsed?.lifecycle.updatedAt ?? info.mtimeMs) < SHARD_RETENTION_MS) continue;
|
|
2997
3015
|
if (parsed?.lifecycle.state === "active" && isProcessAlive(parsed.process.pid)) continue;
|
|
2998
3016
|
}
|
|
2999
|
-
await
|
|
3017
|
+
getOrThrow(await fs.remove(path, void 0, io));
|
|
3000
3018
|
removed += 1;
|
|
3001
3019
|
} catch {}
|
|
3002
3020
|
}
|
|
3003
3021
|
return removed;
|
|
3004
3022
|
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Best-effort cross-process maintenance. A non-recursive `createDir` claims the cleanup lock; if two
|
|
3025
|
+
* cleanups ever overlap, each only removes expired shards, so the lock bounds work rather than guarding
|
|
3026
|
+
* correctness.
|
|
3027
|
+
*/
|
|
3005
3028
|
async function maybeCleanupStatsShardsV7(now = Date.now()) {
|
|
3006
|
-
await
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
}
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
await rm(SHARD_CLEANUP_LOCK_PATH, {
|
|
3017
|
-
recursive: true,
|
|
3018
|
-
force: true
|
|
3019
|
-
});
|
|
3020
|
-
await mkdir(SHARD_CLEANUP_LOCK_PATH);
|
|
3021
|
-
} catch {
|
|
3022
|
-
return;
|
|
3023
|
-
}
|
|
3029
|
+
getOrThrow(await fs.createDir(SHARD_MAINTENANCE_DIR, { recursive: true }, io));
|
|
3030
|
+
const marker = await fs.fileInfo(SHARD_CLEANUP_MARKER_PATH, io);
|
|
3031
|
+
if (marker.ok && now - marker.value.mtimeMs < SHARD_CLEANUP_INTERVAL_MS) return;
|
|
3032
|
+
if (!(await fs.createDir(SHARD_CLEANUP_LOCK_PATH, { recursive: false }, io)).ok) {
|
|
3033
|
+
const lock = await fs.fileInfo(SHARD_CLEANUP_LOCK_PATH, io);
|
|
3034
|
+
if (!lock.ok || now - lock.value.mtimeMs <= SHARD_CLEANUP_LOCK_STALE_MS) return;
|
|
3035
|
+
if (!(await fs.remove(SHARD_CLEANUP_LOCK_PATH, {
|
|
3036
|
+
recursive: true,
|
|
3037
|
+
force: true
|
|
3038
|
+
}, io)).ok || !(await fs.createDir(SHARD_CLEANUP_LOCK_PATH, { recursive: false }, io)).ok) return;
|
|
3024
3039
|
}
|
|
3025
3040
|
try {
|
|
3026
3041
|
await cleanupStatsShardsV7(now);
|
|
3027
|
-
|
|
3028
|
-
await writeFile(tempPath, `${now}\n`, "utf8");
|
|
3029
|
-
await rename(tempPath, SHARD_CLEANUP_MARKER_PATH);
|
|
3042
|
+
await writeFileAtomic(fs, SHARD_CLEANUP_MARKER_PATH, `${now}\n`, io);
|
|
3030
3043
|
} finally {
|
|
3031
|
-
await
|
|
3044
|
+
getOrThrow(await fs.remove(SHARD_CLEANUP_LOCK_PATH, {
|
|
3032
3045
|
recursive: true,
|
|
3033
3046
|
force: true
|
|
3034
|
-
});
|
|
3047
|
+
}, io));
|
|
3035
3048
|
}
|
|
3036
3049
|
}
|
|
3037
3050
|
function isExplicitPromptCacheRetentionUnsupportedApplicable(model) {
|
|
@@ -3182,7 +3195,7 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
3182
3195
|
advanceModelStatsEpoch,
|
|
3183
3196
|
maybeCleanupStatsShardsV7,
|
|
3184
3197
|
removeLegacyStatsFiles,
|
|
3185
|
-
createSerializedAsyncRunner,
|
|
3198
|
+
createSerializedAsyncRunner: createSerialRunner,
|
|
3186
3199
|
hasReasoningProtocolRejectionErrorMessage,
|
|
3187
3200
|
isReasoningProtocolRejectionForModel,
|
|
3188
3201
|
hasPromptCacheKeyUnsupportedErrorMessage,
|
|
@@ -3201,6 +3214,7 @@ function createOptimizerSupport(STATE_DIR, environment) {
|
|
|
3201
3214
|
parsePersistedStatsShardV7,
|
|
3202
3215
|
cleanupStatsShardsV7,
|
|
3203
3216
|
readEffectiveCompatConfig,
|
|
3217
|
+
refreshFileConfig,
|
|
3204
3218
|
getCompat,
|
|
3205
3219
|
SHARD_FILES_DIR,
|
|
3206
3220
|
LOG_PREFIX
|
|
@@ -3220,8 +3234,8 @@ function asModel(model) {
|
|
|
3220
3234
|
} : void 0;
|
|
3221
3235
|
}
|
|
3222
3236
|
/** One native session owner. Only V7 counters, never payloads or credentials, reach disk. */
|
|
3223
|
-
function createNativeOptimizer(initial, stateDir =
|
|
3224
|
-
const support = createOptimizerSupport(stateDir, initial.environment);
|
|
3237
|
+
function createNativeOptimizer(initial, fs, stateDir = defaultAgentDirectory()) {
|
|
3238
|
+
const support = createOptimizerSupport(stateDir, initial.environment, fs);
|
|
3225
3239
|
const serialized = support.createSerializedAsyncRunner();
|
|
3226
3240
|
const instanceId = randomUUID();
|
|
3227
3241
|
const instanceStartedAt = Date.now();
|
|
@@ -3505,6 +3519,7 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3505
3519
|
if (started || closed) return;
|
|
3506
3520
|
started = true;
|
|
3507
3521
|
releaseRetention = acquireEnvironmentValue("PI_CACHE_RETENTION", "long");
|
|
3522
|
+
await support.refreshFileConfig();
|
|
3508
3523
|
currentGlobalEpoch = await support.readGlobalStatsEpoch();
|
|
3509
3524
|
await support.removeLegacyStatsFiles();
|
|
3510
3525
|
await refresh();
|
|
@@ -3519,6 +3534,7 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3519
3534
|
handle: (event, context) => serialized(async () => {
|
|
3520
3535
|
if (typeof event.parentToolCallId === "string" && event.parentToolCallId.trim()) return;
|
|
3521
3536
|
if (started && !closed) {
|
|
3537
|
+
await support.refreshFileConfig();
|
|
3522
3538
|
await refresh();
|
|
3523
3539
|
await publish(context);
|
|
3524
3540
|
}
|
|
@@ -3528,6 +3544,7 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3528
3544
|
event: "agent_settled",
|
|
3529
3545
|
handle: (_event, context) => serialized(async () => {
|
|
3530
3546
|
if (started && !closed) {
|
|
3547
|
+
await support.refreshFileConfig();
|
|
3531
3548
|
await refresh();
|
|
3532
3549
|
await publish(context);
|
|
3533
3550
|
}
|
|
@@ -3537,6 +3554,7 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3537
3554
|
event: "model_select",
|
|
3538
3555
|
handle: (_event, context) => serialized(async () => {
|
|
3539
3556
|
if (!started || closed) return;
|
|
3557
|
+
await support.refreshFileConfig();
|
|
3540
3558
|
const model = selectedModel(context);
|
|
3541
3559
|
support.notifyCacheCompatIfNeeded(model, (text) => notify(context, text), warnedModels);
|
|
3542
3560
|
await refresh();
|
|
@@ -3546,7 +3564,9 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3546
3564
|
{
|
|
3547
3565
|
event: "message_end",
|
|
3548
3566
|
handle: (event, context) => serialized(async () => {
|
|
3549
|
-
if (started
|
|
3567
|
+
if (!started || closed) return;
|
|
3568
|
+
await support.refreshFileConfig();
|
|
3569
|
+
await observe(event.message, context);
|
|
3550
3570
|
})
|
|
3551
3571
|
},
|
|
3552
3572
|
{
|
|
@@ -3566,14 +3586,14 @@ function createNativeOptimizer(initial, stateDir = getAgentDir()) {
|
|
|
3566
3586
|
}
|
|
3567
3587
|
//#endregion
|
|
3568
3588
|
//#region src/extensions/workspaces/sessions/(backend)/root.server.ts
|
|
3569
|
-
var root_server_default = defineRoot(({ agent }) => {
|
|
3589
|
+
var root_server_default = defineRoot(({ agent, context: root }) => {
|
|
3570
3590
|
if (!agent) throw new Error("Cache statistics require the native session host.");
|
|
3571
3591
|
const telemetry = new PromptCacheTelemetry();
|
|
3572
3592
|
const runtime = createCacheRuntime({
|
|
3573
3593
|
telemetry,
|
|
3574
3594
|
now: Date.now
|
|
3575
3595
|
}, agent.context.environment);
|
|
3576
|
-
const optimizer = createNativeOptimizer(agent.context);
|
|
3596
|
+
const optimizer = createNativeOptimizer(agent.context, requirePoFs(root));
|
|
3577
3597
|
return {
|
|
3578
3598
|
value: { hooks: optimizer.hooks.map((hook) => {
|
|
3579
3599
|
if (hook.event === "session_start") return {
|