@retaw106/mmc-pi 2.1.2 → 2.2.1
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/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
normalizeProtectedToolName,
|
|
23
23
|
mergeProtectedTools,
|
|
24
24
|
detectThinkingBindingMismatch,
|
|
25
|
+
detectLatestTurnThinkingMismatch,
|
|
25
26
|
isPrefixBoundThinkingModel,
|
|
26
27
|
detectOverflow,
|
|
27
28
|
stableStringify,
|
|
@@ -32,7 +33,7 @@ import {
|
|
|
32
33
|
localBudget,
|
|
33
34
|
calibrationForModelKey,
|
|
34
35
|
historyLocalBudget,
|
|
35
|
-
|
|
36
|
+
adoptedProtectedToolsPolicy,
|
|
36
37
|
protectedToolTagNumbers,
|
|
37
38
|
protectedToolTokenCount,
|
|
38
39
|
removeSystemReminders,
|
|
@@ -51,6 +52,7 @@ import {
|
|
|
51
52
|
prependTag,
|
|
52
53
|
isRecord,
|
|
53
54
|
TEXT_TAG_IDENTITY_MARKER,
|
|
55
|
+
contentTagOwnerMessageId,
|
|
54
56
|
estimateImageTokensFromDataUrl,
|
|
55
57
|
TODO_STATUSES,
|
|
56
58
|
TODO_PRIORITIES,
|
|
@@ -135,6 +137,7 @@ import {
|
|
|
135
137
|
buildTrueRawTokenIndex,
|
|
136
138
|
computeRawRangeFingerprint,
|
|
137
139
|
invalidateTrueRawTokenCache,
|
|
140
|
+
stripSystemInjection,
|
|
138
141
|
hasUserAnswerMetadata,
|
|
139
142
|
droppedInputMarker,
|
|
140
143
|
createDroppedInputGuard,
|
|
@@ -165,7 +168,7 @@ import {
|
|
|
165
168
|
getRawSessionTagKeysThrough2,
|
|
166
169
|
getLegacyProtectedTailStartOrdinal2,
|
|
167
170
|
readSessionChunk2
|
|
168
|
-
} from "./index-
|
|
171
|
+
} from "./index-j0jjtcwm.js";
|
|
169
172
|
import {
|
|
170
173
|
registerSlowWriteReporter,
|
|
171
174
|
registerSqliteDiagnosticSink,
|
|
@@ -6964,7 +6967,6 @@ var HistorianConfigSchema = AgentMetadataSchema.extend({
|
|
|
6964
6967
|
var MagicContextConfigSchema = object({
|
|
6965
6968
|
enabled: boolean2().default(true).describe("Enable magic context (default: true)"),
|
|
6966
6969
|
allow_home_project: boolean2().default(false).describe("Allow Magic Context sessions launched from the exact canonical home directory. A non-git home uses its deterministic dir: identity; a home repository uses its git: identity. USER-LEVEL ONLY: project config is ignored. The home identity is excluded from registry seed exports, never resolves descendants by containment, and cannot join a workspace."),
|
|
6967
|
-
auto_update: boolean2().optional().describe("DEPRECATED no-op: the automatic update check was removed (the package is private-registry-only, so public npm checks always 404). The key is still accepted so existing configs keep parsing; upgrade via the host's own plugin update channel."),
|
|
6968
6970
|
language: string2().trim().toLowerCase().refine((s) => isValidLanguageCode(s), 'language must be a 2-letter ISO 639-1 code (e.g. "tr", "es", "de")').optional().describe("Output language for Magic Context's generated content and guidance, as a " + '2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' + "historian and the agent-guidance block instruct the model to " + "write its PROSE in this language while keeping all structural tokens (XML tags, " + "the five memory category names, code identifiers, file paths) in English. " + "USER-LEVEL ONLY (ignored in project config for security). Unset = today's " + "behavior (model mirrors the conversation; English scaffolding). Changing it " + "triggers one cache re-materialization; existing compartments/memories keep their " + "original language until naturally rewritten."),
|
|
6969
6971
|
profile: string2().trim().min(1).optional().describe("Select a named user-owned model profile. A valid project name overrides this user default; an empty string, null, or other non-string project value is ignored with a warning so the user selection still applies. Unknown names warn and use the base configuration."),
|
|
6970
6972
|
profiles: ConfigProfilesSchema.optional().describe("User-level named model profiles. A profile may contain only the flat historian model-resolution fields (model, fallback_models, OpenCode variant, Pi thinking_level). Project configs may select a name but cannot define profiles."),
|
|
@@ -7436,10 +7438,6 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
7436
7438
|
delete projectRaw.profiles;
|
|
7437
7439
|
warnings.push("Ignoring profiles from project config (security: profile definitions are user-level only; a repository may select a named user profile with profile).");
|
|
7438
7440
|
}
|
|
7439
|
-
if ("auto_update" in projectRaw) {
|
|
7440
|
-
delete projectRaw.auto_update;
|
|
7441
|
-
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
7442
|
-
}
|
|
7443
7441
|
if ("fail_closed_blocking" in projectRaw) {
|
|
7444
7442
|
delete projectRaw.fail_closed_blocking;
|
|
7445
7443
|
warnings.push("Ignoring fail_closed_blocking from project config (security: only user-level config may disable or force the loud inoperability gate).");
|
|
@@ -11973,8 +11971,8 @@ function ensureBackfillStateTable(db) {
|
|
|
11973
11971
|
}
|
|
11974
11972
|
}
|
|
11975
11973
|
function withImmediateTransaction(db, fn) {
|
|
11974
|
+
withoutSqliteTransformPass(() => withSqliteBackgroundWriter(() => db.exec("BEGIN IMMEDIATE")));
|
|
11976
11975
|
const transactionStartedAt = performance.now();
|
|
11977
|
-
db.exec("BEGIN IMMEDIATE");
|
|
11978
11976
|
try {
|
|
11979
11977
|
const result = fn();
|
|
11980
11978
|
db.exec("COMMIT");
|
|
@@ -12081,6 +12079,9 @@ function createPageReader(source) {
|
|
|
12081
12079
|
};
|
|
12082
12080
|
}
|
|
12083
12081
|
async function runSessionProjectBackfill(db, source, options = {}) {
|
|
12082
|
+
return withoutSqliteTransformPass(() => withSqliteBackgroundWriter(() => runSessionProjectBackfillPass(db, source, options)));
|
|
12083
|
+
}
|
|
12084
|
+
async function runSessionProjectBackfillPass(db, source, options = {}) {
|
|
12084
12085
|
const startedAt = performance.now();
|
|
12085
12086
|
const harness = getHarness();
|
|
12086
12087
|
const now = options.now ?? Date.now;
|
|
@@ -12215,12 +12216,12 @@ import { execFile, execFileSync as execFileSync2 } from "node:child_process";
|
|
|
12215
12216
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
12216
12217
|
|
|
12217
12218
|
// ../plugin/src/shared/pi-executable.ts
|
|
12218
|
-
var PI_IMAGE_NAMES = new Set(["pi", "pi.cmd"]);
|
|
12219
|
+
var PI_IMAGE_NAMES = new Set(["pi", "pi.cmd", "omp", "oh-my-pi"]);
|
|
12219
12220
|
function piHarnessKindFromExecutable(value) {
|
|
12220
12221
|
const executable = (value ?? "").trim().replace(/^['"]|['"]$/g, "").replaceAll("\\", "/").split("/").at(-1)?.toLowerCase().replace(/\.(?:exe|cmd)$/, "");
|
|
12221
12222
|
if (!executable || !PI_IMAGE_NAMES.has(executable))
|
|
12222
12223
|
return;
|
|
12223
|
-
return "pi";
|
|
12224
|
+
return executable === "pi" ? "pi" : "omp";
|
|
12224
12225
|
}
|
|
12225
12226
|
|
|
12226
12227
|
// ../plugin/src/shared/rpc-utils.ts
|
|
@@ -14119,6 +14120,13 @@ function getCurrentVersion(db) {
|
|
|
14119
14120
|
function isMigrationApplied(db, version) {
|
|
14120
14121
|
return db.prepare("SELECT 1 FROM schema_migrations WHERE version = ?").get(version) != null;
|
|
14121
14122
|
}
|
|
14123
|
+
function hasPendingMigrations(db) {
|
|
14124
|
+
const bookkeeping = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_migrations'").get();
|
|
14125
|
+
if (bookkeeping == null)
|
|
14126
|
+
return true;
|
|
14127
|
+
const currentVersion = getCurrentVersion(db);
|
|
14128
|
+
return MIGRATIONS.some((candidate) => candidate.version > currentVersion && !isMigrationApplied(db, candidate.version));
|
|
14129
|
+
}
|
|
14122
14130
|
function isSiblingMigrationConflict(db, error, version) {
|
|
14123
14131
|
if (!(error instanceof Error))
|
|
14124
14132
|
return false;
|
|
@@ -14391,6 +14399,8 @@ function lkgContentDigestFromFields(fields) {
|
|
|
14391
14399
|
}
|
|
14392
14400
|
return hash.digest("base64url");
|
|
14393
14401
|
}
|
|
14402
|
+
var digestMemo = new Map;
|
|
14403
|
+
var DIGEST_MEMO_MAX_BYTES = 16 * 1024 * 1024;
|
|
14394
14404
|
function equalContentFields(left, right) {
|
|
14395
14405
|
if (left === right)
|
|
14396
14406
|
return true;
|
|
@@ -15066,7 +15076,8 @@ function clampWatermark(value, maxCopiedTag) {
|
|
|
15066
15076
|
}
|
|
15067
15077
|
function copySessionStateForClone(db, sourceSessionId, destinationSessionId, filter) {
|
|
15068
15078
|
return runImmediate(db, () => {
|
|
15069
|
-
|
|
15079
|
+
const hasTemporalDecisions = tableExists2(db, "temporal_decisions");
|
|
15080
|
+
if (countRows(db, "compartments", destinationSessionId) > 0 || countRows(db, "tags", destinationSessionId) > 0 || hasTemporalDecisions && countRows(db, "temporal_decisions", destinationSessionId) > 0 || filter.copySessionNotesAndFacts === true && (tableExists2(db, "notes") && countRows(db, "notes", destinationSessionId) > 0 || tableExists2(db, "session_facts") && countRows(db, "session_facts", destinationSessionId) > 0)) {
|
|
15070
15081
|
return {
|
|
15071
15082
|
kind: "destination-not-empty",
|
|
15072
15083
|
compartmentsCopied: 0,
|
|
@@ -15155,6 +15166,14 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
|
|
|
15155
15166
|
insertPendingOp.run(destinationSessionId, row.tag_id, row.operation, row.queued_at, row.harness);
|
|
15156
15167
|
}
|
|
15157
15168
|
}
|
|
15169
|
+
if (hasTemporalDecisions) {
|
|
15170
|
+
const temporalRows = db.prepare("SELECT message_id,marker FROM temporal_decisions WHERE session_id=?").all(sourceSessionId);
|
|
15171
|
+
const insertTemporal = db.prepare("INSERT INTO temporal_decisions(session_id,message_id,marker) VALUES (?,?,?)");
|
|
15172
|
+
for (const row of temporalRows) {
|
|
15173
|
+
if (filter.includeMessageId(row.message_id))
|
|
15174
|
+
insertTemporal.run(destinationSessionId, mapMessageId(filter, row.message_id), row.marker);
|
|
15175
|
+
}
|
|
15176
|
+
}
|
|
15158
15177
|
const inherited = filter.copySessionNotesAndFacts === true ? copyPiSessionNotesAndFacts(db, sourceSessionId, destinationSessionId, filter) : { notesCopied: 0, factsCopied: 0 };
|
|
15159
15178
|
const meta = db.prepare(`SELECT cleared_reasoning_through_tag, tool_reclaim_watermark,
|
|
15160
15179
|
pi_stable_id_scheme, stripped_placeholder_ids,
|
|
@@ -15991,7 +16010,7 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
|
|
|
15991
16010
|
startMessageFtsRowidMapBackfill(db).then(async () => {
|
|
15992
16011
|
if (!readsOpenCodeStore)
|
|
15993
16012
|
return;
|
|
15994
|
-
const { readRawSessionMessagePage, readRawSessionMessages } = await import("./read-session-chunk-
|
|
16013
|
+
const { readRawSessionMessagePage, readRawSessionMessages } = await import("./read-session-chunk-ktp56z65.js");
|
|
15995
16014
|
const { startMessageTimeBackfill } = await import("./message-time-backfill-a3p9r5rh.js");
|
|
15996
16015
|
await startMessageTimeBackfill(db, Object.assign(readRawSessionMessages, {
|
|
15997
16016
|
readPage: readRawSessionMessagePage
|
|
@@ -17511,12 +17530,23 @@ function openDatabase(dbPathOrOptions) {
|
|
|
17511
17530
|
closeQuietly(db);
|
|
17512
17531
|
return null;
|
|
17513
17532
|
}
|
|
17533
|
+
if (options?.allowMigrations === false && hasPendingMigrations(db)) {
|
|
17534
|
+
log(`[magic-context] storage not ready: pending migrations at ${dbPath}; host callers must await the async opener`);
|
|
17535
|
+
closeQuietly(db);
|
|
17536
|
+
return null;
|
|
17537
|
+
}
|
|
17514
17538
|
if (!enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)) {
|
|
17515
17539
|
closeQuietly(db);
|
|
17516
17540
|
return null;
|
|
17517
17541
|
}
|
|
17518
17542
|
initializeDatabase(db, busyTimeoutMs);
|
|
17519
|
-
|
|
17543
|
+
if (options?.allowMigrations === false) {
|
|
17544
|
+
if (hasPendingMigrations(db)) {
|
|
17545
|
+
closeQuietly(db);
|
|
17546
|
+
return null;
|
|
17547
|
+
}
|
|
17548
|
+
} else
|
|
17549
|
+
runMigrations(db);
|
|
17520
17550
|
ensureContextStoreUuid(db);
|
|
17521
17551
|
return finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion);
|
|
17522
17552
|
} catch (error) {
|
|
@@ -19140,7 +19170,7 @@ var CTX_REDUCE_LIGHT_DESCRIPTION = `Stamp an item as no longer needed for the wo
|
|
|
19140
19170
|
var CTX_EXPAND_LIGHT_DESCRIPTION = "Recover one item with tag=N (a §N§ or dropped placeholder number), not a message ordinal; text or one tool call with full input/output. message=N and start/end are whole-message ordinals from history/search, never tag numbers. Recover raw conversation behind a <session-history> heading or around a mmc_search hit: mmc_expand(start, end) returns [N] U:/A: lines (~15K-token cap; oversized ranges return the head and where to continue). verbose=true lists messages with per-part previews to pick one; message=N returns that message in full, including a tool output released with mmc_reduce. Ranges after the last compartment are your live tail, not expandable.";
|
|
19141
19171
|
var CTX_NOTE_LIGHT_DESCRIPTION = 'Session notes are pending intentions: work you intend to return to, with findings attached ("take a note" always qualifies). Not active steps, an executing plan, or restart insurance; a record of how things stand (world-state, a design at a point in time) with nothing you intend to do about it — that goes stale silently; a fact worth keeping is memory, the rest is nothing. First line = title (<80 chars). write saves; read lists rows (note_ids for bodies); update changes one; dismiss retires 1–50. Dismiss a note when its work lands or is abandoned; a queue you never dismiss from stops being read.';
|
|
19142
19172
|
var CTX_MEMORY_LIGHT_DESCRIPTION = "Durable facts about this project, shared with every agent on it and kept for the months this work lasts; active ones are already in <project-memory> as `#id: fact`. Write one standalone fact when it must not have to be found again — a rule, an architecture fact, a constraint, a config value, a naming convention — especially what cost you turns. A pending intention with evidence is mmc_note, not memory. write (content + category); update one id (content; category optional); archive one or more ids (reason optional); merge two or more ids (content); get 1–20 ids in any status.";
|
|
19143
|
-
var CTX_SEARCH_LIGHT_DESCRIPTION = 'Search
|
|
19173
|
+
var CTX_SEARCH_LIGHT_DESCRIPTION = 'Search past context not on your desk: memories not in <project-memory>, compacted conversation, notes. Phrase query as a natural-language question carrying the exact terms you expect ("where is the opencode source code path?", "why did we choose SQLite over postgres?", "how does the historian lease work?") — a keyword stack finds less. Sources (omit for all): memory (rules, conventions), message (compacted conversation; hits carry ordinals for mmc_expand), primer (stored project Q&A), note (parked follow-ups). Memory ids alone (`#7234`) resolve directly. from/to restrict every source to an inclusive UTC date range.';
|
|
19144
19174
|
|
|
19145
19175
|
// ../plugin/src/shared/prompt-surface-runtime.ts
|
|
19146
19176
|
var GUIDANCE_MARKER = "## Magic Context";
|
|
@@ -21676,9 +21706,15 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
21676
21706
|
|
|
21677
21707
|
// ../plugin/src/hooks/magic-context/cache-busting-signals.ts
|
|
21678
21708
|
function hasReclaimRide(signals) {
|
|
21679
|
-
return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory;
|
|
21680
|
-
}
|
|
21681
|
-
var RECLAIM_RIDE_NAMES = [
|
|
21709
|
+
return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
|
|
21710
|
+
}
|
|
21711
|
+
var RECLAIM_RIDE_NAMES = [
|
|
21712
|
+
"hardFold",
|
|
21713
|
+
"force",
|
|
21714
|
+
"explicitFlush",
|
|
21715
|
+
"publishedHistory",
|
|
21716
|
+
"subagentExecute"
|
|
21717
|
+
];
|
|
21682
21718
|
function reclaimRideLabel(signals) {
|
|
21683
21719
|
const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
|
|
21684
21720
|
return `ride=${active.length > 0 ? active.join("+") : "none"}`;
|
|
@@ -21748,6 +21784,9 @@ var MEMORY_MAINTAINER_B_AGENT = "magic-context-maintainer-b";
|
|
|
21748
21784
|
var MEMORY_MAINTAINER_A_ALLOWED_TOOLS = [];
|
|
21749
21785
|
var MEMORY_MAINTAINER_B_ALLOWED_TOOLS = ["read", "grep", "glob"];
|
|
21750
21786
|
var MEMORY_MAINTAINER_A_STEP_CAP = 4;
|
|
21787
|
+
function resolveMaintenanceStepCap(baseSteps, consumedSteps) {
|
|
21788
|
+
return Math.max(1, baseSteps - consumedSteps);
|
|
21789
|
+
}
|
|
21751
21790
|
var MEMORY_MAINTAINER_A_SYSTEM_PROMPT = [
|
|
21752
21791
|
"You are the memory-maintenance stage A screener: a hidden background agent that",
|
|
21753
21792
|
"value-screens a coding project's long-term memory pool before a separate",
|
|
@@ -22018,6 +22057,9 @@ ${stageAManifest}
|
|
|
22018
22057
|
`);
|
|
22019
22058
|
}
|
|
22020
22059
|
|
|
22060
|
+
// ../plugin/src/shared/subagent-runner.ts
|
|
22061
|
+
var HISTORIAN_STEP_CAP = 4;
|
|
22062
|
+
|
|
22021
22063
|
// ../plugin/src/v2/hooks/hidden-child.ts
|
|
22022
22064
|
var HIDDEN_HISTORIAN_AGENT = "historian";
|
|
22023
22065
|
var AGENT_TOOL_ALLOWLIST = {
|
|
@@ -22026,7 +22068,8 @@ var AGENT_TOOL_ALLOWLIST = {
|
|
|
22026
22068
|
[MEMORY_MAINTAINER_B_AGENT]: MEMORY_MAINTAINER_B_ALLOWED_TOOLS
|
|
22027
22069
|
};
|
|
22028
22070
|
var AGENT_STEP_CAPS = {
|
|
22029
|
-
[MEMORY_MAINTAINER_A_AGENT]: MEMORY_MAINTAINER_A_STEP_CAP
|
|
22071
|
+
[MEMORY_MAINTAINER_A_AGENT]: MEMORY_MAINTAINER_A_STEP_CAP,
|
|
22072
|
+
[HIDDEN_HISTORIAN_AGENT]: HISTORIAN_STEP_CAP
|
|
22030
22073
|
};
|
|
22031
22074
|
class HiddenAgentStepLimit extends Error {
|
|
22032
22075
|
agent;
|
|
@@ -23478,11 +23521,10 @@ var MIN_PROACTIVE_TAIL_MESSAGE_COUNT = 12;
|
|
|
23478
23521
|
var DEFAULT_MIN_COMMIT_CLUSTERS_FOR_TRIGGER = 3;
|
|
23479
23522
|
var TAIL_SIZE_TRIGGER_MULTIPLIER = 3;
|
|
23480
23523
|
var BLOCK_UNTIL_DONE_PERCENTAGE = 95;
|
|
23481
|
-
var CONTENT_TAG_OWNER_SUFFIX = /:(?:p|file)\d+$/;
|
|
23482
23524
|
function tagOwnerMessageId(row) {
|
|
23483
23525
|
if (row.type === "tool")
|
|
23484
23526
|
return row.tool_owner_message_id ?? row.message_id;
|
|
23485
|
-
return row.message_id
|
|
23527
|
+
return contentTagOwnerMessageId(row.message_id);
|
|
23486
23528
|
}
|
|
23487
23529
|
function getActiveOrDroppedTagOwnerMessageIds(db, sessionId, floor = 0) {
|
|
23488
23530
|
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
@@ -25591,6 +25633,164 @@ function hasActiveAnthropicThinkingTurn(messages, provider, model) {
|
|
|
25591
25633
|
}
|
|
25592
25634
|
return false;
|
|
25593
25635
|
}
|
|
25636
|
+
function protectNewTagMutations(messages, targets, protectedParts, prefixBound) {
|
|
25637
|
+
if (protectedParts.size === 0)
|
|
25638
|
+
return targets;
|
|
25639
|
+
const positions = new Map;
|
|
25640
|
+
let ordinal = 0;
|
|
25641
|
+
for (const message of messages)
|
|
25642
|
+
for (const part of message.parts)
|
|
25643
|
+
positions.set(part, ordinal++);
|
|
25644
|
+
let lastProtected = -1;
|
|
25645
|
+
for (const part of protectedParts)
|
|
25646
|
+
lastProtected = Math.max(lastProtected, positions.get(part) ?? -1);
|
|
25647
|
+
const result = new Map;
|
|
25648
|
+
for (const [tag, target] of targets) {
|
|
25649
|
+
const message = target.message;
|
|
25650
|
+
const coordinates = target.mutationParts ?? (message ? message.parts.map((part) => ({ message, part })) : []);
|
|
25651
|
+
const prefixEdit = prefixBound && coordinates.some(({ part }) => (positions.get(part) ?? Infinity) < lastProtected);
|
|
25652
|
+
const dropsThinking = target.dropReasoningParts?.some((part) => protectedParts.has(part)) === true;
|
|
25653
|
+
if (!prefixEdit && !dropsThinking) {
|
|
25654
|
+
result.set(tag, target);
|
|
25655
|
+
continue;
|
|
25656
|
+
}
|
|
25657
|
+
result.set(tag, {
|
|
25658
|
+
...target,
|
|
25659
|
+
thinkingDropProtected: true,
|
|
25660
|
+
thinkingRewriteProtected: prefixEdit,
|
|
25661
|
+
canDrop: () => false,
|
|
25662
|
+
drop: () => "incomplete",
|
|
25663
|
+
truncate: () => "incomplete",
|
|
25664
|
+
skeletonReal: () => "incomplete",
|
|
25665
|
+
skeletonStripped: () => "incomplete",
|
|
25666
|
+
editMarker: () => "incomplete",
|
|
25667
|
+
editMarkerStripped: () => "incomplete",
|
|
25668
|
+
setContent: (content, options) => prefixEdit || options?.keepReasoning !== true ? false : target.setContent(content, options)
|
|
25669
|
+
});
|
|
25670
|
+
}
|
|
25671
|
+
return result;
|
|
25672
|
+
}
|
|
25673
|
+
|
|
25674
|
+
// ../plugin/src/hooks/magic-context/latest-thinking-recovery.ts
|
|
25675
|
+
var LATEST_THINKING_RESTORE = "latest_thinking_original";
|
|
25676
|
+
var knownRejectedSessions = new Set;
|
|
25677
|
+
var lastPassTurnAnchor = new Map;
|
|
25678
|
+
var ACTIVE = `${LATEST_THINKING_RESTORE}:`;
|
|
25679
|
+
var ARMED = `${LATEST_THINKING_RESTORE}_armed:`;
|
|
25680
|
+
var UNRECOVERABLE = `${LATEST_THINKING_RESTORE}_unavailable`;
|
|
25681
|
+
var LATEST_THINKING_UNSAFE = "ANTHROPIC_LATEST_TURN_EDIT_UNSAFE: The provider rejected edits to this thinking turn and its original context cannot be safely replayed. Send a new user message or /clear to continue.";
|
|
25682
|
+
function armLatestThinkingRecovery(db, sessionId) {
|
|
25683
|
+
knownRejectedSessions.add(sessionId);
|
|
25684
|
+
ensureSessionMetaRow(db, sessionId);
|
|
25685
|
+
const current = getThinkingBindingRecoveryTarget(db, sessionId);
|
|
25686
|
+
const anchor = lastPassTurnAnchor.get(sessionId);
|
|
25687
|
+
const next = current?.startsWith(ACTIVE) ? UNRECOVERABLE + ":" + current.slice(ACTIVE.length) : current?.startsWith(UNRECOVERABLE) || current?.startsWith(ARMED) ? current : anchor !== undefined ? ARMED + anchor : LATEST_THINKING_RESTORE;
|
|
25688
|
+
db.prepare("UPDATE session_meta SET thinking_binding_recovery_target = ? WHERE session_id = ?").run(next, sessionId);
|
|
25689
|
+
}
|
|
25690
|
+
function clone2(value) {
|
|
25691
|
+
if (Array.isArray(value))
|
|
25692
|
+
return value.map(clone2);
|
|
25693
|
+
if (!isRecord(value))
|
|
25694
|
+
return value;
|
|
25695
|
+
const proto = Object.getPrototypeOf(value);
|
|
25696
|
+
if (proto !== Object.prototype && proto !== null)
|
|
25697
|
+
return value;
|
|
25698
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clone2(item)]));
|
|
25699
|
+
}
|
|
25700
|
+
function isThinkingPart(part) {
|
|
25701
|
+
return isRecord(part) && ["thinking", "reasoning", "redacted_thinking"].includes(String(part.type));
|
|
25702
|
+
}
|
|
25703
|
+
function replayableOriginal(part) {
|
|
25704
|
+
if (!isThinkingPart(part) || !isRecord(part))
|
|
25705
|
+
return false;
|
|
25706
|
+
const metadata = isRecord(part.metadata) && isRecord(part.metadata.anthropic) ? part.metadata.anthropic : {};
|
|
25707
|
+
const signature = part.signature ?? part.thinkingSignature ?? metadata.signature ?? part.data ?? metadata.redactedData;
|
|
25708
|
+
return typeof signature === "string" && signature.length > 0 && part.text !== "[cleared]" && part.thinking !== "[cleared]";
|
|
25709
|
+
}
|
|
25710
|
+
function prepareLatestThinkingRecovery(args) {
|
|
25711
|
+
const start = latestAssistantTurnStart(args.messages);
|
|
25712
|
+
const anchor = start > 0 ? args.id(args.messages[start - 1], start - 1) : undefined;
|
|
25713
|
+
if (anchor === undefined)
|
|
25714
|
+
lastPassTurnAnchor.delete(args.sessionId);
|
|
25715
|
+
else
|
|
25716
|
+
lastPassTurnAnchor.set(args.sessionId, anchor);
|
|
25717
|
+
let target;
|
|
25718
|
+
try {
|
|
25719
|
+
target = getThinkingBindingRecoveryTarget(args.db, args.sessionId);
|
|
25720
|
+
} catch (error) {
|
|
25721
|
+
if (knownRejectedSessions.has(args.sessionId))
|
|
25722
|
+
throw contextRefusalError(LATEST_THINKING_UNSAFE);
|
|
25723
|
+
return { restore: false, ended: false };
|
|
25724
|
+
}
|
|
25725
|
+
if (!target || !target.startsWith(LATEST_THINKING_RESTORE)) {
|
|
25726
|
+
knownRejectedSessions.delete(args.sessionId);
|
|
25727
|
+
return { restore: false, ended: false };
|
|
25728
|
+
}
|
|
25729
|
+
const armedAnchor = target.startsWith(ARMED) ? target.slice(ARMED.length) : undefined;
|
|
25730
|
+
if (target === LATEST_THINKING_RESTORE || armedAnchor !== undefined && armedAnchor !== anchor) {
|
|
25731
|
+
args.db.prepare("UPDATE session_meta SET thinking_binding_recovery_target = '' WHERE session_id = ? AND thinking_binding_recovery_target = ?").run(args.sessionId, target);
|
|
25732
|
+
knownRejectedSessions.delete(args.sessionId);
|
|
25733
|
+
return { restore: false, ended: false };
|
|
25734
|
+
}
|
|
25735
|
+
knownRejectedSessions.add(args.sessionId);
|
|
25736
|
+
const savedAnchor = target.startsWith(ACTIVE) ? target.slice(ACTIVE.length) : target.startsWith(UNRECOVERABLE + ":") ? target.slice(UNRECOVERABLE.length + 1) : undefined;
|
|
25737
|
+
if (savedAnchor !== undefined && savedAnchor !== anchor) {
|
|
25738
|
+
args.db.prepare("UPDATE session_meta SET thinking_binding_recovery_target = '' WHERE session_id = ? AND thinking_binding_recovery_target = ?").run(args.sessionId, target);
|
|
25739
|
+
knownRejectedSessions.delete(args.sessionId);
|
|
25740
|
+
return { restore: false, ended: true };
|
|
25741
|
+
}
|
|
25742
|
+
if (target.startsWith(UNRECOVERABLE) || !anchor)
|
|
25743
|
+
throw contextRefusalError(LATEST_THINKING_UNSAFE);
|
|
25744
|
+
if (armedAnchor !== undefined) {
|
|
25745
|
+
args.db.prepare("UPDATE session_meta SET thinking_binding_recovery_target = ? WHERE session_id = ? AND thinking_binding_recovery_target = ?").run(ACTIVE + anchor, args.sessionId, target);
|
|
25746
|
+
}
|
|
25747
|
+
const active = args.messages.slice(start);
|
|
25748
|
+
if (!active.some((message) => args.parts(message).some(replayableOriginal)))
|
|
25749
|
+
throw contextRefusalError(LATEST_THINKING_UNSAFE + " [missing-thinking-original]");
|
|
25750
|
+
const ids = new Map(args.messages.map((message, index) => [args.id(message, index), index]));
|
|
25751
|
+
for (const decision of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
|
|
25752
|
+
if (decision === "binding_mismatch_order:end" || decision === TOOL_SWEEP_SCOPED_MARKER)
|
|
25753
|
+
continue;
|
|
25754
|
+
const id = decodeMergedReasoningParts(decision)?.[0] ?? (decision.startsWith("binding_mismatch:") ? decision.slice("binding_mismatch:".length) : decision);
|
|
25755
|
+
const index = ids.get(id);
|
|
25756
|
+
if (index === undefined || index >= start && !args.parts(args.messages[index]).some(replayableOriginal))
|
|
25757
|
+
throw contextRefusalError(LATEST_THINKING_UNSAFE + ` [missing-original:${id}]`);
|
|
25758
|
+
}
|
|
25759
|
+
return { restore: true, ended: false };
|
|
25760
|
+
}
|
|
25761
|
+
function latestThinkingRecoveryCoversActiveTurn(args) {
|
|
25762
|
+
let target;
|
|
25763
|
+
try {
|
|
25764
|
+
target = getThinkingBindingRecoveryTarget(args.db, args.sessionId);
|
|
25765
|
+
} catch {
|
|
25766
|
+
return false;
|
|
25767
|
+
}
|
|
25768
|
+
const bound = target?.startsWith(ARMED) ? target.slice(ARMED.length) : target?.startsWith(ACTIVE) ? target.slice(ACTIVE.length) : undefined;
|
|
25769
|
+
if (bound === undefined)
|
|
25770
|
+
return false;
|
|
25771
|
+
const start = latestAssistantTurnStart(args.messages);
|
|
25772
|
+
return start > 0 && args.id(args.messages[start - 1], start - 1) === bound;
|
|
25773
|
+
}
|
|
25774
|
+
function captureOriginalTurn(messages, parts, setParts) {
|
|
25775
|
+
const start = Math.max(0, latestAssistantTurnStart(messages) - 1);
|
|
25776
|
+
const originals = messages.slice(start).map((message) => ({ message, parts: clone2(parts(message)) }));
|
|
25777
|
+
const before = messages.slice(0, start);
|
|
25778
|
+
return (target = messages) => {
|
|
25779
|
+
const first = target.findIndex((message) => originals.some((original) => original.message === message || isRecord(message) && isRecord(original.message) && (isRecord(message.info) && isRecord(original.message.info) && message.info.id === original.message.info.id || message.role === original.message.role && message.timestamp !== undefined && message.timestamp === original.message.timestamp)));
|
|
25780
|
+
const prefix = first >= 0 ? target.slice(0, first) : target === messages ? before : target.slice();
|
|
25781
|
+
for (const original of originals) {
|
|
25782
|
+
setParts(original.message, clone2(original.parts));
|
|
25783
|
+
}
|
|
25784
|
+
target.length = 0;
|
|
25785
|
+
target.push(...prefix, ...originals.map((original) => original.message));
|
|
25786
|
+
};
|
|
25787
|
+
}
|
|
25788
|
+
function armBindingRecoverySafely(db, sessionId) {
|
|
25789
|
+
if (getThinkingBindingRecoveryTarget(db, sessionId)?.startsWith(LATEST_THINKING_RESTORE))
|
|
25790
|
+
armLatestThinkingRecovery(db, sessionId);
|
|
25791
|
+
else
|
|
25792
|
+
armThinkingBindingRecovery(db, sessionId);
|
|
25793
|
+
}
|
|
25594
25794
|
|
|
25595
25795
|
// ../plugin/src/hooks/magic-context/reasoning-budget-status.ts
|
|
25596
25796
|
var sources = new Map;
|
|
@@ -25740,51 +25940,6 @@ function readFilePath(target) {
|
|
|
25740
25940
|
return null;
|
|
25741
25941
|
}
|
|
25742
25942
|
|
|
25743
|
-
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
25744
|
-
var SYSTEM_INJECTION_MARKERS = [
|
|
25745
|
-
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
25746
|
-
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
25747
|
-
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
25748
|
-
"[Category+Skill Reminder]",
|
|
25749
|
-
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
25750
|
-
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
25751
|
-
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
25752
|
-
"Unstable background agent appears idle",
|
|
25753
|
-
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
25754
|
-
];
|
|
25755
|
-
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
25756
|
-
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
25757
|
-
function stripSystemInjection(text) {
|
|
25758
|
-
let hasInjection = false;
|
|
25759
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
25760
|
-
if (text.includes(marker)) {
|
|
25761
|
-
hasInjection = true;
|
|
25762
|
-
break;
|
|
25763
|
-
}
|
|
25764
|
-
}
|
|
25765
|
-
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
25766
|
-
hasInjection = true;
|
|
25767
|
-
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
25768
|
-
if (!hasInjection)
|
|
25769
|
-
return null;
|
|
25770
|
-
let cleaned = text;
|
|
25771
|
-
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
25772
|
-
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
25773
|
-
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
25774
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
25775
|
-
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
25776
|
-
continue;
|
|
25777
|
-
const idx = cleaned.indexOf(marker);
|
|
25778
|
-
if (idx === -1)
|
|
25779
|
-
continue;
|
|
25780
|
-
const blockEnd = cleaned.indexOf(`
|
|
25781
|
-
|
|
25782
|
-
`, idx + marker.length);
|
|
25783
|
-
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
25784
|
-
}
|
|
25785
|
-
return cleaned.trim();
|
|
25786
|
-
}
|
|
25787
|
-
|
|
25788
25943
|
// ../plugin/src/hooks/magic-context/tool-reclaim.ts
|
|
25789
25944
|
function buildSyntheticToolReclaimOps(input) {
|
|
25790
25945
|
const watermark = Math.max(0, input.watermark);
|
|
@@ -26417,6 +26572,10 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton, conve
|
|
|
26417
26572
|
return !occurrences.every((occ, index) => occ.part.remove && authorization[index] !== false);
|
|
26418
26573
|
};
|
|
26419
26574
|
return {
|
|
26575
|
+
mutationParts: occurrences.map((occ) => ({
|
|
26576
|
+
message: { info: occ.message.info, parts: [] },
|
|
26577
|
+
part: occ.part
|
|
26578
|
+
})),
|
|
26420
26579
|
measureReclaim(skeleton) {
|
|
26421
26580
|
let beforeTools = 0;
|
|
26422
26581
|
let afterTools = 0;
|
|
@@ -26530,6 +26689,7 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton, conve
|
|
|
26530
26689
|
}
|
|
26531
26690
|
function buildTextTarget(part, message, textPrefix) {
|
|
26532
26691
|
return {
|
|
26692
|
+
mutationParts: [{ message: { info: message.info, parts: [] }, part }],
|
|
26533
26693
|
textPrefix,
|
|
26534
26694
|
setContent(content) {
|
|
26535
26695
|
return part.setText(content);
|
|
@@ -26545,6 +26705,7 @@ function buildTextTarget(part, message, textPrefix) {
|
|
|
26545
26705
|
}
|
|
26546
26706
|
function buildToolTarget(part, message, tagId) {
|
|
26547
26707
|
return {
|
|
26708
|
+
mutationParts: [{ message: { info: message.info, parts: [] }, part }],
|
|
26548
26709
|
setContent(content) {
|
|
26549
26710
|
return setToolContentOrText(part, content);
|
|
26550
26711
|
},
|
|
@@ -33509,391 +33670,6 @@ function recordPiTransformTiming(sample) {
|
|
|
33509
33670
|
// src/ctx-reduce-nudge-pi.ts
|
|
33510
33671
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
33511
33672
|
|
|
33512
|
-
// src/heuristic-cleanup-pi.ts
|
|
33513
|
-
var PI_CTX_REDUCE_KEEP = CTX_REDUCE_KEEP;
|
|
33514
|
-
var DEDUP_SAFE_TOOLS = new Set([
|
|
33515
|
-
"grep",
|
|
33516
|
-
"read",
|
|
33517
|
-
"glob",
|
|
33518
|
-
"ast_grep_search",
|
|
33519
|
-
"lsp_diagnostics",
|
|
33520
|
-
"lsp_symbols",
|
|
33521
|
-
"lsp_find_references",
|
|
33522
|
-
"lsp_goto_definition",
|
|
33523
|
-
"lsp_prepare_rename",
|
|
33524
|
-
"mcp_grep",
|
|
33525
|
-
"mcp_read",
|
|
33526
|
-
"mcp_glob",
|
|
33527
|
-
"mcp_ast_grep_search",
|
|
33528
|
-
"mcp_lsp_diagnostics",
|
|
33529
|
-
"mcp_lsp_symbols",
|
|
33530
|
-
"mcp_lsp_find_references",
|
|
33531
|
-
"mcp_lsp_goto_definition",
|
|
33532
|
-
"mcp_lsp_prepare_rename"
|
|
33533
|
-
]);
|
|
33534
|
-
function buildPiToolFingerprints(messages, resolveStableId) {
|
|
33535
|
-
const fingerprints = new Map;
|
|
33536
|
-
for (let i = 0;i < messages.length; i++) {
|
|
33537
|
-
const message = messages[i];
|
|
33538
|
-
if (!message || typeof message !== "object")
|
|
33539
|
-
continue;
|
|
33540
|
-
const msg = message;
|
|
33541
|
-
if (msg.role !== "assistant")
|
|
33542
|
-
continue;
|
|
33543
|
-
if (!Array.isArray(msg.content))
|
|
33544
|
-
continue;
|
|
33545
|
-
const ownerMsgId = resolveStableId(message, i);
|
|
33546
|
-
if (!ownerMsgId)
|
|
33547
|
-
continue;
|
|
33548
|
-
for (const part of msg.content) {
|
|
33549
|
-
if (!part || typeof part !== "object")
|
|
33550
|
-
continue;
|
|
33551
|
-
const p = part;
|
|
33552
|
-
if (p.type !== "toolCall")
|
|
33553
|
-
continue;
|
|
33554
|
-
if (typeof p.name !== "string")
|
|
33555
|
-
continue;
|
|
33556
|
-
if (!DEDUP_SAFE_TOOLS.has(p.name))
|
|
33557
|
-
continue;
|
|
33558
|
-
if (typeof p.id !== "string" || p.id.length === 0)
|
|
33559
|
-
continue;
|
|
33560
|
-
const args = p.arguments;
|
|
33561
|
-
if (args && typeof args === "object" && "__magic_context_dropped__" in args) {
|
|
33562
|
-
continue;
|
|
33563
|
-
}
|
|
33564
|
-
let serialized;
|
|
33565
|
-
try {
|
|
33566
|
-
serialized = JSON.stringify(args ?? {});
|
|
33567
|
-
} catch {
|
|
33568
|
-
continue;
|
|
33569
|
-
}
|
|
33570
|
-
const fingerprint = `${ownerMsgId}:${p.name}:${serialized}`;
|
|
33571
|
-
const compositeKey = `${ownerMsgId}\x00${p.id}`;
|
|
33572
|
-
fingerprints.set(compositeKey, fingerprint);
|
|
33573
|
-
}
|
|
33574
|
-
}
|
|
33575
|
-
return fingerprints;
|
|
33576
|
-
}
|
|
33577
|
-
function collectStaleReduceCallIds(messages, messageIdToMaxTag, ctxReduceTagNumbers, toolAgeCutoff, resolveStableId) {
|
|
33578
|
-
const reduceCalls = new Map;
|
|
33579
|
-
for (let i = 0;i < messages.length; i++) {
|
|
33580
|
-
const raw = messages[i];
|
|
33581
|
-
if (!raw || typeof raw !== "object")
|
|
33582
|
-
continue;
|
|
33583
|
-
const msg = raw;
|
|
33584
|
-
if (msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
33585
|
-
continue;
|
|
33586
|
-
const stableId = resolveStableId(raw, i);
|
|
33587
|
-
if (!stableId)
|
|
33588
|
-
continue;
|
|
33589
|
-
const ownerMaxTag = messageIdToMaxTag.get(stableId) ?? 0;
|
|
33590
|
-
for (const part of msg.content) {
|
|
33591
|
-
if (!part || typeof part !== "object")
|
|
33592
|
-
continue;
|
|
33593
|
-
const p = part;
|
|
33594
|
-
if (p.type !== "toolCall")
|
|
33595
|
-
continue;
|
|
33596
|
-
if (p.name !== "mmc_reduce")
|
|
33597
|
-
continue;
|
|
33598
|
-
if (typeof p.id !== "string" || p.id.length === 0)
|
|
33599
|
-
continue;
|
|
33600
|
-
const composite = `${stableId}\x00${p.id}`;
|
|
33601
|
-
const maxTag = ctxReduceTagNumbers.get(composite) ?? ownerMaxTag;
|
|
33602
|
-
if (maxTag === 0)
|
|
33603
|
-
continue;
|
|
33604
|
-
reduceCalls.set(composite, {
|
|
33605
|
-
composite,
|
|
33606
|
-
callId: p.id,
|
|
33607
|
-
maxTag,
|
|
33608
|
-
messageIndex: i
|
|
33609
|
-
});
|
|
33610
|
-
}
|
|
33611
|
-
}
|
|
33612
|
-
const newestFirst = [...reduceCalls.values()].sort((left, right) => {
|
|
33613
|
-
const byPosition = right.maxTag - left.maxTag || right.messageIndex - left.messageIndex;
|
|
33614
|
-
if (byPosition !== 0)
|
|
33615
|
-
return byPosition;
|
|
33616
|
-
if (left.composite === right.composite)
|
|
33617
|
-
return 0;
|
|
33618
|
-
return left.composite < right.composite ? 1 : -1;
|
|
33619
|
-
});
|
|
33620
|
-
const composite = new Set;
|
|
33621
|
-
const bareCallIds = new Set;
|
|
33622
|
-
for (const call of newestFirst) {
|
|
33623
|
-
if (call.maxTag > toolAgeCutoff)
|
|
33624
|
-
continue;
|
|
33625
|
-
composite.add(call.composite);
|
|
33626
|
-
bareCallIds.add(call.callId);
|
|
33627
|
-
}
|
|
33628
|
-
return { composite, bareCallIds };
|
|
33629
|
-
}
|
|
33630
|
-
function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, preloadedTags, resolveId) {
|
|
33631
|
-
const resolveStableId = (msg, index) => {
|
|
33632
|
-
if (resolveId)
|
|
33633
|
-
return resolveId(msg, index);
|
|
33634
|
-
if (!msg || typeof msg !== "object")
|
|
33635
|
-
return;
|
|
33636
|
-
const m = msg;
|
|
33637
|
-
const role = typeof m.role === "string" ? m.role : "unknown";
|
|
33638
|
-
return typeof m.timestamp === "number" ? `pi-msg-${index}-${m.timestamp}-${role}` : `pi-msg-${index}-${role}`;
|
|
33639
|
-
};
|
|
33640
|
-
const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
|
|
33641
|
-
const protectedTools = config.protectedToolTags ?? protectedToolTagNumbers(tags, config.protectedTools);
|
|
33642
|
-
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
33643
|
-
const protectedCutoff = config.protectedCutoff === null ? maxTag + 1 : config.protectedCutoff ?? maxTag - config.protectedTags;
|
|
33644
|
-
const routine = config.routine !== false;
|
|
33645
|
-
const toolAgeCutoff = protectedCutoff;
|
|
33646
|
-
let droppedTools = 0;
|
|
33647
|
-
let emergencyDroppedTools = 0;
|
|
33648
|
-
let deduplicatedTools = 0;
|
|
33649
|
-
let droppedInjections = 0;
|
|
33650
|
-
let droppedStaleReduceCalls = 0;
|
|
33651
|
-
const droppedTokenReductions = [];
|
|
33652
|
-
if (config.emergency) {
|
|
33653
|
-
const emergency = config.emergency;
|
|
33654
|
-
const priorInputSample = getEmergencyInputSample(db, sessionId);
|
|
33655
|
-
const candidateTags = tags.filter((t) => t.status === "active" && t.type === "tool" && targets.get(t.tagNumber)?.canDrop?.());
|
|
33656
|
-
const recentTags = new Set(candidateTags.slice().sort((a, b) => b.tagNumber - a.tagNumber).slice(0, 20).map((tag) => tag.tagNumber));
|
|
33657
|
-
const calibration = sessionDecisionCalibration(db, sessionId);
|
|
33658
|
-
const activeTags = tags.filter((t) => t.status === "active").map((tag) => measureEmergencyTag(tag, targets.get(tag.tagNumber), calibration, targets.get(tag.tagNumber)?.requiresToolArcSkeleton === true || (emergency.usagePercentage ?? 0) < 95 && recentTags.has(tag.tagNumber) && hasSmallToolInput(targets.get(tag.tagNumber))));
|
|
33659
|
-
const byTag = new Map(activeTags.map((tag) => [tag.tagNumber, tag]));
|
|
33660
|
-
const droppableTags = candidateTags.flatMap((tag) => {
|
|
33661
|
-
const measured = byTag.get(tag.tagNumber);
|
|
33662
|
-
return measured ? [measured] : [];
|
|
33663
|
-
}).filter((tag) => (tag.reclaimableTokens ?? 0) > 0);
|
|
33664
|
-
sessionLog(sessionId, `emergency candidates: loaded=${tags.length} active=${activeTags.length} activeTools=${activeTags.filter((tag) => tag.type === "tool").length} visibleCompleteTools=${droppableTags.length} windowYields=${(emergency.usagePercentage ?? 0) >= 95} cutoff=${protectedCutoff}`);
|
|
33665
|
-
const plan = planEmergencyDrop({
|
|
33666
|
-
tags: droppableTags,
|
|
33667
|
-
floorTags: activeTags,
|
|
33668
|
-
maxTag,
|
|
33669
|
-
protectedCutoff,
|
|
33670
|
-
currentTotalInputTokens: emergency.currentTotalInputTokens,
|
|
33671
|
-
ceilingTokens: emergency.ceilingTokens,
|
|
33672
|
-
usagePercentage: emergency.usagePercentage,
|
|
33673
|
-
priorInputSample,
|
|
33674
|
-
hasPriorDrop: priorInputSample > 0,
|
|
33675
|
-
passAlreadyPriced: emergency.passAlreadyPriced === true,
|
|
33676
|
-
protectedToolTags: protectedTools
|
|
33677
|
-
});
|
|
33678
|
-
if (plan.shouldDrop) {
|
|
33679
|
-
const toDrop = new Set(plan.tagNumbers);
|
|
33680
|
-
const newestEmergencyTags = recentTags;
|
|
33681
|
-
db.transaction(() => {
|
|
33682
|
-
for (const tag of tags) {
|
|
33683
|
-
if (!toDrop.has(tag.tagNumber))
|
|
33684
|
-
continue;
|
|
33685
|
-
if (tag.status !== "active" || tag.type !== "tool")
|
|
33686
|
-
continue;
|
|
33687
|
-
const target = targets.get(tag.tagNumber);
|
|
33688
|
-
const recent = (emergency.usagePercentage ?? 0) < 95 && newestEmergencyTags.has(tag.tagNumber);
|
|
33689
|
-
const { result, mode } = applyNewToolDrop(target, {
|
|
33690
|
-
inWindow: recent,
|
|
33691
|
-
keepSkeleton: target?.requiresToolArcSkeleton === true
|
|
33692
|
-
});
|
|
33693
|
-
if (result === "removed" || result === "truncated") {
|
|
33694
|
-
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
33695
|
-
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
33696
|
-
droppedTools++;
|
|
33697
|
-
emergencyDroppedTools++;
|
|
33698
|
-
droppedTokenReductions.push({
|
|
33699
|
-
tagNumber: tag.tagNumber,
|
|
33700
|
-
mode: mode === "full" ? "full" : "truncated"
|
|
33701
|
-
});
|
|
33702
|
-
}
|
|
33703
|
-
}
|
|
33704
|
-
}).immediate();
|
|
33705
|
-
sessionLog(sessionId, `emergency tiered drop: ${plan.reason}`);
|
|
33706
|
-
} else {
|
|
33707
|
-
sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
|
|
33708
|
-
}
|
|
33709
|
-
}
|
|
33710
|
-
const staleReduce = routine && config.staleReduceStripEnabled ? collectStaleReduceCallIds(piMessages, buildMessageIdToMaxTagFromTargets(targets), buildCtxReduceTagNumbers(tags), toolAgeCutoff, resolveStableId) : { composite: new Set, bareCallIds: new Set };
|
|
33711
|
-
if (routine && config.staleReduceStripEnabled && (staleReduce.composite.size > 0 || staleReduce.bareCallIds.size > 0)) {
|
|
33712
|
-
db.transaction(() => {
|
|
33713
|
-
for (const tag of tags) {
|
|
33714
|
-
if (tag.status !== "active")
|
|
33715
|
-
continue;
|
|
33716
|
-
if (tag.type !== "tool")
|
|
33717
|
-
continue;
|
|
33718
|
-
if (protectedTools.has(tag.tagNumber))
|
|
33719
|
-
continue;
|
|
33720
|
-
if (!tag.messageId)
|
|
33721
|
-
continue;
|
|
33722
|
-
const matched = tag.toolOwnerMessageId ? staleReduce.composite.has(`${tag.toolOwnerMessageId}\x00${tag.messageId}`) : staleReduce.bareCallIds.has(tag.messageId);
|
|
33723
|
-
if (!matched)
|
|
33724
|
-
continue;
|
|
33725
|
-
const target = targets.get(tag.tagNumber);
|
|
33726
|
-
if (target?.canDrop?.() === false)
|
|
33727
|
-
continue;
|
|
33728
|
-
const { result, mode } = applyNewToolDrop(target, { inWindow: false });
|
|
33729
|
-
if (result === "incomplete")
|
|
33730
|
-
continue;
|
|
33731
|
-
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
33732
|
-
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
33733
|
-
if (result === "removed" || result === "truncated") {
|
|
33734
|
-
droppedStaleReduceCalls++;
|
|
33735
|
-
config.onStaleReduceEdit?.(tag);
|
|
33736
|
-
}
|
|
33737
|
-
}
|
|
33738
|
-
}).immediate();
|
|
33739
|
-
}
|
|
33740
|
-
if (routine) {
|
|
33741
|
-
db.transaction(() => {
|
|
33742
|
-
for (const tag of tags) {
|
|
33743
|
-
if (tag.status !== "active")
|
|
33744
|
-
continue;
|
|
33745
|
-
if (tag.tagNumber > protectedCutoff)
|
|
33746
|
-
continue;
|
|
33747
|
-
if (tag.type !== "message")
|
|
33748
|
-
continue;
|
|
33749
|
-
const target = targets.get(tag.tagNumber);
|
|
33750
|
-
if (!target)
|
|
33751
|
-
continue;
|
|
33752
|
-
const content = target.getContent?.();
|
|
33753
|
-
if (!content)
|
|
33754
|
-
continue;
|
|
33755
|
-
const stripped = stripSystemInjection(content);
|
|
33756
|
-
if (stripped === null)
|
|
33757
|
-
continue;
|
|
33758
|
-
const strippedSource = stripTagPrefix(stripped);
|
|
33759
|
-
if (strippedSource.trim().length === 0) {
|
|
33760
|
-
if (target.thinkingDropProtected)
|
|
33761
|
-
continue;
|
|
33762
|
-
const dropResult = target.drop?.() ?? "absent";
|
|
33763
|
-
const didReplace = dropResult === "absent" ? target.setContent(`[dropped §${tag.tagNumber}§]`) : false;
|
|
33764
|
-
if (dropResult === "removed" || dropResult === "absent") {
|
|
33765
|
-
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
33766
|
-
if (dropResult === "removed" || didReplace) {
|
|
33767
|
-
droppedInjections++;
|
|
33768
|
-
droppedTokenReductions.push({
|
|
33769
|
-
tagNumber: tag.tagNumber,
|
|
33770
|
-
mode: "full"
|
|
33771
|
-
});
|
|
33772
|
-
}
|
|
33773
|
-
}
|
|
33774
|
-
} else {
|
|
33775
|
-
if (freezePiContentDecision(db, sessionId, "reminder-strip", tag.messageId)) {
|
|
33776
|
-
if (target.setContent(stripped)) {
|
|
33777
|
-
droppedInjections++;
|
|
33778
|
-
droppedTokenReductions.push({
|
|
33779
|
-
tagNumber: tag.tagNumber,
|
|
33780
|
-
mode: "partial",
|
|
33781
|
-
removedCharacters: Math.max(0, content.length - stripped.length)
|
|
33782
|
-
});
|
|
33783
|
-
}
|
|
33784
|
-
}
|
|
33785
|
-
}
|
|
33786
|
-
}
|
|
33787
|
-
}).immediate();
|
|
33788
|
-
}
|
|
33789
|
-
const toolFingerprints = routine ? buildPiToolFingerprints(piMessages, resolveStableId) : new Map;
|
|
33790
|
-
if (toolFingerprints.size > 0) {
|
|
33791
|
-
const tagsByCompositeKey = new Map;
|
|
33792
|
-
for (const tag of tags) {
|
|
33793
|
-
if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
|
|
33794
|
-
const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
|
|
33795
|
-
tagsByCompositeKey.set(key, tag);
|
|
33796
|
-
}
|
|
33797
|
-
}
|
|
33798
|
-
const fingerprintGroups = new Map;
|
|
33799
|
-
for (const [compositeKey, fingerprint] of toolFingerprints) {
|
|
33800
|
-
const tag = tagsByCompositeKey.get(compositeKey);
|
|
33801
|
-
if (!tag)
|
|
33802
|
-
continue;
|
|
33803
|
-
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
33804
|
-
group.push(tag);
|
|
33805
|
-
fingerprintGroups.set(fingerprint, group);
|
|
33806
|
-
}
|
|
33807
|
-
db.transaction(() => {
|
|
33808
|
-
for (const [, group] of fingerprintGroups) {
|
|
33809
|
-
if (group.length <= 1)
|
|
33810
|
-
continue;
|
|
33811
|
-
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
33812
|
-
for (let i = 0;i < group.length - 1; i++) {
|
|
33813
|
-
const tag = group[i];
|
|
33814
|
-
if (tag.tagNumber > protectedCutoff)
|
|
33815
|
-
continue;
|
|
33816
|
-
const target = targets.get(tag.tagNumber);
|
|
33817
|
-
if (protectedTools.has(tag.tagNumber))
|
|
33818
|
-
continue;
|
|
33819
|
-
if (target?.canDrop?.() === false)
|
|
33820
|
-
continue;
|
|
33821
|
-
const { result, mode } = applyNewToolDrop(target, {
|
|
33822
|
-
inWindow: false
|
|
33823
|
-
});
|
|
33824
|
-
if (result === "incomplete")
|
|
33825
|
-
continue;
|
|
33826
|
-
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
33827
|
-
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
33828
|
-
if (result === "removed" || result === "truncated") {
|
|
33829
|
-
deduplicatedTools++;
|
|
33830
|
-
droppedTokenReductions.push({
|
|
33831
|
-
tagNumber: tag.tagNumber,
|
|
33832
|
-
mode: mode === "full" ? "full" : "truncated"
|
|
33833
|
-
});
|
|
33834
|
-
}
|
|
33835
|
-
}
|
|
33836
|
-
}
|
|
33837
|
-
}).immediate();
|
|
33838
|
-
}
|
|
33839
|
-
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
|
|
33840
|
-
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale mmc_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
33841
|
-
}
|
|
33842
|
-
let compressedTextTags = 0;
|
|
33843
|
-
let mutatedTextTags = 0;
|
|
33844
|
-
if (routine && config.caveman?.enabled) {
|
|
33845
|
-
const cavemanTags = getActiveTagsBySession(db, sessionId);
|
|
33846
|
-
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, cavemanTags, {
|
|
33847
|
-
enabled: true,
|
|
33848
|
-
minChars: config.caveman.minChars,
|
|
33849
|
-
wordRules: config.caveman.wordRules,
|
|
33850
|
-
protectedCutoff
|
|
33851
|
-
});
|
|
33852
|
-
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
33853
|
-
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
33854
|
-
if (cavemanResult.textReductions) {
|
|
33855
|
-
for (const r of cavemanResult.textReductions) {
|
|
33856
|
-
droppedTokenReductions.push({
|
|
33857
|
-
tagNumber: r.tagNumber,
|
|
33858
|
-
mode: "partial",
|
|
33859
|
-
removedCharacters: r.removedCharacters
|
|
33860
|
-
});
|
|
33861
|
-
}
|
|
33862
|
-
}
|
|
33863
|
-
}
|
|
33864
|
-
return {
|
|
33865
|
-
droppedTools,
|
|
33866
|
-
deduplicatedTools,
|
|
33867
|
-
droppedInjections,
|
|
33868
|
-
droppedStaleReduceCalls,
|
|
33869
|
-
emergencyDroppedTools,
|
|
33870
|
-
compressedTextTags,
|
|
33871
|
-
mutatedTextTags,
|
|
33872
|
-
droppedTokenReductions
|
|
33873
|
-
};
|
|
33874
|
-
}
|
|
33875
|
-
function buildCtxReduceTagNumbers(tags) {
|
|
33876
|
-
const byComposite = new Map;
|
|
33877
|
-
for (const tag of tags) {
|
|
33878
|
-
if (tag.status !== "active" || tag.type !== "tool" || tag.toolName !== "mmc_reduce" || !tag.toolOwnerMessageId) {
|
|
33879
|
-
continue;
|
|
33880
|
-
}
|
|
33881
|
-
byComposite.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag.tagNumber);
|
|
33882
|
-
}
|
|
33883
|
-
return byComposite;
|
|
33884
|
-
}
|
|
33885
|
-
function buildMessageIdToMaxTagFromTargets(targets) {
|
|
33886
|
-
const byMessage = new Map;
|
|
33887
|
-
for (const [tagNumber, target] of targets) {
|
|
33888
|
-
const id = target.message?.info?.id;
|
|
33889
|
-
if (typeof id !== "string" || id.length === 0)
|
|
33890
|
-
continue;
|
|
33891
|
-
if (tagNumber > (byMessage.get(id) ?? 0))
|
|
33892
|
-
byMessage.set(id, tagNumber);
|
|
33893
|
-
}
|
|
33894
|
-
return byMessage;
|
|
33895
|
-
}
|
|
33896
|
-
|
|
33897
33673
|
// src/tail-hygiene-walk-pi.ts
|
|
33898
33674
|
var TAG_PREFIX = /^§(\d+)§\s*/;
|
|
33899
33675
|
var SYNTHETIC_TODO_PREFIX = "mc_synthetic_todo_";
|
|
@@ -34205,14 +33981,14 @@ function excludedDraft(key, value) {
|
|
|
34205
33981
|
tokens: 0
|
|
34206
33982
|
};
|
|
34207
33983
|
}
|
|
34208
|
-
function finalizeParts(drafts, pendingDropTagNumbers, protectedTagNumbers, newestMessagePartStart) {
|
|
33984
|
+
function finalizeParts(drafts, pendingDropTagNumbers, protectedTagNumbers, newestMessagePartStart, protectedToolTags) {
|
|
34209
33985
|
const visibleTags = new Map;
|
|
34210
33986
|
for (const part of drafts) {
|
|
34211
33987
|
if (part.kind !== "excluded" && part.tag)
|
|
34212
33988
|
visibleTags.set(part.tag.tagNumber, part.tag);
|
|
34213
33989
|
}
|
|
34214
33990
|
const protectedNumbers = new Set(protectedTagNumbers);
|
|
34215
|
-
const exemplarNumbers = [...visibleTags.values()]
|
|
33991
|
+
const exemplarNumbers = protectedToolTags ?? protectedToolTagNumbers([...visibleTags.values()]);
|
|
34216
33992
|
for (const tagNumber of exemplarNumbers)
|
|
34217
33993
|
protectedNumbers.add(tagNumber);
|
|
34218
33994
|
let u = 0;
|
|
@@ -34379,9 +34155,14 @@ function measurePiTailHygiene(input) {
|
|
|
34379
34155
|
drafts.push(excludedDraft(`${key}\x00excluded`, part));
|
|
34380
34156
|
}
|
|
34381
34157
|
}
|
|
34382
|
-
return finalizeParts(drafts, input.pendingDropTagNumbers ?? new Set, input.protectedTagNumbers, newestMessagePartStart);
|
|
34158
|
+
return finalizeParts(drafts, input.pendingDropTagNumbers ?? new Set, input.protectedTagNumbers, newestMessagePartStart, input.protectedToolTags);
|
|
34383
34159
|
}
|
|
34384
34160
|
function refreshPiTailHygieneBaseline(input) {
|
|
34161
|
+
const protectedToolsPolicy = adoptedProtectedToolsPolicy(input.protectedTools, input.previous?.protectedToolsPolicy, input.cacheBusting, !!input.previous);
|
|
34162
|
+
input = {
|
|
34163
|
+
...input,
|
|
34164
|
+
protectedToolTags: protectedToolTagNumbers(input.tags, protectedToolsPolicy)
|
|
34165
|
+
};
|
|
34385
34166
|
const rawMeasured = measurePiTailHygiene(input);
|
|
34386
34167
|
const frozenCalibration = !input.cacheBusting && input.previous ? {
|
|
34387
34168
|
toolsRatio: input.previous.toolsRatio,
|
|
@@ -34406,6 +34187,7 @@ function refreshPiTailHygieneBaseline(input) {
|
|
|
34406
34187
|
const now = input.now ?? Date.now();
|
|
34407
34188
|
const refrozen = (mismatch) => ({
|
|
34408
34189
|
...freezeTailHygieneMeasurement(measured),
|
|
34190
|
+
protectedToolsPolicy,
|
|
34409
34191
|
hygieneUnitsVersion: frozenCalibration.hygieneUnitsVersion,
|
|
34410
34192
|
toolsRatio: frozenCalibration.toolsRatio,
|
|
34411
34193
|
proseRatio: frozenCalibration.proseRatio,
|
|
@@ -34432,6 +34214,7 @@ function refreshPiTailHygieneBaseline(input) {
|
|
|
34432
34214
|
}
|
|
34433
34215
|
return {
|
|
34434
34216
|
...input.previous,
|
|
34217
|
+
protectedToolsPolicy,
|
|
34435
34218
|
turnDeltaU,
|
|
34436
34219
|
turnDeltaT,
|
|
34437
34220
|
evaluable: true,
|
|
@@ -34789,6 +34572,390 @@ function hasPiFallbackMessageTags2(db, sessionId) {
|
|
|
34789
34572
|
return probe(db, sessionId, "message");
|
|
34790
34573
|
}
|
|
34791
34574
|
|
|
34575
|
+
// src/heuristic-cleanup-pi.ts
|
|
34576
|
+
var DEDUP_SAFE_TOOLS = new Set([
|
|
34577
|
+
"grep",
|
|
34578
|
+
"read",
|
|
34579
|
+
"glob",
|
|
34580
|
+
"ast_grep_search",
|
|
34581
|
+
"lsp_diagnostics",
|
|
34582
|
+
"lsp_symbols",
|
|
34583
|
+
"lsp_find_references",
|
|
34584
|
+
"lsp_goto_definition",
|
|
34585
|
+
"lsp_prepare_rename",
|
|
34586
|
+
"mcp_grep",
|
|
34587
|
+
"mcp_read",
|
|
34588
|
+
"mcp_glob",
|
|
34589
|
+
"mcp_ast_grep_search",
|
|
34590
|
+
"mcp_lsp_diagnostics",
|
|
34591
|
+
"mcp_lsp_symbols",
|
|
34592
|
+
"mcp_lsp_find_references",
|
|
34593
|
+
"mcp_lsp_goto_definition",
|
|
34594
|
+
"mcp_lsp_prepare_rename"
|
|
34595
|
+
]);
|
|
34596
|
+
function buildPiToolFingerprints(messages, resolveStableId) {
|
|
34597
|
+
const fingerprints = new Map;
|
|
34598
|
+
for (let i = 0;i < messages.length; i++) {
|
|
34599
|
+
const message = messages[i];
|
|
34600
|
+
if (!message || typeof message !== "object")
|
|
34601
|
+
continue;
|
|
34602
|
+
const msg = message;
|
|
34603
|
+
if (msg.role !== "assistant")
|
|
34604
|
+
continue;
|
|
34605
|
+
if (!Array.isArray(msg.content))
|
|
34606
|
+
continue;
|
|
34607
|
+
const ownerMsgId = resolveStableId(message, i);
|
|
34608
|
+
if (!ownerMsgId)
|
|
34609
|
+
continue;
|
|
34610
|
+
for (const part of msg.content) {
|
|
34611
|
+
if (!part || typeof part !== "object")
|
|
34612
|
+
continue;
|
|
34613
|
+
const p = part;
|
|
34614
|
+
if (p.type !== "toolCall")
|
|
34615
|
+
continue;
|
|
34616
|
+
if (typeof p.name !== "string")
|
|
34617
|
+
continue;
|
|
34618
|
+
if (!DEDUP_SAFE_TOOLS.has(p.name))
|
|
34619
|
+
continue;
|
|
34620
|
+
if (typeof p.id !== "string" || p.id.length === 0)
|
|
34621
|
+
continue;
|
|
34622
|
+
const args = p.arguments;
|
|
34623
|
+
if (args && typeof args === "object" && "__magic_context_dropped__" in args) {
|
|
34624
|
+
continue;
|
|
34625
|
+
}
|
|
34626
|
+
let serialized;
|
|
34627
|
+
try {
|
|
34628
|
+
serialized = JSON.stringify(args ?? {});
|
|
34629
|
+
} catch {
|
|
34630
|
+
continue;
|
|
34631
|
+
}
|
|
34632
|
+
const fingerprint = `${ownerMsgId}:${p.name}:${serialized}`;
|
|
34633
|
+
const compositeKey = `${ownerMsgId}\x00${p.id}`;
|
|
34634
|
+
fingerprints.set(compositeKey, fingerprint);
|
|
34635
|
+
}
|
|
34636
|
+
}
|
|
34637
|
+
return fingerprints;
|
|
34638
|
+
}
|
|
34639
|
+
function collectStaleReduceCallIds(messages, messageIdToMaxTag, ctxReduceTagNumbers, toolAgeCutoff, resolveStableId) {
|
|
34640
|
+
const reduceCalls = new Map;
|
|
34641
|
+
for (let i = 0;i < messages.length; i++) {
|
|
34642
|
+
const raw = messages[i];
|
|
34643
|
+
if (!raw || typeof raw !== "object")
|
|
34644
|
+
continue;
|
|
34645
|
+
const msg = raw;
|
|
34646
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
34647
|
+
continue;
|
|
34648
|
+
const stableId = resolveStableId(raw, i);
|
|
34649
|
+
if (!stableId)
|
|
34650
|
+
continue;
|
|
34651
|
+
const ownerMaxTag = messageIdToMaxTag.get(stableId) ?? 0;
|
|
34652
|
+
for (const part of msg.content) {
|
|
34653
|
+
if (!part || typeof part !== "object")
|
|
34654
|
+
continue;
|
|
34655
|
+
const p = part;
|
|
34656
|
+
if (p.type !== "toolCall")
|
|
34657
|
+
continue;
|
|
34658
|
+
if (p.name !== "mmc_reduce")
|
|
34659
|
+
continue;
|
|
34660
|
+
if (typeof p.id !== "string" || p.id.length === 0)
|
|
34661
|
+
continue;
|
|
34662
|
+
const composite = `${stableId}\x00${p.id}`;
|
|
34663
|
+
const maxTag = ctxReduceTagNumbers.get(composite) ?? ownerMaxTag;
|
|
34664
|
+
if (maxTag === 0)
|
|
34665
|
+
continue;
|
|
34666
|
+
reduceCalls.set(composite, {
|
|
34667
|
+
composite,
|
|
34668
|
+
callId: p.id,
|
|
34669
|
+
maxTag,
|
|
34670
|
+
messageIndex: i
|
|
34671
|
+
});
|
|
34672
|
+
}
|
|
34673
|
+
}
|
|
34674
|
+
const newestFirst = [...reduceCalls.values()].sort((left, right) => {
|
|
34675
|
+
const byPosition = right.maxTag - left.maxTag || right.messageIndex - left.messageIndex;
|
|
34676
|
+
if (byPosition !== 0)
|
|
34677
|
+
return byPosition;
|
|
34678
|
+
if (left.composite === right.composite)
|
|
34679
|
+
return 0;
|
|
34680
|
+
return left.composite < right.composite ? 1 : -1;
|
|
34681
|
+
});
|
|
34682
|
+
const composite = new Set;
|
|
34683
|
+
const bareCallIds = new Set;
|
|
34684
|
+
for (const call of newestFirst) {
|
|
34685
|
+
if (call.maxTag > toolAgeCutoff)
|
|
34686
|
+
continue;
|
|
34687
|
+
composite.add(call.composite);
|
|
34688
|
+
bareCallIds.add(call.callId);
|
|
34689
|
+
}
|
|
34690
|
+
return { composite, bareCallIds };
|
|
34691
|
+
}
|
|
34692
|
+
function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, preloadedTags, resolveId) {
|
|
34693
|
+
const resolveStableId = (msg, index) => {
|
|
34694
|
+
if (resolveId)
|
|
34695
|
+
return resolveId(msg, index);
|
|
34696
|
+
if (!msg || typeof msg !== "object")
|
|
34697
|
+
return;
|
|
34698
|
+
const m = msg;
|
|
34699
|
+
const role = typeof m.role === "string" ? m.role : "unknown";
|
|
34700
|
+
return typeof m.timestamp === "number" ? `pi-msg-${index}-${m.timestamp}-${role}` : `pi-msg-${index}-${role}`;
|
|
34701
|
+
};
|
|
34702
|
+
const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
|
|
34703
|
+
const protectedTools = config.protectedToolTags ?? protectedToolTagNumbers(tags, config.protectedTools);
|
|
34704
|
+
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
34705
|
+
const protectedCutoff = config.protectedCutoff === null ? maxTag + 1 : config.protectedCutoff ?? maxTag - config.protectedTags;
|
|
34706
|
+
const routine = config.routine !== false;
|
|
34707
|
+
const toolAgeCutoff = protectedCutoff;
|
|
34708
|
+
let droppedTools = 0;
|
|
34709
|
+
let emergencyDroppedTools = 0;
|
|
34710
|
+
let deduplicatedTools = 0;
|
|
34711
|
+
let droppedInjections = 0;
|
|
34712
|
+
let droppedStaleReduceCalls = 0;
|
|
34713
|
+
const droppedTokenReductions = [];
|
|
34714
|
+
if (config.emergency) {
|
|
34715
|
+
const emergency = config.emergency;
|
|
34716
|
+
const priorInputSample = getEmergencyInputSample(db, sessionId);
|
|
34717
|
+
const candidateTags = tags.filter((t) => t.status === "active" && t.type === "tool" && targets.get(t.tagNumber)?.canDrop?.());
|
|
34718
|
+
const recentTags = new Set(candidateTags.slice().sort((a, b) => b.tagNumber - a.tagNumber).slice(0, 20).map((tag) => tag.tagNumber));
|
|
34719
|
+
const calibration = sessionDecisionCalibration(db, sessionId);
|
|
34720
|
+
const activeTags = tags.filter((t) => t.status === "active").map((tag) => measureEmergencyTag(tag, targets.get(tag.tagNumber), calibration, targets.get(tag.tagNumber)?.requiresToolArcSkeleton === true || (emergency.usagePercentage ?? 0) < 95 && recentTags.has(tag.tagNumber) && hasSmallToolInput(targets.get(tag.tagNumber))));
|
|
34721
|
+
const byTag = new Map(activeTags.map((tag) => [tag.tagNumber, tag]));
|
|
34722
|
+
const droppableTags = candidateTags.flatMap((tag) => {
|
|
34723
|
+
const measured = byTag.get(tag.tagNumber);
|
|
34724
|
+
return measured ? [measured] : [];
|
|
34725
|
+
}).filter((tag) => (tag.reclaimableTokens ?? 0) > 0);
|
|
34726
|
+
sessionLog(sessionId, `emergency candidates: loaded=${tags.length} active=${activeTags.length} activeTools=${activeTags.filter((tag) => tag.type === "tool").length} visibleCompleteTools=${droppableTags.length} windowYields=${(emergency.usagePercentage ?? 0) >= 95} cutoff=${protectedCutoff}`);
|
|
34727
|
+
const plan = planEmergencyDrop({
|
|
34728
|
+
tags: droppableTags,
|
|
34729
|
+
floorTags: activeTags,
|
|
34730
|
+
maxTag,
|
|
34731
|
+
protectedCutoff,
|
|
34732
|
+
currentTotalInputTokens: emergency.currentTotalInputTokens,
|
|
34733
|
+
ceilingTokens: emergency.ceilingTokens,
|
|
34734
|
+
usagePercentage: emergency.usagePercentage,
|
|
34735
|
+
priorInputSample,
|
|
34736
|
+
hasPriorDrop: priorInputSample > 0,
|
|
34737
|
+
passAlreadyPriced: emergency.passAlreadyPriced === true,
|
|
34738
|
+
protectedToolTags: protectedTools
|
|
34739
|
+
});
|
|
34740
|
+
if (plan.shouldDrop) {
|
|
34741
|
+
const toDrop = new Set(plan.tagNumbers);
|
|
34742
|
+
const newestEmergencyTags = recentTags;
|
|
34743
|
+
db.transaction(() => {
|
|
34744
|
+
for (const tag of tags) {
|
|
34745
|
+
if (!toDrop.has(tag.tagNumber))
|
|
34746
|
+
continue;
|
|
34747
|
+
if (tag.status !== "active" || tag.type !== "tool")
|
|
34748
|
+
continue;
|
|
34749
|
+
const target = targets.get(tag.tagNumber);
|
|
34750
|
+
const recent = (emergency.usagePercentage ?? 0) < 95 && newestEmergencyTags.has(tag.tagNumber);
|
|
34751
|
+
const { result, mode } = applyNewToolDrop(target, {
|
|
34752
|
+
inWindow: recent,
|
|
34753
|
+
keepSkeleton: target?.requiresToolArcSkeleton === true
|
|
34754
|
+
});
|
|
34755
|
+
if (result === "removed" || result === "truncated") {
|
|
34756
|
+
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
34757
|
+
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
34758
|
+
droppedTools++;
|
|
34759
|
+
emergencyDroppedTools++;
|
|
34760
|
+
droppedTokenReductions.push({
|
|
34761
|
+
tagNumber: tag.tagNumber,
|
|
34762
|
+
mode: mode === "full" ? "full" : "truncated"
|
|
34763
|
+
});
|
|
34764
|
+
}
|
|
34765
|
+
}
|
|
34766
|
+
}).immediate();
|
|
34767
|
+
sessionLog(sessionId, `emergency tiered drop: ${plan.reason}`);
|
|
34768
|
+
} else {
|
|
34769
|
+
sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
|
|
34770
|
+
}
|
|
34771
|
+
}
|
|
34772
|
+
const staleReduce = routine && config.staleReduceStripEnabled ? collectStaleReduceCallIds(piMessages, buildMessageIdToMaxTagFromTargets(targets), buildCtxReduceTagNumbers(tags), toolAgeCutoff, resolveStableId) : { composite: new Set, bareCallIds: new Set };
|
|
34773
|
+
if (routine && config.staleReduceStripEnabled && (staleReduce.composite.size > 0 || staleReduce.bareCallIds.size > 0)) {
|
|
34774
|
+
db.transaction(() => {
|
|
34775
|
+
for (const tag of tags) {
|
|
34776
|
+
if (tag.status !== "active")
|
|
34777
|
+
continue;
|
|
34778
|
+
if (tag.type !== "tool")
|
|
34779
|
+
continue;
|
|
34780
|
+
if (protectedTools.has(tag.tagNumber))
|
|
34781
|
+
continue;
|
|
34782
|
+
if (!tag.messageId)
|
|
34783
|
+
continue;
|
|
34784
|
+
const matched = tag.toolOwnerMessageId ? staleReduce.composite.has(`${tag.toolOwnerMessageId}\x00${tag.messageId}`) : staleReduce.bareCallIds.has(tag.messageId);
|
|
34785
|
+
if (!matched)
|
|
34786
|
+
continue;
|
|
34787
|
+
const target = targets.get(tag.tagNumber);
|
|
34788
|
+
if (target?.canDrop?.() === false)
|
|
34789
|
+
continue;
|
|
34790
|
+
const { result, mode } = applyNewToolDrop(target, { inWindow: false });
|
|
34791
|
+
if (result === "incomplete")
|
|
34792
|
+
continue;
|
|
34793
|
+
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
34794
|
+
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
34795
|
+
if (result === "removed" || result === "truncated") {
|
|
34796
|
+
droppedStaleReduceCalls++;
|
|
34797
|
+
config.onStaleReduceEdit?.(tag);
|
|
34798
|
+
}
|
|
34799
|
+
}
|
|
34800
|
+
}).immediate();
|
|
34801
|
+
}
|
|
34802
|
+
if (routine) {
|
|
34803
|
+
db.transaction(() => {
|
|
34804
|
+
for (const tag of tags) {
|
|
34805
|
+
if (tag.status !== "active")
|
|
34806
|
+
continue;
|
|
34807
|
+
if (tag.tagNumber > protectedCutoff)
|
|
34808
|
+
continue;
|
|
34809
|
+
if (tag.type !== "message")
|
|
34810
|
+
continue;
|
|
34811
|
+
const target = targets.get(tag.tagNumber);
|
|
34812
|
+
if (!target)
|
|
34813
|
+
continue;
|
|
34814
|
+
const content = target.getContent?.();
|
|
34815
|
+
if (!content)
|
|
34816
|
+
continue;
|
|
34817
|
+
const stripped = stripSystemInjection(content);
|
|
34818
|
+
if (stripped === null)
|
|
34819
|
+
continue;
|
|
34820
|
+
const strippedSource = stripTagPrefix(stripped);
|
|
34821
|
+
if (strippedSource.trim().length === 0) {
|
|
34822
|
+
if (target.thinkingDropProtected)
|
|
34823
|
+
continue;
|
|
34824
|
+
const dropResult = target.drop?.() ?? "absent";
|
|
34825
|
+
const didReplace = dropResult === "absent" ? target.setContent(`[dropped §${tag.tagNumber}§]`) : false;
|
|
34826
|
+
if (dropResult === "removed" || dropResult === "absent") {
|
|
34827
|
+
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
34828
|
+
if (dropResult === "removed" || didReplace) {
|
|
34829
|
+
droppedInjections++;
|
|
34830
|
+
droppedTokenReductions.push({
|
|
34831
|
+
tagNumber: tag.tagNumber,
|
|
34832
|
+
mode: "full"
|
|
34833
|
+
});
|
|
34834
|
+
}
|
|
34835
|
+
}
|
|
34836
|
+
} else {
|
|
34837
|
+
if (freezePiContentDecision(db, sessionId, "reminder-strip", tag.messageId)) {
|
|
34838
|
+
if (target.setContent(stripped)) {
|
|
34839
|
+
droppedInjections++;
|
|
34840
|
+
droppedTokenReductions.push({
|
|
34841
|
+
tagNumber: tag.tagNumber,
|
|
34842
|
+
mode: "partial",
|
|
34843
|
+
removedCharacters: Math.max(0, content.length - stripped.length)
|
|
34844
|
+
});
|
|
34845
|
+
}
|
|
34846
|
+
}
|
|
34847
|
+
}
|
|
34848
|
+
}
|
|
34849
|
+
}).immediate();
|
|
34850
|
+
}
|
|
34851
|
+
const toolFingerprints = routine ? buildPiToolFingerprints(piMessages, resolveStableId) : new Map;
|
|
34852
|
+
if (toolFingerprints.size > 0) {
|
|
34853
|
+
const tagsByCompositeKey = new Map;
|
|
34854
|
+
for (const tag of tags) {
|
|
34855
|
+
if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
|
|
34856
|
+
const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
|
|
34857
|
+
tagsByCompositeKey.set(key, tag);
|
|
34858
|
+
}
|
|
34859
|
+
}
|
|
34860
|
+
const fingerprintGroups = new Map;
|
|
34861
|
+
for (const [compositeKey, fingerprint] of toolFingerprints) {
|
|
34862
|
+
const tag = tagsByCompositeKey.get(compositeKey);
|
|
34863
|
+
if (!tag)
|
|
34864
|
+
continue;
|
|
34865
|
+
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
34866
|
+
group.push(tag);
|
|
34867
|
+
fingerprintGroups.set(fingerprint, group);
|
|
34868
|
+
}
|
|
34869
|
+
db.transaction(() => {
|
|
34870
|
+
for (const [, group] of fingerprintGroups) {
|
|
34871
|
+
if (group.length <= 1)
|
|
34872
|
+
continue;
|
|
34873
|
+
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
34874
|
+
for (let i = 0;i < group.length - 1; i++) {
|
|
34875
|
+
const tag = group[i];
|
|
34876
|
+
if (tag.tagNumber > protectedCutoff)
|
|
34877
|
+
continue;
|
|
34878
|
+
const target = targets.get(tag.tagNumber);
|
|
34879
|
+
if (protectedTools.has(tag.tagNumber))
|
|
34880
|
+
continue;
|
|
34881
|
+
if (target?.canDrop?.() === false)
|
|
34882
|
+
continue;
|
|
34883
|
+
const { result, mode } = applyNewToolDrop(target, {
|
|
34884
|
+
inWindow: false
|
|
34885
|
+
});
|
|
34886
|
+
if (result === "incomplete")
|
|
34887
|
+
continue;
|
|
34888
|
+
updateTagDropMode(db, sessionId, tag.tagNumber, mode);
|
|
34889
|
+
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
34890
|
+
if (result === "removed" || result === "truncated") {
|
|
34891
|
+
deduplicatedTools++;
|
|
34892
|
+
droppedTokenReductions.push({
|
|
34893
|
+
tagNumber: tag.tagNumber,
|
|
34894
|
+
mode: mode === "full" ? "full" : "truncated"
|
|
34895
|
+
});
|
|
34896
|
+
}
|
|
34897
|
+
}
|
|
34898
|
+
}
|
|
34899
|
+
}).immediate();
|
|
34900
|
+
}
|
|
34901
|
+
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
|
|
34902
|
+
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale mmc_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
34903
|
+
}
|
|
34904
|
+
let compressedTextTags = 0;
|
|
34905
|
+
let mutatedTextTags = 0;
|
|
34906
|
+
if (routine && config.caveman?.enabled) {
|
|
34907
|
+
const cavemanTags = getActiveTagsBySession(db, sessionId);
|
|
34908
|
+
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, cavemanTags, {
|
|
34909
|
+
enabled: true,
|
|
34910
|
+
minChars: config.caveman.minChars,
|
|
34911
|
+
wordRules: config.caveman.wordRules,
|
|
34912
|
+
protectedCutoff
|
|
34913
|
+
});
|
|
34914
|
+
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
34915
|
+
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
34916
|
+
if (cavemanResult.textReductions) {
|
|
34917
|
+
for (const r of cavemanResult.textReductions) {
|
|
34918
|
+
droppedTokenReductions.push({
|
|
34919
|
+
tagNumber: r.tagNumber,
|
|
34920
|
+
mode: "partial",
|
|
34921
|
+
removedCharacters: r.removedCharacters
|
|
34922
|
+
});
|
|
34923
|
+
}
|
|
34924
|
+
}
|
|
34925
|
+
}
|
|
34926
|
+
return {
|
|
34927
|
+
droppedTools,
|
|
34928
|
+
deduplicatedTools,
|
|
34929
|
+
droppedInjections,
|
|
34930
|
+
droppedStaleReduceCalls,
|
|
34931
|
+
emergencyDroppedTools,
|
|
34932
|
+
compressedTextTags,
|
|
34933
|
+
mutatedTextTags,
|
|
34934
|
+
droppedTokenReductions
|
|
34935
|
+
};
|
|
34936
|
+
}
|
|
34937
|
+
function buildCtxReduceTagNumbers(tags) {
|
|
34938
|
+
const byComposite = new Map;
|
|
34939
|
+
for (const tag of tags) {
|
|
34940
|
+
if (tag.status !== "active" || tag.type !== "tool" || tag.toolName !== "mmc_reduce" || !tag.toolOwnerMessageId) {
|
|
34941
|
+
continue;
|
|
34942
|
+
}
|
|
34943
|
+
byComposite.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag.tagNumber);
|
|
34944
|
+
}
|
|
34945
|
+
return byComposite;
|
|
34946
|
+
}
|
|
34947
|
+
function buildMessageIdToMaxTagFromTargets(targets) {
|
|
34948
|
+
const byMessage = new Map;
|
|
34949
|
+
for (const [tagNumber, target] of targets) {
|
|
34950
|
+
const id = target.message?.info?.id;
|
|
34951
|
+
if (typeof id !== "string" || id.length === 0)
|
|
34952
|
+
continue;
|
|
34953
|
+
if (tagNumber > (byMessage.get(id) ?? 0))
|
|
34954
|
+
byMessage.set(id, tagNumber);
|
|
34955
|
+
}
|
|
34956
|
+
return byMessage;
|
|
34957
|
+
}
|
|
34958
|
+
|
|
34792
34959
|
// src/historian-tail-pi.ts
|
|
34793
34960
|
function readPiHistorianTail(db, sessionId, provider) {
|
|
34794
34961
|
const end = getLastCompartmentEndMessage(db, sessionId);
|
|
@@ -35367,7 +35534,11 @@ function materializeM0Pi(state, db, passSnapshot) {
|
|
|
35367
35534
|
modelKey: snapshotMarkers.modelKey,
|
|
35368
35535
|
projectIdentity: snapshotMarkers.projectIdentity
|
|
35369
35536
|
});
|
|
35370
|
-
|
|
35537
|
+
const visibleMemoryIds = [
|
|
35538
|
+
...new Set([...renderedMemoryIds, ...m1Render.renderedMemoryIds])
|
|
35539
|
+
];
|
|
35540
|
+
const visibleIdsJson = JSON.stringify(visibleMemoryIds);
|
|
35541
|
+
db.prepare("UPDATE session_meta SET memory_block_count = ?, memory_block_ids = ? WHERE session_id = ?").run(visibleMemoryIds.length, visibleIdsJson, state.sessionId);
|
|
35371
35542
|
setCachedBoundary(db, state.sessionId, snapshotMarkers.lastBaselineEndMessageId);
|
|
35372
35543
|
db.exec("COMMIT");
|
|
35373
35544
|
logSlowWriteTransaction("pi_materialize_cache", transactionStartedAt);
|
|
@@ -35505,7 +35676,8 @@ ${body}
|
|
|
35505
35676
|
if (sections.length === 0) {
|
|
35506
35677
|
return {
|
|
35507
35678
|
text: PI_M1_PLACEHOLDER,
|
|
35508
|
-
memoryUpdateCount: memoryUpdates.count
|
|
35679
|
+
memoryUpdateCount: memoryUpdates.count,
|
|
35680
|
+
renderedMemoryIds: []
|
|
35509
35681
|
};
|
|
35510
35682
|
}
|
|
35511
35683
|
return {
|
|
@@ -35516,7 +35688,8 @@ ${sections.join(`
|
|
|
35516
35688
|
${sections.join(`
|
|
35517
35689
|
`)}
|
|
35518
35690
|
</session-history-since>`,
|
|
35519
|
-
memoryUpdateCount: memoryUpdates.count
|
|
35691
|
+
memoryUpdateCount: memoryUpdates.count,
|
|
35692
|
+
renderedMemoryIds: newMemoriesBlock ? deltaMemories.map((memory) => memory.id) : []
|
|
35520
35693
|
};
|
|
35521
35694
|
}
|
|
35522
35695
|
function toCachedBuffer(value) {
|
|
@@ -35684,9 +35857,13 @@ function softRefreshCachedM1Pi(args) {
|
|
|
35684
35857
|
const renderedM0Ids = readCachedM0MemoryIds(row.cached_m0_upgrade_state, parseMemoryBlockIds(row.memory_block_ids), markers.maxMemoryId);
|
|
35685
35858
|
const rendered = renderM1PiWithMetadata(args.state, args.db, markers, renderedM0Ids, args.compartmentsForNormalization);
|
|
35686
35859
|
const m1Bytes = Buffer.from(rendered.text, "utf8");
|
|
35860
|
+
const visibleMemoryIds = [
|
|
35861
|
+
...new Set([...renderedM0Ids, ...rendered.renderedMemoryIds])
|
|
35862
|
+
];
|
|
35863
|
+
const visibleIdsJson = JSON.stringify(visibleMemoryIds);
|
|
35687
35864
|
const latestCompartment = args.compartmentsForNormalization.at(-1);
|
|
35688
35865
|
const advancedBoundary = latestCompartment?.endMessageId && latestCompartment.endMessageId.length > 0 ? latestCompartment.endMessageId : markers.lastBaselineEndMessageId;
|
|
35689
|
-
args.db.prepare("UPDATE session_meta SET cached_m1_bytes = ?, cached_m0_last_baseline_end_message_id = ?, cached_m0_upgrade_state = ? WHERE session_id = ?").run(m1Bytes, advancedBoundary, withCachedM0MemoryIds(row.cached_m0_upgrade_state, renderedM0Ids), args.state.sessionId);
|
|
35866
|
+
args.db.prepare("UPDATE session_meta SET cached_m1_bytes = ?, cached_m0_last_baseline_end_message_id = ?, memory_block_count = ?, memory_block_ids = ?, cached_m0_upgrade_state = ? WHERE session_id = ?").run(m1Bytes, advancedBoundary, visibleMemoryIds.length, visibleIdsJson, withCachedM0MemoryIds(row.cached_m0_upgrade_state, renderedM0Ids), args.state.sessionId);
|
|
35690
35867
|
args.db.exec("COMMIT");
|
|
35691
35868
|
logSlowWriteTransaction("pi_soft_refresh_cache", transactionStartedAt);
|
|
35692
35869
|
return {
|
|
@@ -37955,6 +38132,7 @@ async function runPhase(deps, ctx, phase, stageAManifest) {
|
|
|
37955
38132
|
messages: []
|
|
37956
38133
|
};
|
|
37957
38134
|
let refusalNotes = [];
|
|
38135
|
+
let consumedSteps = 0;
|
|
37958
38136
|
for (let round = 1;round <= maxRounds; round += 1) {
|
|
37959
38137
|
const decision = ctx.shouldContinue();
|
|
37960
38138
|
if (decision === "stop")
|
|
@@ -37974,10 +38152,12 @@ async function runPhase(deps, ctx, phase, stageAManifest) {
|
|
|
37974
38152
|
sessionLog(deps.parentSessionId ?? "pi-maintenance", `maintenance phase ${phase} round ${round}: producer admission refused`);
|
|
37975
38153
|
break;
|
|
37976
38154
|
}
|
|
38155
|
+
const stepCap = phase === "a" ? MEMORY_MAINTAINER_A_STEP_CAP : resolveMaintenanceStepCap(deps.options.runConfig.budgets.toolSteps, consumedSteps);
|
|
37977
38156
|
const result = await session({
|
|
37978
38157
|
agent: phase === "a" ? MAINTAINER_AGENT_A : MAINTAINER_AGENT_B,
|
|
37979
38158
|
systemPrompt: maintainerSystemPrompt(deps, phase),
|
|
37980
|
-
userMessage: prompt
|
|
38159
|
+
userMessage: prompt,
|
|
38160
|
+
stepCap
|
|
37981
38161
|
});
|
|
37982
38162
|
ctx.recordUsage(result.usage);
|
|
37983
38163
|
acc.usage.inputTokens += result.usage.inputTokens;
|
|
@@ -37986,6 +38166,7 @@ async function runPhase(deps, ctx, phase, stageAManifest) {
|
|
|
37986
38166
|
for (let step = 0;step < result.toolSteps; step += 1) {
|
|
37987
38167
|
if (ctx.shouldContinue() === "continue") {
|
|
37988
38168
|
ctx.recordToolStep();
|
|
38169
|
+
consumedSteps += 1;
|
|
37989
38170
|
} else {
|
|
37990
38171
|
const refusal = ctx.refuseToolStep();
|
|
37991
38172
|
refusalNotes.push(refusal.message);
|
|
@@ -38058,6 +38239,7 @@ async function defaultSessionFace(deps, args) {
|
|
|
38058
38239
|
agent: args.agent,
|
|
38059
38240
|
systemPrompt: args.systemPrompt,
|
|
38060
38241
|
userMessage: args.userMessage,
|
|
38242
|
+
stepCap: args.stepCap,
|
|
38061
38243
|
model: deps.options.model,
|
|
38062
38244
|
fallbackModels: deps.options.fallbackModels,
|
|
38063
38245
|
timeoutMs: deps.options.timeoutMs ?? DEFAULT_MAINTAINER_TIMEOUT_MS,
|
|
@@ -40460,10 +40642,16 @@ function handlePiProviderFailure(args) {
|
|
|
40460
40642
|
const provider = typeof message.provider === "string" ? message.provider : undefined;
|
|
40461
40643
|
const model = typeof message.model === "string" ? message.model : undefined;
|
|
40462
40644
|
const binding = detectThinkingBindingMismatch(message.errorMessage);
|
|
40645
|
+
if (detectLatestTurnThinkingMismatch(message.errorMessage) && !args.compactionOff && isAnthropicFamilyRoute(provider, model)) {
|
|
40646
|
+
armLatestThinkingRecovery(args.db, args.sessionId);
|
|
40647
|
+
clearPiLkgSessionState(args.sessionId);
|
|
40648
|
+
dropSlot(args.sessionId, "latest-thinking-recovery-arm");
|
|
40649
|
+
return { kind: "thinking_binding", armed: true };
|
|
40650
|
+
}
|
|
40463
40651
|
if (binding.isBindingMismatch) {
|
|
40464
40652
|
const enabled = args.thinkingBindingRecoveryEnabled !== false && !args.compactionOff && isPrefixBoundThinkingModel(provider, model);
|
|
40465
40653
|
if (enabled) {
|
|
40466
|
-
|
|
40654
|
+
armBindingRecoverySafely(args.db, args.sessionId);
|
|
40467
40655
|
clearPiLkgSessionState(args.sessionId);
|
|
40468
40656
|
dropSlot(args.sessionId, "thinking-binding-recovery-arm");
|
|
40469
40657
|
reportBindingRecovery(args.sessionId, args.report, `thinking-binding recovery armed from message_end (provider paths: failing=${binding.failingBlockPath ?? "?"} firstChanged=${binding.firstChangedPath ?? "?"})`);
|
|
@@ -40513,12 +40701,16 @@ function stripThinkingParts(message) {
|
|
|
40513
40701
|
return before - strippedContent.length;
|
|
40514
40702
|
}
|
|
40515
40703
|
function applyPiThinkingBindingRecovery(args) {
|
|
40704
|
+
const protectedMessages = latestAssistantTurnMessages(args.messages);
|
|
40516
40705
|
const frozenEntryIds = frozenBindingEntryIds(args.db, args.sessionId);
|
|
40517
|
-
const
|
|
40706
|
+
const flagTargetCandidate = isPrefixBoundThinkingModel(args.provider, args.model) ? getThinkingBindingRecoveryTarget(args.db, args.sessionId) : null;
|
|
40707
|
+
const flagTarget = flagTargetCandidate?.startsWith(LATEST_THINKING_RESTORE) ? null : flagTargetCandidate;
|
|
40518
40708
|
let applied = null;
|
|
40519
40709
|
if (flagTarget) {
|
|
40520
40710
|
const entryIds = new Set;
|
|
40521
40711
|
for (let index = 0;index < args.messages.length; index += 1) {
|
|
40712
|
+
if (protectedMessages.has(args.messages[index]))
|
|
40713
|
+
continue;
|
|
40522
40714
|
const entryId = args.entryIds[index];
|
|
40523
40715
|
if (entryId && hasThinkingPart(args.messages[index]))
|
|
40524
40716
|
entryIds.add(entryId);
|
|
@@ -40534,7 +40726,15 @@ function applyPiThinkingBindingRecovery(args) {
|
|
|
40534
40726
|
reportBindingRecovery(args.sessionId, args.report, `thinking-binding recovery consumed on context pass target=${flagTarget} entries=${applied.entryIds.length} [${applied.entryIds.join(",")}]`);
|
|
40535
40727
|
}
|
|
40536
40728
|
}
|
|
40729
|
+
const restoringActiveTurn = latestThinkingRecoveryCoversActiveTurn({
|
|
40730
|
+
db: args.db,
|
|
40731
|
+
sessionId: args.sessionId,
|
|
40732
|
+
messages: args.messages,
|
|
40733
|
+
id: (message, index) => resolvePiStableId(message, index, args.entryIds)
|
|
40734
|
+
});
|
|
40537
40735
|
for (let index = 0;index < args.messages.length; index += 1) {
|
|
40736
|
+
if (restoringActiveTurn && protectedMessages.has(args.messages[index]))
|
|
40737
|
+
continue;
|
|
40538
40738
|
const entryId = args.entryIds[index];
|
|
40539
40739
|
if (entryId && frozenEntryIds.has(entryId))
|
|
40540
40740
|
stripThinkingParts(args.messages[index]);
|
|
@@ -40546,9 +40746,12 @@ function applyPiProactiveThinkingStrip(args) {
|
|
|
40546
40746
|
return null;
|
|
40547
40747
|
if (!isPrefixBoundThinkingModel(args.provider, args.model))
|
|
40548
40748
|
return null;
|
|
40749
|
+
const protectedMessages = latestAssistantTurnMessages(args.messages);
|
|
40549
40750
|
const entryIds = [];
|
|
40550
40751
|
const indices = [];
|
|
40551
40752
|
for (let index = 0;index < args.messages.length; index += 1) {
|
|
40753
|
+
if (protectedMessages.has(args.messages[index]))
|
|
40754
|
+
continue;
|
|
40552
40755
|
const entryId = args.entryIds[index];
|
|
40553
40756
|
if (!entryId || !hasThinkingPart(args.messages[index]))
|
|
40554
40757
|
continue;
|
|
@@ -44274,8 +44477,10 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
44274
44477
|
messages: outputMessages,
|
|
44275
44478
|
tags,
|
|
44276
44479
|
protectedTagNumbers,
|
|
44480
|
+
protectedTools: options.protectedTools,
|
|
44277
44481
|
pendingDropTagNumbers,
|
|
44278
44482
|
stableId,
|
|
44483
|
+
protectedToolTags: protectedToolTagNumbers(tags, options.protectedTools),
|
|
44279
44484
|
syntheticLeadingCount: result.syntheticLeadingCount,
|
|
44280
44485
|
cacheBusting: result.bustedThisPass,
|
|
44281
44486
|
previous: previousBaseline,
|
|
@@ -45187,6 +45392,16 @@ async function runPipeline(args) {
|
|
|
45187
45392
|
args.assertCurrentPass?.();
|
|
45188
45393
|
if (args.compactionOff)
|
|
45189
45394
|
return runCompactionOffPipeline(args);
|
|
45395
|
+
const thinkingRecovery = prepareLatestThinkingRecovery({
|
|
45396
|
+
db: args.db,
|
|
45397
|
+
sessionId: args.sessionId,
|
|
45398
|
+
messages: args.messages,
|
|
45399
|
+
id: (message, index) => resolvePiStableId(message, index, args.entryIds, args.entryIdByRef ?? undefined),
|
|
45400
|
+
parts: (message) => Array.isArray(message?.content) ? message.content : []
|
|
45401
|
+
});
|
|
45402
|
+
if (thinkingRecovery.ended)
|
|
45403
|
+
signalPiPendingMaterialization(args.sessionId);
|
|
45404
|
+
let restoreOriginals;
|
|
45190
45405
|
const activeThinkingTurn = hasActiveAnthropicThinkingTurn(args.messages, args.resolvedProviderID, args.resolvedModelID);
|
|
45191
45406
|
const protectedSignedPrefix = activeThinkingTurn && args.reasoningClearing?.prefixBound === true;
|
|
45192
45407
|
let foldingSystemState = null;
|
|
@@ -45445,6 +45660,10 @@ async function runPipeline(args) {
|
|
|
45445
45660
|
afterFallbackAdoptionForTests?.(args.stableIdSchemeCutover === true);
|
|
45446
45661
|
const textIdentityPlan = buildPiTextIdentityPlan(args.db, args.sessionId, args.tagger, transcript, args.reusableMessageIds);
|
|
45447
45662
|
const tTag = performance.now();
|
|
45663
|
+
const mutationView = transcript.messages.map((message) => ({
|
|
45664
|
+
...message,
|
|
45665
|
+
parts: message.parts
|
|
45666
|
+
}));
|
|
45448
45667
|
let tagTextTokenCache = piTagTextTokenCacheBySession.get(args.sessionId);
|
|
45449
45668
|
if (!tagTextTokenCache) {
|
|
45450
45669
|
tagTextTokenCache = new Map;
|
|
@@ -45457,7 +45676,7 @@ async function runPipeline(args) {
|
|
|
45457
45676
|
}
|
|
45458
45677
|
const { targets } = runPersistedReplayStage("tagging-persistence-failure", () => args.tagger.cleanup(args.sessionId), () => {
|
|
45459
45678
|
args.assertCurrentPass?.();
|
|
45460
|
-
return tagTranscript(args.sessionId, transcript, args.tagger, args.db, {
|
|
45679
|
+
return tagTranscript(args.sessionId, { ...transcript, messages: mutationView }, args.tagger, args.db, {
|
|
45461
45680
|
skipPrefixInjection: !ctxReduceCallable,
|
|
45462
45681
|
entryFingerprintByMessageId,
|
|
45463
45682
|
reuseMessageIds: textIdentityPlan.reusableMessageIds,
|
|
@@ -45475,6 +45694,35 @@ async function runPipeline(args) {
|
|
|
45475
45694
|
});
|
|
45476
45695
|
});
|
|
45477
45696
|
logTransformTiming(args.sessionId, "tagMessages", tTag);
|
|
45697
|
+
const reasoningTagsForProtection = buildMessageIdToMaxTag(targets);
|
|
45698
|
+
const frozenThinkingForProtection = activeThinkingTurn ? frozenBindingEntryIds(args.db, args.sessionId) : new Set;
|
|
45699
|
+
const protectedThinkingProxies = new Set;
|
|
45700
|
+
if (activeThinkingTurn) {
|
|
45701
|
+
for (let i = latestAssistantTurnStart(workingMessages);i < mutationView.length; i++) {
|
|
45702
|
+
const id = stableIdResolver(workingMessages[i], i);
|
|
45703
|
+
if (!thinkingRecovery.restore && id && frozenThinkingForProtection.has(id))
|
|
45704
|
+
continue;
|
|
45705
|
+
for (let p = 0;p < mutationView[i].parts.length; p++) {
|
|
45706
|
+
const part = mutationView[i].parts[p];
|
|
45707
|
+
if (part.kind !== "thinking")
|
|
45708
|
+
continue;
|
|
45709
|
+
const local = workingMessages[i].content?.[p];
|
|
45710
|
+
if (!thinkingRecovery.restore && !local?.redacted && id && (reasoningTagsForProtection.get(id) ?? Infinity) <= (args.sessionMeta.clearedReasoningThroughTag ?? 0))
|
|
45711
|
+
continue;
|
|
45712
|
+
protectedThinkingProxies.add(part);
|
|
45713
|
+
}
|
|
45714
|
+
}
|
|
45715
|
+
}
|
|
45716
|
+
const newTargets = protectNewTagMutations(mutationView.map((message) => ({
|
|
45717
|
+
info: message.info,
|
|
45718
|
+
parts: message.parts
|
|
45719
|
+
})), targets, protectedThinkingProxies, args.reasoningClearing?.prefixBound === true);
|
|
45720
|
+
if (thinkingRecovery.restore) {
|
|
45721
|
+
transcript.commit();
|
|
45722
|
+
restoreOriginals = captureOriginalTurn(args.messages, (message) => message.content, (message, content) => {
|
|
45723
|
+
message.content = content;
|
|
45724
|
+
});
|
|
45725
|
+
}
|
|
45478
45726
|
if (foldBustsServedPrefixThisPass) {
|
|
45479
45727
|
try {
|
|
45480
45728
|
let converted = 0;
|
|
@@ -45517,7 +45765,7 @@ async function runPipeline(args) {
|
|
|
45517
45765
|
pendingDecisionLogObserverForTests?.(pendingDecisionLog);
|
|
45518
45766
|
try {
|
|
45519
45767
|
const tApplyPending = performance.now();
|
|
45520
|
-
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db,
|
|
45768
|
+
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, new Set([
|
|
45521
45769
|
...args.contextUsage.percentage >= 95 ? [] : protectedTagNumbersForPass,
|
|
45522
45770
|
...protectedToolTagNumbers(getActiveTagsBySession(args.db, args.sessionId), args.protectedTools)
|
|
45523
45771
|
]), pendingOperationTags, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
|
|
@@ -45530,7 +45778,8 @@ async function runPipeline(args) {
|
|
|
45530
45778
|
pendingOpsAppliedThisPass = true;
|
|
45531
45779
|
if (hasPendingMaterializeSignal) {
|
|
45532
45780
|
if (args.heuristics === undefined) {
|
|
45533
|
-
|
|
45781
|
+
if (!pendingOps.some((op) => newTargets.get(op.tagId)?.thinkingDropProtected))
|
|
45782
|
+
consumePendingMaterialization(args.sessionId);
|
|
45534
45783
|
}
|
|
45535
45784
|
}
|
|
45536
45785
|
} catch (err) {
|
|
@@ -45618,7 +45867,7 @@ async function runPipeline(args) {
|
|
|
45618
45867
|
clearEmergencyDropSample(args.db, args.sessionId);
|
|
45619
45868
|
}
|
|
45620
45869
|
routineCleanupApplied = (emergencyDropEligible ? args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0 : args.sessionMeta.isSubagent || !routinePressureAlreadyApplied) || hasPendingMaterializeSignal || deferredMaterialize || independentMutationBeforeHeuristics;
|
|
45621
|
-
heuristicsResult = applyPiHeuristicCleanup(args.sessionId, args.db,
|
|
45870
|
+
heuristicsResult = applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
|
|
45622
45871
|
protectedTools: args.protectedTools,
|
|
45623
45872
|
protectedToolTags,
|
|
45624
45873
|
protectedTags: args.protectedTags,
|
|
@@ -45635,7 +45884,7 @@ async function runPipeline(args) {
|
|
|
45635
45884
|
caveman: args.isSubagent ? undefined : args.heuristics.caveman
|
|
45636
45885
|
}, activeTags, stableIdResolver);
|
|
45637
45886
|
if (!routineCleanupApplied && heuristicsResult.emergencyDroppedTools > 0) {
|
|
45638
|
-
const ridingCleanup = applyPiHeuristicCleanup(args.sessionId, args.db,
|
|
45887
|
+
const ridingCleanup = applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
|
|
45639
45888
|
protectedTools: args.protectedTools,
|
|
45640
45889
|
protectedToolTags,
|
|
45641
45890
|
protectedTags: args.protectedTags,
|
|
@@ -45675,7 +45924,8 @@ async function runPipeline(args) {
|
|
|
45675
45924
|
heuristicsExecuted = true;
|
|
45676
45925
|
executedWorkThisPass = true;
|
|
45677
45926
|
if (hasPendingMaterializeSignal) {
|
|
45678
|
-
|
|
45927
|
+
if (!pendingOps.some((op) => newTargets.get(op.tagId)?.thinkingDropProtected))
|
|
45928
|
+
consumePendingMaterialization(args.sessionId);
|
|
45679
45929
|
}
|
|
45680
45930
|
if (currentTurnId !== null) {
|
|
45681
45931
|
lastHeuristicsTurnIdBySession.set(args.sessionId, currentTurnId);
|
|
@@ -45776,7 +46026,7 @@ async function runPipeline(args) {
|
|
|
45776
46026
|
const syntheticPendingOps = buildSyntheticToolReclaimOps({
|
|
45777
46027
|
db: args.db,
|
|
45778
46028
|
sessionId: args.sessionId,
|
|
45779
|
-
targets,
|
|
46029
|
+
targets: newTargets,
|
|
45780
46030
|
watermark: reclaimMeta.toolReclaimWatermark ?? 0,
|
|
45781
46031
|
pendingOps
|
|
45782
46032
|
});
|
|
@@ -45787,7 +46037,7 @@ async function runPipeline(args) {
|
|
|
45787
46037
|
const supersessionOps = buildSupersessionReclaimOps({
|
|
45788
46038
|
db: args.db,
|
|
45789
46039
|
sessionId: args.sessionId,
|
|
45790
|
-
targets,
|
|
46040
|
+
targets: newTargets,
|
|
45791
46041
|
pendingOps,
|
|
45792
46042
|
recentMessageIds,
|
|
45793
46043
|
protectedToolTags
|
|
@@ -45801,7 +46051,7 @@ async function runPipeline(args) {
|
|
|
45801
46051
|
const editReclaim = buildEditSupersessionReclaim({
|
|
45802
46052
|
db: args.db,
|
|
45803
46053
|
sessionId: args.sessionId,
|
|
45804
|
-
targets,
|
|
46054
|
+
targets: newTargets,
|
|
45805
46055
|
pendingOps,
|
|
45806
46056
|
recentMessageIds,
|
|
45807
46057
|
protectedToolTags
|
|
@@ -45816,7 +46066,7 @@ async function runPipeline(args) {
|
|
|
45816
46066
|
}
|
|
45817
46067
|
autoReclaimTargetCount = syntheticPendingOps.length;
|
|
45818
46068
|
if (syntheticPendingOps.length > 0) {
|
|
45819
|
-
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db,
|
|
46069
|
+
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, protectedTagNumbersForPass, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction));
|
|
45820
46070
|
if (autoReclaimDidMutate) {
|
|
45821
46071
|
droppedCount += syntheticPendingOps.length;
|
|
45822
46072
|
autoReclaimDidMutateThisPass = true;
|
|
@@ -46078,6 +46328,7 @@ async function runPipeline(args) {
|
|
|
46078
46328
|
} catch (err) {
|
|
46079
46329
|
sessionLog(args.sessionId, `token accounting failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
46080
46330
|
}
|
|
46331
|
+
restoreOriginals?.(workingMessages);
|
|
46081
46332
|
const materialized = injectionResult?.m0Materialized === true;
|
|
46082
46333
|
if (args.reasoningClearing?.prefixBound && firstEditSourceOrder && firstEditParts.size > 0 && !prefixEditBesidesReasoningTrim) {
|
|
46083
46334
|
const frozenThinking = frozenBindingEntryIds(args.db, args.sessionId);
|
|
@@ -46704,17 +46955,8 @@ ${result.message}`,
|
|
|
46704
46955
|
var rebasesInFlight = new WeakMap;
|
|
46705
46956
|
var repairCheckedSessions = new WeakMap;
|
|
46706
46957
|
|
|
46707
|
-
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
46708
|
-
import { mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
46709
|
-
function cleanupHistorianStateFile(path) {
|
|
46710
|
-
if (!path)
|
|
46711
|
-
return;
|
|
46712
|
-
try {
|
|
46713
|
-
unlinkSync2(path);
|
|
46714
|
-
} catch {}
|
|
46715
|
-
}
|
|
46716
46958
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
46717
|
-
import { mkdirSync as
|
|
46959
|
+
import { mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
46718
46960
|
import { join as join11 } from "node:path";
|
|
46719
46961
|
|
|
46720
46962
|
// ../plugin/src/agents/historian.ts
|
|
@@ -47467,7 +47709,7 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
47467
47709
|
if (!dumpPath)
|
|
47468
47710
|
return;
|
|
47469
47711
|
try {
|
|
47470
|
-
|
|
47712
|
+
unlinkSync2(dumpPath);
|
|
47471
47713
|
} catch (error) {
|
|
47472
47714
|
sessionLog(sessionId, "compartment agent: failed to remove historian response dump", {
|
|
47473
47715
|
dumpPath,
|
|
@@ -47478,12 +47720,12 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
47478
47720
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
47479
47721
|
try {
|
|
47480
47722
|
const dumpDir = historianResponseDumpDir(directory);
|
|
47481
|
-
|
|
47723
|
+
mkdirSync2(dumpDir, { recursive: true });
|
|
47482
47724
|
ensureMmcArtifactGitignore(directory);
|
|
47483
47725
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
47484
47726
|
const safeLabel = sanitizeDumpName(label);
|
|
47485
47727
|
const dumpPath = join11(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
47486
|
-
|
|
47728
|
+
writeFileSync2(dumpPath, text, "utf8");
|
|
47487
47729
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
47488
47730
|
label,
|
|
47489
47731
|
dumpPath
|
|
@@ -47634,7 +47876,6 @@ Could not acquire the compartment-state lease for this session.`;
|
|
|
47634
47876
|
logPostPublishFailure(step, error);
|
|
47635
47877
|
}
|
|
47636
47878
|
};
|
|
47637
|
-
let currentStateFilePath;
|
|
47638
47879
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
47639
47880
|
try {
|
|
47640
47881
|
const rawMessageCount = getRawSessionMessageCount2(sessionId);
|
|
@@ -47971,7 +48212,6 @@ Another process acquired the compartment-state lease before recomp could publish
|
|
|
47971
48212
|
${renderUserFacingFailure("recomp_unavailable")}`;
|
|
47972
48213
|
} finally {
|
|
47973
48214
|
updateSessionMeta(db, sessionId, { compartmentInProgress: false });
|
|
47974
|
-
cleanupHistorianStateFile(currentStateFilePath);
|
|
47975
48215
|
}
|
|
47976
48216
|
}
|
|
47977
48217
|
|
|
@@ -49876,7 +50116,7 @@ function buildStatusViewFor(check, options) {
|
|
|
49876
50116
|
// package.json
|
|
49877
50117
|
var package_default = {
|
|
49878
50118
|
name: "@retaw106/mmc-pi",
|
|
49879
|
-
version: "2.1
|
|
50119
|
+
version: "2.2.1",
|
|
49880
50120
|
type: "module",
|
|
49881
50121
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
49882
50122
|
main: "dist/index.js",
|
|
@@ -49907,7 +50147,7 @@ var package_default = {
|
|
|
49907
50147
|
"dist",
|
|
49908
50148
|
"README.md"
|
|
49909
50149
|
],
|
|
49910
|
-
"//":
|
|
50150
|
+
"//": 'The build intentionally bundles typebox (no --external typebox): OMP\'s extension loader rewrites every bare `typebox` import to its own omptype-based shim, whose schemas are callable objects rather than JSON Schema; they fail structuredClone during tool registration, so an external typebox import stops Magic Context loading on OMP. The package nonetheless declares typebox as an optional peer "*": Pi treats it as a host-provided extension package and warns on startup when it appears in dependencies (upstream issue #571). The bundled copy is the only one loaded at runtime. src/typebox-bundling.test.ts guards both facts.',
|
|
49911
50151
|
scripts: {
|
|
49912
50152
|
build: "bun ../../scripts/check-bun.mjs && bun ../../scripts/clean-dist-chunks.mjs dist index.js historian-calibration-extension.js config-init.js cli.js && rm -rf dist/web && bun build src/index.ts src/historian-calibration-extension.ts --outdir dist --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external node:sqlite && bun run build:web && bun run build:config-init && bun run build:cli",
|
|
49913
50153
|
"build:web": "bun build src/web/main.ts --outfile dist/web/main.js --target node --format esm --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external node:sqlite && mkdir -p dist/web/ui && cp ../plugin/src/web/ui/* dist/web/ui/",
|
|
@@ -49927,7 +50167,6 @@ var package_default = {
|
|
|
49927
50167
|
dependencies: {
|
|
49928
50168
|
"ai-tokenizer": "^1.0.6",
|
|
49929
50169
|
"comment-json": "^5.0.0",
|
|
49930
|
-
typebox: "^1.3.1",
|
|
49931
50170
|
zod: "^4.1.8"
|
|
49932
50171
|
},
|
|
49933
50172
|
devDependencies: {
|
|
@@ -49941,11 +50180,13 @@ var package_default = {
|
|
|
49941
50180
|
"pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
|
|
49942
50181
|
"pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
|
|
49943
50182
|
"pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
|
|
50183
|
+
typebox: "^1.3.1",
|
|
49944
50184
|
typescript: "^5.8.0"
|
|
49945
50185
|
},
|
|
49946
50186
|
peerDependencies: {
|
|
49947
50187
|
"@earendil-works/pi-coding-agent": ">=0.80.2",
|
|
49948
|
-
"@earendil-works/pi-tui": ">=0.80.2"
|
|
50188
|
+
"@earendil-works/pi-tui": ">=0.80.2",
|
|
50189
|
+
typebox: "*"
|
|
49949
50190
|
},
|
|
49950
50191
|
peerDependenciesMeta: {
|
|
49951
50192
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -49953,6 +50194,9 @@ var package_default = {
|
|
|
49953
50194
|
},
|
|
49954
50195
|
"@earendil-works/pi-tui": {
|
|
49955
50196
|
optional: true
|
|
50197
|
+
},
|
|
50198
|
+
typebox: {
|
|
50199
|
+
optional: true
|
|
49956
50200
|
}
|
|
49957
50201
|
},
|
|
49958
50202
|
exports: {
|
|
@@ -49969,6 +50213,7 @@ var package_default = {
|
|
|
49969
50213
|
|
|
49970
50214
|
// src/dialogs/status-dialog.ts
|
|
49971
50215
|
var REFRESH_INTERVAL_MS = 1000;
|
|
50216
|
+
var DETAIL_REFRESH_INTERVAL_MS = 1e4;
|
|
49972
50217
|
var BORDER_ROWS = 2;
|
|
49973
50218
|
var BORDER_COLUMNS = 2;
|
|
49974
50219
|
var PADDING_COLUMNS = 2;
|
|
@@ -49998,6 +50243,7 @@ function stopStatusDialogRefresh() {
|
|
|
49998
50243
|
class StatusDialogComponent {
|
|
49999
50244
|
props;
|
|
50000
50245
|
detail;
|
|
50246
|
+
detailRefresh;
|
|
50001
50247
|
refreshTimer = null;
|
|
50002
50248
|
closed = false;
|
|
50003
50249
|
scrollOffset = 0;
|
|
@@ -50005,13 +50251,14 @@ class StatusDialogComponent {
|
|
|
50005
50251
|
maxScrollOffset = 0;
|
|
50006
50252
|
constructor(props) {
|
|
50007
50253
|
this.props = props;
|
|
50008
|
-
this.
|
|
50254
|
+
this.detailRefresh = new PiStatusDetailRefresh(props.pi, props.ctx, props.deps, props.sessionId);
|
|
50255
|
+
this.detail = this.detailRefresh.refresh();
|
|
50009
50256
|
openStatusDialogs.add(this);
|
|
50010
50257
|
this.refreshTimer = setInterval(() => {
|
|
50011
50258
|
if (this.closed)
|
|
50012
50259
|
return;
|
|
50013
50260
|
try {
|
|
50014
|
-
this.detail =
|
|
50261
|
+
this.detail = this.detailRefresh.refresh();
|
|
50015
50262
|
this.props.tui.requestRender();
|
|
50016
50263
|
} catch {}
|
|
50017
50264
|
}, REFRESH_INTERVAL_MS);
|
|
@@ -50248,7 +50495,152 @@ function deriveDefaultProtectedTokensFloor(usableSoft) {
|
|
|
50248
50495
|
const val = Math.round(0.05 * soft);
|
|
50249
50496
|
return Math.max(low, Math.min(64000, val));
|
|
50250
50497
|
}
|
|
50498
|
+
function readStatusHostBytes(pi, ctx) {
|
|
50499
|
+
return {
|
|
50500
|
+
modelKey: ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined,
|
|
50501
|
+
modelBytes: safeStringify(ctx.model),
|
|
50502
|
+
system: safeRead(() => readHostSystemPrompt(ctx), undefined),
|
|
50503
|
+
tools: safeRead(() => (pi.getAllTools?.() ?? []).map((tool) => `${tool.name ?? ""}
|
|
50504
|
+
${tool.description ?? ""}
|
|
50505
|
+
${safeStringify(tool.parameters)}`), [])
|
|
50506
|
+
};
|
|
50507
|
+
}
|
|
50508
|
+
|
|
50509
|
+
class PiStatusTokenCache {
|
|
50510
|
+
estimate;
|
|
50511
|
+
systemKey;
|
|
50512
|
+
systemTokens = 0;
|
|
50513
|
+
toolsKey;
|
|
50514
|
+
toolTokens = 0;
|
|
50515
|
+
constructor(estimate = estimateTokens) {
|
|
50516
|
+
this.estimate = estimate;
|
|
50517
|
+
}
|
|
50518
|
+
estimates(host, fallbackSystemTokens) {
|
|
50519
|
+
if (host.system !== undefined) {
|
|
50520
|
+
const key = JSON.stringify([host.modelKey, host.system]);
|
|
50521
|
+
if (this.systemKey !== key) {
|
|
50522
|
+
this.systemTokens = this.estimate(host.system);
|
|
50523
|
+
this.systemKey = key;
|
|
50524
|
+
}
|
|
50525
|
+
}
|
|
50526
|
+
const key = JSON.stringify([host.modelKey, host.tools]);
|
|
50527
|
+
if (this.toolsKey !== key) {
|
|
50528
|
+
this.toolTokens = host.tools.reduce((sum, bytes) => sum + this.estimate(bytes), 0);
|
|
50529
|
+
this.toolsKey = key;
|
|
50530
|
+
}
|
|
50531
|
+
return {
|
|
50532
|
+
systemPromptTokens: host.system === undefined ? fallbackSystemTokens : this.systemTokens,
|
|
50533
|
+
toolDefinitionTokens: this.toolTokens
|
|
50534
|
+
};
|
|
50535
|
+
}
|
|
50536
|
+
}
|
|
50537
|
+
|
|
50538
|
+
class PiStatusDetailRefresh {
|
|
50539
|
+
pi;
|
|
50540
|
+
ctx;
|
|
50541
|
+
deps;
|
|
50542
|
+
initialSessionId;
|
|
50543
|
+
detail;
|
|
50544
|
+
state;
|
|
50545
|
+
lastBuildAt = 0;
|
|
50546
|
+
detailKey = "";
|
|
50547
|
+
storeRevision;
|
|
50548
|
+
revisionDb;
|
|
50549
|
+
revisionStatement;
|
|
50550
|
+
constructor(pi, ctx, deps, initialSessionId, tokens = new PiStatusTokenCache) {
|
|
50551
|
+
this.pi = pi;
|
|
50552
|
+
this.ctx = ctx;
|
|
50553
|
+
this.deps = deps;
|
|
50554
|
+
this.initialSessionId = initialSessionId;
|
|
50555
|
+
this.state = { tokens };
|
|
50556
|
+
}
|
|
50557
|
+
readStoreRevision() {
|
|
50558
|
+
if (!isKnownAutocommit(this.deps.db))
|
|
50559
|
+
return;
|
|
50560
|
+
try {
|
|
50561
|
+
if (this.revisionDb !== this.deps.db) {
|
|
50562
|
+
this.revisionStatement = this.deps.db.prepare("SELECT total_changes() AS changes, data_version AS version FROM pragma_data_version");
|
|
50563
|
+
this.revisionDb = this.deps.db;
|
|
50564
|
+
}
|
|
50565
|
+
const row = this.revisionStatement?.get();
|
|
50566
|
+
return row ? `${row.changes}/${row.version}` : undefined;
|
|
50567
|
+
} catch {
|
|
50568
|
+
return;
|
|
50569
|
+
}
|
|
50570
|
+
}
|
|
50571
|
+
refresh(now = Date.now()) {
|
|
50572
|
+
const sessionId = resolveSessionId(this.ctx) ?? this.initialSessionId;
|
|
50573
|
+
const host = readStatusHostBytes(this.pi, this.ctx);
|
|
50574
|
+
const usage = this.ctx.getContextUsage?.();
|
|
50575
|
+
const { db: _db, ...config } = this.deps;
|
|
50576
|
+
const key = JSON.stringify([sessionId, host, usage?.contextWindow, config]);
|
|
50577
|
+
const databaseChanged = this.revisionDb !== this.deps.db;
|
|
50578
|
+
const revision = this.readStoreRevision();
|
|
50579
|
+
if (!this.detail || key !== this.detailKey || revision === undefined || revision !== this.storeRevision || databaseChanged || now - this.lastBuildAt >= DETAIL_REFRESH_INTERVAL_MS) {
|
|
50580
|
+
this.detail = buildStatusDetail(this.pi, this.ctx, this.deps, sessionId, this.state, host);
|
|
50581
|
+
this.detailKey = key;
|
|
50582
|
+
this.lastBuildAt = now;
|
|
50583
|
+
this.storeRevision = this.readStoreRevision();
|
|
50584
|
+
}
|
|
50585
|
+
this.detail = refreshLiveStatus(this.detail, this.state, this.ctx, usage, now);
|
|
50586
|
+
return this.detail;
|
|
50587
|
+
}
|
|
50588
|
+
}
|
|
50589
|
+
function conversationTokensFor(detail) {
|
|
50590
|
+
return Math.max(0, detail.inputTokens - detail.systemPromptTokens - detail.compartmentTokens - detail.factTokens - detail.memoryTokens - detail.profileTokens - detail.toolCallTokens - detail.toolDefinitionTokens);
|
|
50591
|
+
}
|
|
50592
|
+
function refreshLiveStatus(detail, state, ctx, usage, now) {
|
|
50593
|
+
const live = state.live;
|
|
50594
|
+
if (!live)
|
|
50595
|
+
return detail;
|
|
50596
|
+
const windowGeometry = resolvePiWindowGeometry({
|
|
50597
|
+
rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
|
|
50598
|
+
rawContextWindowSource: "catalog",
|
|
50599
|
+
model: ctx.model,
|
|
50600
|
+
detectedContextLimit: live.detectedContextLimit,
|
|
50601
|
+
provenInputTokens: live.provenInputTokens,
|
|
50602
|
+
persistedInputTokens: live.persistedInputTokens,
|
|
50603
|
+
persistedPercentage: live.persistedPercentage
|
|
50604
|
+
});
|
|
50605
|
+
const pressure = resolvePiStatusPressureSnapshot({
|
|
50606
|
+
providerInputLimit: live.providerInputLimit,
|
|
50607
|
+
sessionId: detail.sessionId,
|
|
50608
|
+
persistedPercentage: live.persistedPercentage,
|
|
50609
|
+
persistedInputTokens: live.persistedInputTokens,
|
|
50610
|
+
liveInputTokens: usage?.tokens,
|
|
50611
|
+
usableContextLimit: windowGeometry?.usableSoft
|
|
50612
|
+
});
|
|
50613
|
+
const cacheRemainingMs = cacheRemaining(detail.cacheTtl, detail.lastResponseTime, now);
|
|
50614
|
+
const current = {
|
|
50615
|
+
...detail,
|
|
50616
|
+
inputTokens: pressure.inputTokens,
|
|
50617
|
+
usagePercentage: pressure.percentage,
|
|
50618
|
+
contextLimit: pressure.contextLimit ?? 0,
|
|
50619
|
+
windowGeometry,
|
|
50620
|
+
cacheRemainingMs,
|
|
50621
|
+
cacheExpired: detail.lastResponseTime > 0 && cacheRemainingMs === 0,
|
|
50622
|
+
tailHygiene: resolveTailHygieneStatus(getPiChannel1Baseline(detail.sessionId)),
|
|
50623
|
+
recompInFlight: isPiRecompInFlight(detail.sessionId)
|
|
50624
|
+
};
|
|
50625
|
+
return { ...current, conversationTokens: conversationTokensFor(current) };
|
|
50626
|
+
}
|
|
50627
|
+
function cacheRemaining(cacheTtl, lastResponseTime, now) {
|
|
50628
|
+
let ttlMs;
|
|
50629
|
+
try {
|
|
50630
|
+
ttlMs = parseCacheTtl(cacheTtl);
|
|
50631
|
+
} catch {
|
|
50632
|
+
ttlMs = 5 * 60 * 1000;
|
|
50633
|
+
}
|
|
50634
|
+
if (ttlMs === Number.POSITIVE_INFINITY)
|
|
50635
|
+
return ttlMs;
|
|
50636
|
+
return lastResponseTime > 0 ? Math.max(0, ttlMs - (now - lastResponseTime)) : ttlMs;
|
|
50637
|
+
}
|
|
50251
50638
|
function buildPiStatusDetail(pi, ctx, deps, sessionId) {
|
|
50639
|
+
return buildStatusDetail(pi, ctx, deps, sessionId, {
|
|
50640
|
+
tokens: new PiStatusTokenCache
|
|
50641
|
+
});
|
|
50642
|
+
}
|
|
50643
|
+
function buildStatusDetail(pi, ctx, deps, sessionId, state, host = readStatusHostBytes(pi, ctx)) {
|
|
50252
50644
|
const usage = ctx.getContextUsage?.();
|
|
50253
50645
|
const meta = getOrCreateSessionMeta(deps.db, sessionId);
|
|
50254
50646
|
let detectedContextLimit;
|
|
@@ -50270,6 +50662,13 @@ function buildPiStatusDetail(pi, ctx, deps, sessionId) {
|
|
|
50270
50662
|
readBranch: () => ctx.sessionManager.getBranch(),
|
|
50271
50663
|
providerInputLimit
|
|
50272
50664
|
});
|
|
50665
|
+
state.live = {
|
|
50666
|
+
persistedInputTokens: meta.lastInputTokens,
|
|
50667
|
+
persistedPercentage: meta.lastContextPercentage,
|
|
50668
|
+
detectedContextLimit,
|
|
50669
|
+
provenInputTokens: provenInputTokens || undefined,
|
|
50670
|
+
providerInputLimit
|
|
50671
|
+
};
|
|
50273
50672
|
const windowGeometry = resolvePiWindowGeometry({
|
|
50274
50673
|
rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
|
|
50275
50674
|
rawContextWindowSource: "catalog",
|
|
@@ -50305,29 +50704,23 @@ function buildPiStatusDetail(pi, ctx, deps, sessionId) {
|
|
|
50305
50704
|
const factTokens = m0Blocks.factTokens;
|
|
50306
50705
|
const memoryTokens = m0Blocks.memoryTokens;
|
|
50307
50706
|
const profileTokens = m0Blocks.profileTokens;
|
|
50308
|
-
|
|
50309
|
-
try {
|
|
50310
|
-
const sysPrompt = readHostSystemPrompt(ctx);
|
|
50311
|
-
if (sysPrompt !== undefined && sysPrompt.length > 0) {
|
|
50312
|
-
systemPromptTokens = estimateTokens(sysPrompt);
|
|
50313
|
-
}
|
|
50314
|
-
} catch {}
|
|
50707
|
+
const { systemPromptTokens, toolDefinitionTokens } = state.tokens.estimates(host, meta.systemPromptTokens);
|
|
50315
50708
|
const tags = getTagsBySession(deps.db, sessionId);
|
|
50316
50709
|
const activeTags = tags.filter((tag) => tag.status === "active");
|
|
50317
50710
|
const droppedTags = tags.filter((tag) => tag.status === "dropped");
|
|
50318
50711
|
const activeBytes = activeTags.reduce((sum, tag) => sum + tag.byteSize, 0);
|
|
50319
50712
|
const pendingOps = readPendingOpsCount(deps.db, sessionId);
|
|
50320
50713
|
const toolCallTokens = meta.toolCallTokens;
|
|
50321
|
-
|
|
50322
|
-
|
|
50323
|
-
|
|
50324
|
-
|
|
50325
|
-
|
|
50326
|
-
|
|
50327
|
-
|
|
50328
|
-
|
|
50329
|
-
|
|
50330
|
-
|
|
50714
|
+
const conversationTokens = conversationTokensFor({
|
|
50715
|
+
inputTokens,
|
|
50716
|
+
systemPromptTokens,
|
|
50717
|
+
compartmentTokens,
|
|
50718
|
+
factTokens,
|
|
50719
|
+
memoryTokens,
|
|
50720
|
+
profileTokens,
|
|
50721
|
+
toolCallTokens,
|
|
50722
|
+
toolDefinitionTokens
|
|
50723
|
+
});
|
|
50331
50724
|
const workMetrics = getSessionWorkMetrics(deps.db, sessionId);
|
|
50332
50725
|
const tailHygiene = resolveTailHygieneStatus(getPiChannel1Baseline(sessionId));
|
|
50333
50726
|
const modelKey = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
|
|
@@ -51935,7 +52328,7 @@ import {
|
|
|
51935
52328
|
realpathSync as realpathSync4,
|
|
51936
52329
|
rmSync as rmSync2,
|
|
51937
52330
|
statSync as statSync8,
|
|
51938
|
-
writeFileSync as
|
|
52331
|
+
writeFileSync as writeFileSync3
|
|
51939
52332
|
} from "node:fs";
|
|
51940
52333
|
import { createRequire } from "node:module";
|
|
51941
52334
|
import { homedir as homedir5, tmpdir } from "node:os";
|
|
@@ -52456,7 +52849,7 @@ class PiSubagentRunner {
|
|
|
52456
52849
|
try {
|
|
52457
52850
|
systemPromptTempDir = mkdtempSync(join13(tmpdir(), "mc-pi-prompt-"));
|
|
52458
52851
|
systemPromptPath = join13(systemPromptTempDir, "system-prompt.txt");
|
|
52459
|
-
|
|
52852
|
+
writeFileSync3(systemPromptPath, options.systemPrompt, "utf8");
|
|
52460
52853
|
} catch (error) {
|
|
52461
52854
|
cleanupSystemPromptFile();
|
|
52462
52855
|
return failBeforeSpawn("spawn_failed", `failed to prepare pi system prompt file: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -52585,6 +52978,11 @@ class PiSubagentRunner {
|
|
|
52585
52978
|
let lastEventTimestamp = 0;
|
|
52586
52979
|
const accumulatedMessages = [];
|
|
52587
52980
|
accountingMessages = accumulatedMessages;
|
|
52981
|
+
const stepCap = options.stepCap ?? (options.agent === "magic-context-historian" ? HISTORIAN_STEP_CAP : undefined);
|
|
52982
|
+
let assistantSteps = 0;
|
|
52983
|
+
let streamedAssistantSteps = 0;
|
|
52984
|
+
let terminalSeen = false;
|
|
52985
|
+
const isAssistant = (message) => message !== null && typeof message === "object" && message.role === "assistant";
|
|
52588
52986
|
rl.on("line", (line) => {
|
|
52589
52987
|
if (settled || line.length === 0)
|
|
52590
52988
|
return;
|
|
@@ -52618,6 +53016,37 @@ class PiSubagentRunner {
|
|
|
52618
53016
|
event,
|
|
52619
53017
|
ms: elapsedMs
|
|
52620
53018
|
});
|
|
53019
|
+
if (stepCap !== undefined) {
|
|
53020
|
+
if (e.type === "message_end" && isAssistant(e.message)) {
|
|
53021
|
+
streamedAssistantSteps += 1;
|
|
53022
|
+
assistantSteps += 1;
|
|
53023
|
+
}
|
|
53024
|
+
if (e.type === "agent_end" && Array.isArray(e.messages) && !terminalSeen) {
|
|
53025
|
+
terminalSeen = true;
|
|
53026
|
+
const assistants = e.messages.filter(isAssistant);
|
|
53027
|
+
for (let i = streamedAssistantSteps;i < assistants.length; i += 1)
|
|
53028
|
+
assistantSteps += 1;
|
|
53029
|
+
}
|
|
53030
|
+
if (assistantSteps > stepCap) {
|
|
53031
|
+
if (e.type === "message_end")
|
|
53032
|
+
accumulatedMessages.push(e.message);
|
|
53033
|
+
if (e.type === "agent_end" && Array.isArray(e.messages))
|
|
53034
|
+
accountingMessages = e.messages;
|
|
53035
|
+
if (timeoutHandle)
|
|
53036
|
+
clearTimeout(timeoutHandle);
|
|
53037
|
+
if (drainTimerHandle)
|
|
53038
|
+
clearTimeout(drainTimerHandle);
|
|
53039
|
+
terminateChild(child);
|
|
53040
|
+
settle({
|
|
53041
|
+
ok: false,
|
|
53042
|
+
reason: "step_limit",
|
|
53043
|
+
error: `pi subagent ${options.agent} exceeded its ${stepCap}-step limit`,
|
|
53044
|
+
durationMs: Date.now() - startTime,
|
|
53045
|
+
meta: { cap: stepCap, steps: assistantSteps }
|
|
53046
|
+
});
|
|
53047
|
+
return;
|
|
53048
|
+
}
|
|
53049
|
+
}
|
|
52621
53050
|
if (e.type === "auto_retry_start" || e.type === "agent_end" && event.willRetry === true) {
|
|
52622
53051
|
sawAgentEnd = false;
|
|
52623
53052
|
agentEndMessages = null;
|
|
@@ -53079,7 +53508,6 @@ var FULL_PARAMETER_DESCRIPTIONS = {
|
|
|
53079
53508
|
content: "The memory text — one standalone fact (write, update, merge).",
|
|
53080
53509
|
category: "Kind of fact (required for write; on update/merge optional, omitted keeps the current category).",
|
|
53081
53510
|
ids: "Memory ids from <project-memory>: one for update, one or more for archive, two or more for merge, 1–20 for get.",
|
|
53082
|
-
limit: "Max results for list (default 10).",
|
|
53083
53511
|
reason: "Why it is being archived (optional)."
|
|
53084
53512
|
},
|
|
53085
53513
|
mmc_search: {
|
|
@@ -53114,13 +53542,12 @@ var LIGHT_PARAMETER_DESCRIPTIONS = {
|
|
|
53114
53542
|
content: "One standalone fact (write, update, merge).",
|
|
53115
53543
|
category: "Kind of fact (required for write; optional on update/merge).",
|
|
53116
53544
|
ids: "Ids from <project-memory>: one for update, 1+ for archive, 2+ for merge, 1–20 for get.",
|
|
53117
|
-
limit: "Max results for list (default 10).",
|
|
53118
53545
|
reason: "Why it is archived (optional)."
|
|
53119
53546
|
},
|
|
53120
53547
|
mmc_search: {
|
|
53121
53548
|
query: "A natural-language question carrying the exact terms you expect in the answer.",
|
|
53122
53549
|
limit: "Maximum results (default 10).",
|
|
53123
|
-
sources: "
|
|
53550
|
+
sources: "Sources; omit or [] for all.",
|
|
53124
53551
|
from: "Earliest date, YYYY-MM-DD (inclusive).",
|
|
53125
53552
|
to: "Latest date, YYYY-MM-DD (inclusive; default open)."
|
|
53126
53553
|
}
|
|
@@ -54832,7 +55259,8 @@ function createCtxReduceTool(deps) {
|
|
|
54832
55259
|
parts.push(`drop ${formatIds(immediateDropIds)}`);
|
|
54833
55260
|
if (deferredDropIds.length > 0)
|
|
54834
55261
|
parts.push(`deferred drop ${formatIds(deferredDropIds)}`);
|
|
54835
|
-
|
|
55262
|
+
const held = deferredDropIds.length === 1 ? `Held: §${deferredDropIds[0]} is inside the protected working set; it applies once newer work displaces it.` : deferredDropIds.length > 1 ? `Held: ${deferredDropIds.map((id) => `§${id}`).join(", ")} are inside the protected working set; they apply once newer work displaces them.` : "";
|
|
55263
|
+
return ok4(`Queued: ${parts.join(", ")}.${held ? ` ${held}` : ""}${skippedNote ? ` ${skippedNote}` : ""}${inertNote ? ` ${inertNote}` : ""}${ctxReduceSelfStampNote ? ` ${ctxReduceSelfStampNote}` : ""}`);
|
|
54836
55264
|
}
|
|
54837
55265
|
};
|
|
54838
55266
|
}
|