@cortexkit/pi-magic-context 0.44.2 → 0.44.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-esnhck8v.js → index-5am7amy4.js} +229 -60
- package/dist/{index-gsff513e.js → index-npagr1cy.js} +113 -30
- package/dist/index.js +401 -221
- package/dist/{read-session-chunk-zhtcx9f1.js → read-session-chunk-w493f72c.js} +1 -1
- package/dist/subagent-entry.js +2 -2
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -38,8 +38,10 @@ import {
|
|
|
38
38
|
formatWindowDerivationLine,
|
|
39
39
|
isSaneLimit,
|
|
40
40
|
resolveOutputReserve,
|
|
41
|
+
getSdkWindowGeometry,
|
|
41
42
|
getSdkContextLimit,
|
|
42
43
|
getSdkOutputLimit,
|
|
44
|
+
getSdkInputLimit,
|
|
43
45
|
cortexKitUserConfigBasePath,
|
|
44
46
|
cortexKitProjectConfigBasePath,
|
|
45
47
|
migrateMagicContextConfigLocations,
|
|
@@ -58,6 +60,7 @@ import {
|
|
|
58
60
|
isFailClosedBlockingError,
|
|
59
61
|
shouldBypassFailClosedBlock,
|
|
60
62
|
createFailClosedController,
|
|
63
|
+
setHomeProjectPermission,
|
|
61
64
|
ProjectIdentityError,
|
|
62
65
|
resolveProjectIdentityStrict,
|
|
63
66
|
isUserHomeDirectory,
|
|
@@ -301,6 +304,7 @@ import {
|
|
|
301
304
|
readPiSessionMessages,
|
|
302
305
|
readPiSessionMessagePage,
|
|
303
306
|
findLastModelKeyFromBranch,
|
|
307
|
+
iterateEntriesToRawMessageRange,
|
|
304
308
|
convertEntriesToRawMessages,
|
|
305
309
|
convertEntriesToRawMessagePage,
|
|
306
310
|
computeCueContentHash,
|
|
@@ -399,6 +403,9 @@ import {
|
|
|
399
403
|
MEMORY_RENDER_FORMAT_EPOCH,
|
|
400
404
|
encodeCachedM0UpgradeIdentity,
|
|
401
405
|
decodeCachedM0UpgradeIdentity,
|
|
406
|
+
renderBudgetIdentityChanged,
|
|
407
|
+
renderedBudgetSnapshot,
|
|
408
|
+
renderedBudgetShrinkReason,
|
|
402
409
|
DEFAULT_HISTORY_BUDGET_TOKENS,
|
|
403
410
|
renderCompartmentAtTier,
|
|
404
411
|
renderDecayedCompartments,
|
|
@@ -423,8 +430,10 @@ import {
|
|
|
423
430
|
registerTodoStateLifecycle,
|
|
424
431
|
syncCtxMemoryToolEnabled,
|
|
425
432
|
registerMagicContextTools
|
|
426
|
-
} from "./index-
|
|
433
|
+
} from "./index-5am7amy4.js";
|
|
427
434
|
import {
|
|
435
|
+
Database,
|
|
436
|
+
withSqliteBackgroundWriter,
|
|
428
437
|
CTX_REDUCE_KEEP,
|
|
429
438
|
newestCtxReduceTagNumbers,
|
|
430
439
|
textMentionsRecentCommit,
|
|
@@ -500,7 +509,6 @@ import {
|
|
|
500
509
|
recordOpenCodeDbReadFailure,
|
|
501
510
|
clearOpenCodeDbReadFailure,
|
|
502
511
|
claimOpenCodeDbDiagnosticOnce,
|
|
503
|
-
Database,
|
|
504
512
|
closeQuietly,
|
|
505
513
|
RAW_SUMMARY_TEXT_MAX_CHARS,
|
|
506
514
|
completedToolArcCrossesBoundary,
|
|
@@ -511,6 +519,7 @@ import {
|
|
|
511
519
|
buildTrueRawTokenIndex,
|
|
512
520
|
computeRawRangeFingerprint,
|
|
513
521
|
invalidateTrueRawTokenCache,
|
|
522
|
+
hasUserAnswerMetadata,
|
|
514
523
|
DreamTokenBudgetExceeded,
|
|
515
524
|
TOKEN_BUDGET_FINALIZE_MESSAGE,
|
|
516
525
|
TOKEN_BUDGET_TOOL_REFUSAL,
|
|
@@ -543,7 +552,7 @@ import {
|
|
|
543
552
|
getRawSessionTagKeysThrough2,
|
|
544
553
|
getLegacyProtectedTailStartOrdinal2,
|
|
545
554
|
readSessionChunk2
|
|
546
|
-
} from "./index-
|
|
555
|
+
} from "./index-npagr1cy.js";
|
|
547
556
|
import {
|
|
548
557
|
pushNotification2
|
|
549
558
|
} from "./index-b3eqj1g6.js";
|
|
@@ -1071,7 +1080,7 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
|
1071
1080
|
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
1072
1081
|
const retainedMessages = fallbackSnapshot ?? messages;
|
|
1073
1082
|
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
1074
|
-
indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd);
|
|
1083
|
+
withSqliteBackgroundWriter(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
|
|
1075
1084
|
const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
1076
1085
|
if (nextCursor <= cursor)
|
|
1077
1086
|
break;
|
|
@@ -1097,6 +1106,8 @@ function scheduleReconciliation(db, sessionId, readMessages) {
|
|
|
1097
1106
|
defer(() => {
|
|
1098
1107
|
reconcileSessionIndex(db, sessionId, readMessages).catch((error) => {
|
|
1099
1108
|
logIndexingError(sessionId, "reconciliation", error);
|
|
1109
|
+
if (isDatabaseLockedError(error))
|
|
1110
|
+
setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000).unref();
|
|
1100
1111
|
}).finally(() => {
|
|
1101
1112
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
1102
1113
|
});
|
|
@@ -1126,7 +1137,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
1126
1137
|
return;
|
|
1127
1138
|
}
|
|
1128
1139
|
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
1129
|
-
indexSingleMessage(db, sessionId, message);
|
|
1140
|
+
withSqliteBackgroundWriter(() => indexSingleMessage(db, sessionId, message));
|
|
1130
1141
|
const finalWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
1131
1142
|
if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
1132
1143
|
heapHolder.reconciledSessions.add(sessionId);
|
|
@@ -1135,6 +1146,8 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
1135
1146
|
}).catch((error) => {
|
|
1136
1147
|
heapHolder.reconciledSessions.delete(sessionId);
|
|
1137
1148
|
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
1149
|
+
if (isDatabaseLockedError(error))
|
|
1150
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
1138
1151
|
}).finally(() => {
|
|
1139
1152
|
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
1140
1153
|
});
|
|
@@ -1750,7 +1763,7 @@ function countFailures(db) {
|
|
|
1750
1763
|
function classifyBackfillError(error) {
|
|
1751
1764
|
if (error instanceof ProjectIdentityError) {
|
|
1752
1765
|
return {
|
|
1753
|
-
errorClass: error.errorClass === "dubious_ownership" || error.errorClass === "home_project_disabled" || error.errorClass === "git_identity_unavailable" ? "unknown" : error.errorClass,
|
|
1766
|
+
errorClass: error.errorClass === "dubious_ownership" || error.errorClass === "home_project_disabled" || error.errorClass === "git_identity_unavailable" || error.errorClass === "no_commits" ? "unknown" : error.errorClass,
|
|
1754
1767
|
errorMessage: error.message
|
|
1755
1768
|
};
|
|
1756
1769
|
}
|
|
@@ -1989,6 +2002,21 @@ function resolveKnownHistorianContextLimit(historianModelOverride) {
|
|
|
1989
2002
|
const limit = getSdkContextLimit(providerID, modelID, undefined, { reservation: "none" });
|
|
1990
2003
|
return typeof limit === "number" && limit > 0 ? limit : undefined;
|
|
1991
2004
|
}
|
|
2005
|
+
function resolveHistorianProducerLimits(modelKey) {
|
|
2006
|
+
if (!modelKey?.includes("/"))
|
|
2007
|
+
return {};
|
|
2008
|
+
const [provider, ...parts] = modelKey.split("/");
|
|
2009
|
+
const model = parts.join("/");
|
|
2010
|
+
if (!provider || !model)
|
|
2011
|
+
return {};
|
|
2012
|
+
const input = getSdkInputLimit(provider, model);
|
|
2013
|
+
const window = getSdkWindowGeometry(provider, model)?.derivation.window;
|
|
2014
|
+
const context = window ?? (input === undefined ? resolveKnownHistorianContextLimit(modelKey) : undefined);
|
|
2015
|
+
return {
|
|
2016
|
+
...context !== undefined ? { context } : {},
|
|
2017
|
+
...input !== undefined ? { input } : {}
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
1992
2020
|
function resolveHistorianContextLimit(historianModelOverride) {
|
|
1993
2021
|
if (typeof historianModelOverride === "string" && historianModelOverride.includes("/")) {
|
|
1994
2022
|
return resolveKnownHistorianContextLimit(historianModelOverride) ?? DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
@@ -4185,6 +4213,27 @@ function forgetHistorianOutputCap(sessionId) {
|
|
|
4185
4213
|
historianCaps.delete(sessionId);
|
|
4186
4214
|
}
|
|
4187
4215
|
|
|
4216
|
+
// ../plugin/src/shared/run-token-log.ts
|
|
4217
|
+
function count(value) {
|
|
4218
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4219
|
+
}
|
|
4220
|
+
function runTokenLog(tokens, maxTokens, finish) {
|
|
4221
|
+
const usage = tokens && typeof tokens === "object" ? tokens : {};
|
|
4222
|
+
const cache = usage.cache && typeof usage.cache === "object" ? usage.cache : {};
|
|
4223
|
+
return {
|
|
4224
|
+
input: count(usage.input ?? usage.input_tokens),
|
|
4225
|
+
output: count(usage.output ?? usage.output_tokens),
|
|
4226
|
+
reasoning: count(usage.reasoning ?? usage.reasoning_tokens),
|
|
4227
|
+
cache_read: count(usage.cacheRead ?? usage.cache_read ?? usage.cached_input_tokens ?? cache.read),
|
|
4228
|
+
cache_write: count(usage.cacheWrite ?? usage.cache_write ?? usage.cache_write_tokens ?? cache.write),
|
|
4229
|
+
max_tokens: count(maxTokens),
|
|
4230
|
+
finish_reason: typeof finish === "string" ? finish : null
|
|
4231
|
+
};
|
|
4232
|
+
}
|
|
4233
|
+
function formatRunTokenLog(tokens) {
|
|
4234
|
+
return `tokens=${JSON.stringify(tokens)}`;
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4188
4237
|
// ../plugin/src/hooks/magic-context/historian-prompt.generated.ts
|
|
4189
4238
|
var COMPARTMENT_AGENT_SYSTEM_PROMPT = `# Historian
|
|
4190
4239
|
|
|
@@ -5347,11 +5396,14 @@ function clampProducerAtomChars(text, maxChars, marker) {
|
|
|
5347
5396
|
const tailChars = Math.floor(keptChars / 2);
|
|
5348
5397
|
return `${text.slice(0, headChars)}${marker}${text.slice(text.length - tailChars)}`;
|
|
5349
5398
|
}
|
|
5350
|
-
function producerInputTokenLimit(contextLimitTokens, maxOutputTokens) {
|
|
5351
|
-
if (
|
|
5399
|
+
function producerInputTokenLimit(contextLimitTokens, maxOutputTokens, inputLimitTokens) {
|
|
5400
|
+
if (!Number.isFinite(maxOutputTokens) || maxOutputTokens < 0)
|
|
5352
5401
|
return;
|
|
5353
|
-
|
|
5354
|
-
const
|
|
5402
|
+
const shared = typeof contextLimitTokens === "number" && Number.isFinite(contextLimitTokens) && contextLimitTokens > 0 ? contextLimitTokens - maxOutputTokens : undefined;
|
|
5403
|
+
const input = typeof inputLimitTokens === "number" && Number.isFinite(inputLimitTokens) && inputLimitTokens > 0 ? inputLimitTokens : undefined;
|
|
5404
|
+
if (shared === undefined && input === undefined)
|
|
5405
|
+
return;
|
|
5406
|
+
const usableInputTokens = Math.floor(Math.min(shared ?? Infinity, input ?? Infinity));
|
|
5355
5407
|
if (usableInputTokens <= 0)
|
|
5356
5408
|
return;
|
|
5357
5409
|
const limit = Math.floor(usableInputTokens * (1 - PRODUCER_WINDOW_REFUSAL_MARGIN));
|
|
@@ -5363,15 +5415,15 @@ function historianProducerReserve(window, configuredOutput, catalogOutput) {
|
|
|
5363
5415
|
return window === undefined ? 0 : catalogOutputReserve(window, catalogOutput);
|
|
5364
5416
|
}
|
|
5365
5417
|
function producerWindowFailureReason(input) {
|
|
5366
|
-
const { producerSourceTokens, contextLimitTokens, maxOutputTokens } = input;
|
|
5367
|
-
const producerInputLimitTokens = producerInputTokenLimit(contextLimitTokens, maxOutputTokens);
|
|
5368
|
-
if (producerInputLimitTokens === undefined ||
|
|
5418
|
+
const { producerSourceTokens, contextLimitTokens, inputLimitTokens, maxOutputTokens } = input;
|
|
5419
|
+
const producerInputLimitTokens = producerInputTokenLimit(contextLimitTokens, maxOutputTokens, inputLimitTokens);
|
|
5420
|
+
if (producerInputLimitTokens === undefined || !Number.isFinite(producerSourceTokens) || producerSourceTokens <= 0) {
|
|
5369
5421
|
return null;
|
|
5370
5422
|
}
|
|
5371
|
-
const usableInputTokens = Math.max(0,
|
|
5423
|
+
const usableInputTokens = Math.floor(Math.min(contextLimitTokens === undefined ? Infinity : Math.max(0, contextLimitTokens - maxOutputTokens), inputLimitTokens ?? Infinity));
|
|
5372
5424
|
if (producerSourceTokens <= producerInputLimitTokens)
|
|
5373
5425
|
return null;
|
|
5374
|
-
return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} producer_input_limit_tokens=${producerInputLimitTokens} context_limit_tokens=${Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)} estimator_margin=${PRODUCER_WINDOW_REFUSAL_MARGIN}`;
|
|
5426
|
+
return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} producer_input_limit_tokens=${producerInputLimitTokens} context_limit_tokens=${contextLimitTokens === undefined ? "unknown" : Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)} estimator_margin=${PRODUCER_WINDOW_REFUSAL_MARGIN}`;
|
|
5375
5427
|
}
|
|
5376
5428
|
function splitMarkerPair() {
|
|
5377
5429
|
return `
|
|
@@ -5380,7 +5432,7 @@ ${HISTORIAN_TRUNCATION_MARKER}
|
|
|
5380
5432
|
`;
|
|
5381
5433
|
}
|
|
5382
5434
|
function fitAtomicHistorianSourceToProducerWindow(args) {
|
|
5383
|
-
const producerInputLimitTokens = producerInputTokenLimit(args.contextLimitTokens, args.maxOutputTokens);
|
|
5435
|
+
const producerInputLimitTokens = producerInputTokenLimit(args.contextLimitTokens, args.maxOutputTokens, args.inputLimitTokens);
|
|
5384
5436
|
const originalTokens = estimateTokens(args.text);
|
|
5385
5437
|
if (producerInputLimitTokens === undefined || originalTokens < producerInputLimitTokens || producerInputLimitTokens <= 0) {
|
|
5386
5438
|
return { text: args.text, producerInputLimitTokens, removedTokens: 0 };
|
|
@@ -5414,7 +5466,7 @@ function fitAtomicHistorianSourceToProducerWindow(args) {
|
|
|
5414
5466
|
};
|
|
5415
5467
|
}
|
|
5416
5468
|
function producerPromptFailureReason(input) {
|
|
5417
|
-
const limit = producerInputTokenLimit(input.contextLimitTokens, input.maxOutputTokens);
|
|
5469
|
+
const limit = producerInputTokenLimit(input.contextLimitTokens, input.maxOutputTokens, input.inputLimitTokens);
|
|
5418
5470
|
const tokens = providerMass({ prose: input.sourceLocal, system: input.systemLocal, tools: input.toolsLocal }, calibrationForModelKey(input.modelKey), true);
|
|
5419
5471
|
if (limit === undefined)
|
|
5420
5472
|
return null;
|
|
@@ -5525,12 +5577,15 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
|
|
|
5525
5577
|
throw new Error(`Historian host recorded an assistant error${finish}: ${describeAssistantFailure(assistantFailure.error)}`);
|
|
5526
5578
|
}
|
|
5527
5579
|
const text = extractLatestAssistantText(messages);
|
|
5580
|
+
const latest = Array.isArray(messages) ? messages.filter((message) => isRecord(message) && isRecord(message.info) && message.info.role === "assistant").sort((left, right) => historianMessageCreatedAt(right) - historianMessageCreatedAt(left))[0] : undefined;
|
|
5581
|
+
const info = latest && isRecord(latest.info) ? latest.info : {};
|
|
5528
5582
|
return {
|
|
5529
5583
|
messages,
|
|
5530
5584
|
text,
|
|
5531
5585
|
reasoning: text ? null : extractLatestHistorianReasoning(messages),
|
|
5532
5586
|
lengthCapped: hasLengthCappedOutput(messages),
|
|
5533
|
-
usage: sumTokensFromChildMessages(messages)
|
|
5587
|
+
usage: sumTokensFromChildMessages(messages),
|
|
5588
|
+
tokenLog: runTokenLog(info.tokens, undefined, info.finish ?? info.finish_reason ?? info.finishReason)
|
|
5534
5589
|
};
|
|
5535
5590
|
},
|
|
5536
5591
|
async close(handle, settlement) {
|
|
@@ -5549,8 +5604,8 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
|
|
|
5549
5604
|
}
|
|
5550
5605
|
};
|
|
5551
5606
|
}
|
|
5552
|
-
function historianReasoningBudgetDiagnostic(outputTokens) {
|
|
5553
|
-
return `historian ran out of output budget while reasoning (length-capped at ${outputTokens} tokens, no text) — set historian.maxTokens or route historian.model to a low-reasoning lane/variant`;
|
|
5607
|
+
function historianReasoningBudgetDiagnostic(outputTokens, tokens) {
|
|
5608
|
+
return `historian ran out of output budget while reasoning (length-capped at ${outputTokens} tokens, no text${tokens ? `; ${formatRunTokenLog(tokens)}` : ""}) — set historian.maxTokens or route historian.model to a low-reasoning lane/variant`;
|
|
5554
5609
|
}
|
|
5555
5610
|
async function runValidatedHistorianPass(args) {
|
|
5556
5611
|
const firstRun = await runHistorianPrompt({
|
|
@@ -5739,8 +5794,10 @@ async function runHistorianPrompt(args) {
|
|
|
5739
5794
|
const modelKey = selected ? `${selected.providerID}/${selected.modelID}` : undefined;
|
|
5740
5795
|
const system = withContentLanguageDirective(agentId === HISTORIAN_EDITOR_AGENT ? HISTORIAN_EDITOR_SYSTEM_PROMPT : COMPARTMENT_AGENT_SYSTEM_PROMPT, args.language);
|
|
5741
5796
|
const contextLimitTokens = selected ? getSdkContextLimit(selected.providerID, selected.modelID, undefined, { reservation: "none" }) : undefined;
|
|
5742
|
-
const
|
|
5743
|
-
|
|
5797
|
+
const producerLimits = selected ? resolveHistorianProducerLimits(modelKey) : {};
|
|
5798
|
+
const producerContext = producerLimits.context ?? (producerLimits.input === undefined ? contextLimitTokens : undefined);
|
|
5799
|
+
const reserve = historianProducerReserve(producerContext, args.maxOutputTokens, selected ? getSdkOutputLimit(selected.providerID, selected.modelID) : undefined);
|
|
5800
|
+
if (contextLimitTokens !== undefined && producerInputTokenLimit(producerContext, reserve, producerLimits.input) === undefined && modelKey && !unknownProducerWindows.has(modelKey)) {
|
|
5744
5801
|
unknownProducerWindows.add(modelKey);
|
|
5745
5802
|
sessionLog(parentSessionId, `producer window inconsistent for ${modelKey}: window=${contextLimitTokens} reserve=${reserve}; sending unguarded`);
|
|
5746
5803
|
}
|
|
@@ -5749,7 +5806,8 @@ async function runHistorianPrompt(args) {
|
|
|
5749
5806
|
systemLocal: estimateTokens(system),
|
|
5750
5807
|
toolsLocal: 0,
|
|
5751
5808
|
modelKey,
|
|
5752
|
-
contextLimitTokens,
|
|
5809
|
+
contextLimitTokens: producerContext,
|
|
5810
|
+
inputLimitTokens: producerLimits.input,
|
|
5753
5811
|
maxOutputTokens: reserve
|
|
5754
5812
|
});
|
|
5755
5813
|
if (failure)
|
|
@@ -5783,9 +5841,15 @@ async function runHistorianPrompt(args) {
|
|
|
5783
5841
|
}
|
|
5784
5842
|
completion = await executor.collect(handle, 50);
|
|
5785
5843
|
const lengthCapped = completion.lengthCapped;
|
|
5844
|
+
const tokens = {
|
|
5845
|
+
...runTokenLog(undefined, args.maxOutputTokens),
|
|
5846
|
+
...completion.tokenLog,
|
|
5847
|
+
max_tokens: args.maxOutputTokens ?? null
|
|
5848
|
+
};
|
|
5849
|
+
sessionLog(parentSessionId, `historian response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
|
|
5786
5850
|
const textResult = completion.text;
|
|
5787
5851
|
const reasoningResult = textResult ? null : completion.reasoning;
|
|
5788
|
-
const emptyError = !textResult && reasoningResult && lengthCapped ? historianReasoningBudgetDiagnostic(completion.usage.output) : !textResult && !reasoningResult ? "Historian returned no assistant output." : !textResult ? "Historian returned reasoning but no assistant text." : lengthCapped ?
|
|
5852
|
+
const emptyError = !textResult && reasoningResult && lengthCapped ? historianReasoningBudgetDiagnostic(completion.usage.output, tokens) : !textResult && !reasoningResult ? "Historian returned no assistant output." : !textResult ? "Historian returned reasoning but no assistant text." : lengthCapped ? `Historian returned length-capped output. ${formatRunTokenLog(tokens)}` : null;
|
|
5789
5853
|
const invocationId = recordInvocation({
|
|
5790
5854
|
status: emptyError ? "empty" : "completed",
|
|
5791
5855
|
messages: completion.messages,
|
|
@@ -6159,7 +6223,7 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisiti
|
|
|
6159
6223
|
}
|
|
6160
6224
|
};
|
|
6161
6225
|
beat();
|
|
6162
|
-
const timer = lost ? undefined : setInterval(beat, intervalMs);
|
|
6226
|
+
const timer = lost ? undefined : setInterval(() => withSqliteBackgroundWriter(beat), intervalMs);
|
|
6163
6227
|
return {
|
|
6164
6228
|
stop: () => {
|
|
6165
6229
|
if (timer)
|
|
@@ -6878,8 +6942,10 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
6878
6942
|
callContext: args.callContext,
|
|
6879
6943
|
fetchOutput: () => args.executor.collect(handle, 50),
|
|
6880
6944
|
validateOutput: (completion) => {
|
|
6945
|
+
const tokens = completion.tokenLog ?? runTokenLog(undefined);
|
|
6946
|
+
sessionLog(args.parentSessionId ?? "dreamer", `${args.callContext} response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
|
|
6881
6947
|
if (completion.lengthCapped) {
|
|
6882
|
-
throw new Error(completion.reasoning && !completion.text ? `${args.callContext} ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text) — set dreamer.maxTokens or use a low-reasoning model` : `${args.callContext} returned length-capped output`);
|
|
6948
|
+
throw new Error(completion.reasoning && !completion.text ? `${args.callContext} ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text; ${formatRunTokenLog(tokens)}) — set dreamer.maxTokens or use a low-reasoning model` : `${args.callContext} returned length-capped output; ${formatRunTokenLog(tokens)}`);
|
|
6883
6949
|
}
|
|
6884
6950
|
const text = completion.text;
|
|
6885
6951
|
if (!text && !args.allowEmpty)
|
|
@@ -7714,8 +7780,10 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
7714
7780
|
fetchOutput: () => executor.collect(opened, 50),
|
|
7715
7781
|
validateOutput: (completion) => {
|
|
7716
7782
|
const messages = completion.messages ?? [];
|
|
7783
|
+
const tokens = completion.tokenLog ?? runTokenLog(undefined);
|
|
7784
|
+
sessionLog(args.parentSessionId ?? "dreamer", `dreamer:classify response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
|
|
7717
7785
|
if (completion.lengthCapped) {
|
|
7718
|
-
throw new Error(completion.reasoning && !completion.text ? `classify ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text) — set dreamer.maxTokens or use a low-reasoning model` :
|
|
7786
|
+
throw new Error(completion.reasoning && !completion.text ? `classify ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text; ${formatRunTokenLog(tokens)}) — set dreamer.maxTokens or use a low-reasoning model` : `classify returned length-capped output; ${formatRunTokenLog(tokens)}`);
|
|
7719
7787
|
}
|
|
7720
7788
|
const text = completion.text;
|
|
7721
7789
|
if (!text)
|
|
@@ -10339,6 +10407,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10339
10407
|
let agentSessionId = null;
|
|
10340
10408
|
let promptSettled = false;
|
|
10341
10409
|
const startedAt = Date.now();
|
|
10410
|
+
let budgetFinalized = false;
|
|
10411
|
+
const onBudgetUpdate = (state) => {
|
|
10412
|
+
budgetFinalized ||= state.finalizeFired;
|
|
10413
|
+
args.onBudgetUpdate?.(state);
|
|
10414
|
+
};
|
|
10342
10415
|
try {
|
|
10343
10416
|
const prompt = buildMapMemoriesPrompt(args.projectIdentity, batch);
|
|
10344
10417
|
if (args.hiddenCompletionExecutor) {
|
|
@@ -10351,7 +10424,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10351
10424
|
prompt,
|
|
10352
10425
|
title: "magic-context-dream-map-memories",
|
|
10353
10426
|
callContext: "dreamer:map-memories",
|
|
10354
|
-
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate
|
|
10427
|
+
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
|
|
10355
10428
|
model: args.model,
|
|
10356
10429
|
fallbackModels: args.fallbackModels,
|
|
10357
10430
|
timeoutMs: sliceMs,
|
|
@@ -10362,9 +10435,12 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10362
10435
|
status: "completed",
|
|
10363
10436
|
messages: run.completion.messages ?? []
|
|
10364
10437
|
});
|
|
10365
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
10438
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
10366
10439
|
const returnedIds = new Set(run.validated.map((entry) => entry.id));
|
|
10367
|
-
return {
|
|
10440
|
+
return {
|
|
10441
|
+
...outcome,
|
|
10442
|
+
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
10443
|
+
};
|
|
10368
10444
|
}
|
|
10369
10445
|
const client = args.client;
|
|
10370
10446
|
if (!client)
|
|
@@ -10394,7 +10470,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10394
10470
|
}, {
|
|
10395
10471
|
transport: createPromptAsyncTransport(client, agentSessionId, {
|
|
10396
10472
|
tokenBudget: args.tokenBudget,
|
|
10397
|
-
onBudgetUpdate
|
|
10473
|
+
onBudgetUpdate
|
|
10398
10474
|
}),
|
|
10399
10475
|
timeoutMs: sliceMs,
|
|
10400
10476
|
signal,
|
|
@@ -10421,11 +10497,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10421
10497
|
});
|
|
10422
10498
|
promptSettled = true;
|
|
10423
10499
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
10424
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
10500
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
10425
10501
|
const returnedIds = new Set(run.validated.filter((entry) => batch.some((memory) => memory.id === entry.id)).map((entry) => entry.id));
|
|
10426
10502
|
return {
|
|
10427
10503
|
...outcome,
|
|
10428
|
-
requeue: batch.filter((memory) => !returnedIds.has(memory.id))
|
|
10504
|
+
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
10429
10505
|
};
|
|
10430
10506
|
} catch (error) {
|
|
10431
10507
|
const desc = describeError(error);
|
|
@@ -10460,7 +10536,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
10460
10536
|
});
|
|
10461
10537
|
}
|
|
10462
10538
|
}
|
|
10463
|
-
async function applyParsedBatchMappings(args, batch, parsed) {
|
|
10539
|
+
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false) {
|
|
10464
10540
|
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
10465
10541
|
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
10466
10542
|
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
@@ -10468,9 +10544,12 @@ async function applyParsedBatchMappings(args, batch, parsed) {
|
|
|
10468
10544
|
log(`[dreamer] map-memories warning: dropping ${unknown.length} unknown mapping entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
|
|
10469
10545
|
}
|
|
10470
10546
|
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
10471
|
-
if (valid.length * 2 < batch.length) {
|
|
10547
|
+
if (!budgetFinalized && valid.length * 2 < batch.length) {
|
|
10472
10548
|
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
10473
10549
|
}
|
|
10550
|
+
if (budgetFinalized && valid.length < batch.length) {
|
|
10551
|
+
log(`[dreamer] map-memories: accepted partial manifest after token budget: ${valid.length}/${batch.length}`);
|
|
10552
|
+
}
|
|
10474
10553
|
if (valid.length === 0)
|
|
10475
10554
|
return { mapped: 0, independent: 0 };
|
|
10476
10555
|
const planned = [];
|
|
@@ -12247,6 +12326,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12247
12326
|
let agentSessionId = null;
|
|
12248
12327
|
let promptSettled = false;
|
|
12249
12328
|
const startedAt = Date.now();
|
|
12329
|
+
let budgetFinalized = false;
|
|
12330
|
+
const onBudgetUpdate = (state) => {
|
|
12331
|
+
budgetFinalized ||= state.finalizeFired;
|
|
12332
|
+
args.onBudgetUpdate?.(state);
|
|
12333
|
+
};
|
|
12250
12334
|
try {
|
|
12251
12335
|
const headAtPrompt = await readGitHead(args.sessionDirectory);
|
|
12252
12336
|
const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
|
|
@@ -12261,7 +12345,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12261
12345
|
prompt,
|
|
12262
12346
|
title: "magic-context-dream-verify",
|
|
12263
12347
|
callContext: "dreamer:verify",
|
|
12264
|
-
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate
|
|
12348
|
+
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
|
|
12265
12349
|
model: args.model,
|
|
12266
12350
|
fallbackModels: args.fallbackModels,
|
|
12267
12351
|
language: args.language,
|
|
@@ -12278,7 +12362,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12278
12362
|
status: "completed",
|
|
12279
12363
|
messages: run.completion.messages ?? []
|
|
12280
12364
|
});
|
|
12281
|
-
return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
|
|
12365
|
+
return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
12282
12366
|
}
|
|
12283
12367
|
const client = args.client;
|
|
12284
12368
|
if (!client)
|
|
@@ -12308,7 +12392,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12308
12392
|
}, {
|
|
12309
12393
|
transport: createPromptAsyncTransport(client, agentSessionId, {
|
|
12310
12394
|
tokenBudget: args.tokenBudget,
|
|
12311
|
-
onBudgetUpdate
|
|
12395
|
+
onBudgetUpdate
|
|
12312
12396
|
}),
|
|
12313
12397
|
timeoutMs: sliceMs,
|
|
12314
12398
|
signal,
|
|
@@ -12338,7 +12422,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12338
12422
|
});
|
|
12339
12423
|
promptSettled = true;
|
|
12340
12424
|
recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
|
|
12341
|
-
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
|
|
12425
|
+
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
12342
12426
|
} catch (error) {
|
|
12343
12427
|
const desc = describeError(error);
|
|
12344
12428
|
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
@@ -12384,7 +12468,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
12384
12468
|
});
|
|
12385
12469
|
}
|
|
12386
12470
|
}
|
|
12387
|
-
async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
|
|
12471
|
+
async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
|
|
12388
12472
|
const batchIds = new Set(batch.map((m) => m.id));
|
|
12389
12473
|
const batchById = new Map(batch.map((memory) => [memory.id, memory]));
|
|
12390
12474
|
const valid = {
|
|
@@ -12404,9 +12488,12 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
|
|
|
12404
12488
|
}
|
|
12405
12489
|
const validIds = [...valid.verified, ...valid.updated, ...valid.archived, ...valid.skipped].map((entry) => entry.id);
|
|
12406
12490
|
assertNoDuplicateManifestIds(validIds, "verify");
|
|
12407
|
-
if (validIds.length * 2 < batch.length) {
|
|
12491
|
+
if (!budgetFinalized && validIds.length * 2 < batch.length) {
|
|
12408
12492
|
throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
12409
12493
|
}
|
|
12494
|
+
if (budgetFinalized && validIds.length < batch.length) {
|
|
12495
|
+
log(`[dreamer] verify: accepted partial manifest after token budget: ${validIds.length}/${batch.length}`);
|
|
12496
|
+
}
|
|
12410
12497
|
if (validIds.length === 0) {
|
|
12411
12498
|
return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
|
|
12412
12499
|
}
|
|
@@ -14433,6 +14520,205 @@ function clearDreamerTickFailure(db) {
|
|
|
14433
14520
|
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
|
|
14434
14521
|
}
|
|
14435
14522
|
|
|
14523
|
+
// ../plugin/src/hooks/magic-context/lkg-persist.ts
|
|
14524
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
14525
|
+
function parseStringArray(value) {
|
|
14526
|
+
if (typeof value !== "string")
|
|
14527
|
+
return null;
|
|
14528
|
+
let parsed;
|
|
14529
|
+
try {
|
|
14530
|
+
parsed = JSON.parse(value);
|
|
14531
|
+
} catch {
|
|
14532
|
+
return null;
|
|
14533
|
+
}
|
|
14534
|
+
if (!Array.isArray(parsed))
|
|
14535
|
+
return null;
|
|
14536
|
+
const result = [];
|
|
14537
|
+
for (const entry of parsed) {
|
|
14538
|
+
if (typeof entry !== "string" || entry.length === 0)
|
|
14539
|
+
return null;
|
|
14540
|
+
result.push(entry);
|
|
14541
|
+
}
|
|
14542
|
+
return result;
|
|
14543
|
+
}
|
|
14544
|
+
function parseNullableString(value) {
|
|
14545
|
+
if (value === null || value === undefined)
|
|
14546
|
+
return null;
|
|
14547
|
+
return typeof value === "string" ? value : undefined;
|
|
14548
|
+
}
|
|
14549
|
+
function parseNullableInteger(value) {
|
|
14550
|
+
if (value === null || value === undefined)
|
|
14551
|
+
return;
|
|
14552
|
+
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
14553
|
+
}
|
|
14554
|
+
function parsePersistedLkgSlot(row) {
|
|
14555
|
+
if (!row || typeof row !== "object")
|
|
14556
|
+
return;
|
|
14557
|
+
const record = row;
|
|
14558
|
+
const jsonPrefix = record.json_prefix;
|
|
14559
|
+
const lastInputMessageId = record.last_input_message_id;
|
|
14560
|
+
const capturedAt = record.captured_at;
|
|
14561
|
+
let inputIdsRaw = record.input_id_seq;
|
|
14562
|
+
let piOutputEntryIds;
|
|
14563
|
+
if (typeof inputIdsRaw === "string") {
|
|
14564
|
+
try {
|
|
14565
|
+
const metadata = JSON.parse(inputIdsRaw);
|
|
14566
|
+
if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
|
|
14567
|
+
if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
|
|
14568
|
+
return;
|
|
14569
|
+
piOutputEntryIds = metadata.piOutputEntryIds;
|
|
14570
|
+
inputIdsRaw = JSON.stringify(metadata.inputIds);
|
|
14571
|
+
}
|
|
14572
|
+
} catch {
|
|
14573
|
+
return;
|
|
14574
|
+
}
|
|
14575
|
+
}
|
|
14576
|
+
const inputIdSeq = parseStringArray(inputIdsRaw);
|
|
14577
|
+
const inputContentDigests = parseStringArray(record.input_content_digests);
|
|
14578
|
+
const modelKey = parseNullableString(record.model_key);
|
|
14579
|
+
const providerKey = parseNullableString(record.provider_key);
|
|
14580
|
+
if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
|
|
14581
|
+
return;
|
|
14582
|
+
}
|
|
14583
|
+
if (piOutputEntryIds) {
|
|
14584
|
+
try {
|
|
14585
|
+
const output = JSON.parse(jsonPrefix);
|
|
14586
|
+
const inputs = new Set(inputIdSeq);
|
|
14587
|
+
if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
|
|
14588
|
+
return;
|
|
14589
|
+
} catch {
|
|
14590
|
+
return;
|
|
14591
|
+
}
|
|
14592
|
+
}
|
|
14593
|
+
let inputContentSignatures;
|
|
14594
|
+
if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
|
|
14595
|
+
const parsed = parseStringArray(record.input_content_signatures);
|
|
14596
|
+
if (parsed === null || parsed.length !== inputIdSeq.length)
|
|
14597
|
+
return;
|
|
14598
|
+
inputContentSignatures = parsed;
|
|
14599
|
+
}
|
|
14600
|
+
const slot = {
|
|
14601
|
+
jsonPrefix,
|
|
14602
|
+
inputIdSeq,
|
|
14603
|
+
inputContentDigests,
|
|
14604
|
+
lastInputMessageId,
|
|
14605
|
+
modelKey,
|
|
14606
|
+
providerKey,
|
|
14607
|
+
capturedAt
|
|
14608
|
+
};
|
|
14609
|
+
if (inputContentSignatures)
|
|
14610
|
+
slot.inputContentSignatures = inputContentSignatures;
|
|
14611
|
+
if (piOutputEntryIds)
|
|
14612
|
+
slot.piOutputEntryIds = piOutputEntryIds;
|
|
14613
|
+
const rowVersion = parseNullableInteger(record.row_version);
|
|
14614
|
+
if (rowVersion !== undefined)
|
|
14615
|
+
slot.rowVersion = rowVersion;
|
|
14616
|
+
const captureSequence = parseNullableInteger(record.capture_sequence);
|
|
14617
|
+
if (captureSequence !== undefined)
|
|
14618
|
+
slot.captureSequence = captureSequence;
|
|
14619
|
+
return slot;
|
|
14620
|
+
}
|
|
14621
|
+
var persistedFingerprints = new WeakMap;
|
|
14622
|
+
function saveLkgSlotToDb(db, sessionId, slot) {
|
|
14623
|
+
const fingerprint = createHash11("sha256").update(JSON.stringify([
|
|
14624
|
+
slot.jsonPrefix,
|
|
14625
|
+
slot.inputIdSeq,
|
|
14626
|
+
slot.inputContentDigests,
|
|
14627
|
+
slot.inputContentSignatures,
|
|
14628
|
+
slot.piOutputEntryIds,
|
|
14629
|
+
slot.lastInputMessageId,
|
|
14630
|
+
slot.modelKey,
|
|
14631
|
+
slot.providerKey,
|
|
14632
|
+
slot.rowVersion,
|
|
14633
|
+
slot.captureSequence
|
|
14634
|
+
])).digest("hex");
|
|
14635
|
+
let saved = persistedFingerprints.get(db);
|
|
14636
|
+
if (saved?.get(sessionId) === fingerprint)
|
|
14637
|
+
return true;
|
|
14638
|
+
try {
|
|
14639
|
+
db.prepare(`INSERT INTO lkg_slots (
|
|
14640
|
+
session_id, json_prefix, input_id_seq, input_content_digests,
|
|
14641
|
+
input_content_signatures, last_input_message_id, model_key, provider_key,
|
|
14642
|
+
captured_at, row_version, capture_sequence
|
|
14643
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
14644
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
14645
|
+
json_prefix = excluded.json_prefix,
|
|
14646
|
+
input_id_seq = excluded.input_id_seq,
|
|
14647
|
+
input_content_digests = excluded.input_content_digests,
|
|
14648
|
+
input_content_signatures = excluded.input_content_signatures,
|
|
14649
|
+
last_input_message_id = excluded.last_input_message_id,
|
|
14650
|
+
model_key = excluded.model_key,
|
|
14651
|
+
provider_key = excluded.provider_key,
|
|
14652
|
+
captured_at = excluded.captured_at,
|
|
14653
|
+
row_version = excluded.row_version,
|
|
14654
|
+
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
|
|
14655
|
+
version: 1,
|
|
14656
|
+
inputIds: slot.inputIdSeq,
|
|
14657
|
+
piOutputEntryIds: slot.piOutputEntryIds
|
|
14658
|
+
} : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
|
|
14659
|
+
if (!saved) {
|
|
14660
|
+
saved = new Map;
|
|
14661
|
+
persistedFingerprints.set(db, saved);
|
|
14662
|
+
}
|
|
14663
|
+
if (saved.size >= 1000) {
|
|
14664
|
+
const oldest = saved.keys().next().value;
|
|
14665
|
+
if (oldest !== undefined)
|
|
14666
|
+
saved.delete(oldest);
|
|
14667
|
+
}
|
|
14668
|
+
saved.set(sessionId, fingerprint);
|
|
14669
|
+
return true;
|
|
14670
|
+
} catch (error) {
|
|
14671
|
+
sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
|
|
14672
|
+
return false;
|
|
14673
|
+
}
|
|
14674
|
+
}
|
|
14675
|
+
function clearPersistedLkgSlot(db, sessionId) {
|
|
14676
|
+
try {
|
|
14677
|
+
db.prepare("DELETE FROM lkg_slots WHERE session_id = ?").run(sessionId);
|
|
14678
|
+
persistedFingerprints.get(db)?.delete(sessionId);
|
|
14679
|
+
} catch (error) {
|
|
14680
|
+
sessionLog(sessionId, "LKG snapshot durable clear failed:", error);
|
|
14681
|
+
}
|
|
14682
|
+
}
|
|
14683
|
+
function loadPersistedLkgSlot(db, sessionId) {
|
|
14684
|
+
let row;
|
|
14685
|
+
try {
|
|
14686
|
+
row = db.prepare("SELECT * FROM lkg_slots WHERE session_id = ?").get(sessionId);
|
|
14687
|
+
} catch (error) {
|
|
14688
|
+
sessionLog(sessionId, "LKG snapshot durable load failed:", error);
|
|
14689
|
+
return;
|
|
14690
|
+
}
|
|
14691
|
+
if (!row)
|
|
14692
|
+
return;
|
|
14693
|
+
const slot = parsePersistedLkgSlot(row);
|
|
14694
|
+
if (!slot) {
|
|
14695
|
+
clearPersistedLkgSlot(db, sessionId);
|
|
14696
|
+
return;
|
|
14697
|
+
}
|
|
14698
|
+
return slot;
|
|
14699
|
+
}
|
|
14700
|
+
function pruneStaleLkgSlots(db, now = Date.now()) {
|
|
14701
|
+
const previousTimeout = db.prepare("PRAGMA busy_timeout").get();
|
|
14702
|
+
try {
|
|
14703
|
+
db.exec("PRAGMA busy_timeout = 0");
|
|
14704
|
+
const result = db.prepare(`DELETE FROM lkg_slots WHERE captured_at < ? AND NOT EXISTS (
|
|
14705
|
+
SELECT 1 FROM session_projects sp
|
|
14706
|
+
WHERE sp.session_id = lkg_slots.session_id AND sp.updated_at >= ?
|
|
14707
|
+
)`).run(now - 7 * 24 * 60 * 60 * 1000, now - 7 * 24 * 60 * 60 * 1000);
|
|
14708
|
+
if (result.changes)
|
|
14709
|
+
persistedFingerprints.delete(db);
|
|
14710
|
+
return result.changes;
|
|
14711
|
+
} finally {
|
|
14712
|
+
db.exec(`PRAGMA busy_timeout = ${Number(previousTimeout.timeout) || 0}`);
|
|
14713
|
+
}
|
|
14714
|
+
}
|
|
14715
|
+
function createDbLkgPersistence(db) {
|
|
14716
|
+
return {
|
|
14717
|
+
load: (sessionId) => loadPersistedLkgSlot(db, sessionId),
|
|
14718
|
+
clear: (sessionId) => clearPersistedLkgSlot(db, sessionId)
|
|
14719
|
+
};
|
|
14720
|
+
}
|
|
14721
|
+
|
|
14436
14722
|
// ../plugin/src/plugin/dream-timer.ts
|
|
14437
14723
|
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
14438
14724
|
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
@@ -14595,6 +14881,11 @@ function persistTickOutcome(db, failure) {
|
|
|
14595
14881
|
}
|
|
14596
14882
|
}
|
|
14597
14883
|
async function runMessageHistoryMaintenance(db) {
|
|
14884
|
+
try {
|
|
14885
|
+
pruneStaleLkgSlots(db);
|
|
14886
|
+
} catch (error) {
|
|
14887
|
+
log("[magic-context] LKG pruning deferred:", error);
|
|
14888
|
+
}
|
|
14598
14889
|
const cleanup = retryPendingSessionCleanups(db);
|
|
14599
14890
|
if (cleanup.cleared > 0 || cleanup.failedSessionIds.length > 0) {
|
|
14600
14891
|
log(`[message-index] pending session cleanup: cleared=${cleanup.cleared} failed=${cleanup.failedSessionIds.length}`);
|
|
@@ -15492,6 +15783,15 @@ class PiSubagentRunner {
|
|
|
15492
15783
|
if (settled)
|
|
15493
15784
|
return;
|
|
15494
15785
|
settled = true;
|
|
15786
|
+
if (accountingMessages.length > 0 && /historian|dreamer|classify/i.test(options.agent)) {
|
|
15787
|
+
const last = [...accountingMessages].reverse().find((message) => message !== null && typeof message === "object" && message.role === "assistant");
|
|
15788
|
+
const responseChars = result.ok ? result.assistantText.length : last?.content?.filter((part) => typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string").reduce((sum, part) => sum + part.text.length, 0) ?? 0;
|
|
15789
|
+
const tokenDetails = formatRunTokenLog(runTokenLog(last?.usage, options.maxOutputTokens, last?.stopReason));
|
|
15790
|
+
if (!result.ok && result.reason === "truncated") {
|
|
15791
|
+
result = { ...result, error: `${result.error}; ${tokenDetails}` };
|
|
15792
|
+
}
|
|
15793
|
+
sessionLog(options.accountingSessionId ?? "subagent", `${options.agent} response_chars=${responseChars} ${tokenDetails}`);
|
|
15794
|
+
}
|
|
15495
15795
|
const outcome = budget ? {
|
|
15496
15796
|
...result,
|
|
15497
15797
|
meta: { ...result.meta, tokenBudget: budget.snapshot() }
|
|
@@ -16599,6 +16899,9 @@ function createPiPrimerRawProviderFactory(deps = {}) {
|
|
|
16599
16899
|
readMessages() {
|
|
16600
16900
|
throw new Error("Pi primer history requires bounded pages");
|
|
16601
16901
|
},
|
|
16902
|
+
iterateMessageRange(from, to) {
|
|
16903
|
+
return iterateEntriesToRawMessageRange(summaryEntries(path), from - 1, Number.MAX_SAFE_INTEGER, to);
|
|
16904
|
+
},
|
|
16602
16905
|
readMessagePage(after, limit, watermark) {
|
|
16603
16906
|
return convertEntriesToRawMessagePage(summaryEntries(path), after, Math.min(50, limit), watermark);
|
|
16604
16907
|
}
|
|
@@ -17944,6 +18247,12 @@ function resolveTokensMatchWithKey(tokensConfig, modelKey) {
|
|
|
17944
18247
|
}
|
|
17945
18248
|
return;
|
|
17946
18249
|
}
|
|
18250
|
+
function historyBudgetPolicyIdentity(historyBudgetPercentage, executeThresholdPercentage, modelKey, executeThresholdTokens) {
|
|
18251
|
+
if (!historyBudgetPercentage)
|
|
18252
|
+
return "pdefault";
|
|
18253
|
+
const threshold = resolveExecuteThresholdDetail(executeThresholdPercentage ?? 65, modelKey, 65, { tokensConfig: executeThresholdTokens, contextLimit: Number.MAX_SAFE_INTEGER });
|
|
18254
|
+
return `p${historyBudgetPercentage}:${threshold.mode}:${threshold.absoluteTokens ?? threshold.percentage}`;
|
|
18255
|
+
}
|
|
17947
18256
|
|
|
17948
18257
|
// ../plugin/src/features/magic-context/scheduler.ts
|
|
17949
18258
|
var TTL_PATTERN = /^(\d+)([smh])$/;
|
|
@@ -20545,10 +20854,10 @@ function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
|
|
|
20545
20854
|
}
|
|
20546
20855
|
|
|
20547
20856
|
// ../plugin/src/shared/tag-transcript.ts
|
|
20548
|
-
import { createHash as
|
|
20857
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
20549
20858
|
var TEXT_TAG_IDENTITY_MARKER = ":mc-text-v1:";
|
|
20550
20859
|
function textIdentityDigest(value) {
|
|
20551
|
-
return
|
|
20860
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
20552
20861
|
}
|
|
20553
20862
|
function buildContentDerivedTextIds(messageId, parts) {
|
|
20554
20863
|
const sources = parts.filter((part) => part.kind === "text").map((part) => stripTagPrefix(part.getText() ?? ""));
|
|
@@ -21235,7 +21544,7 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton, conve
|
|
|
21235
21544
|
}
|
|
21236
21545
|
return any ? "truncated" : "absent";
|
|
21237
21546
|
},
|
|
21238
|
-
canDrop: complete,
|
|
21547
|
+
canDrop: () => complete() && !occurrences.some((occ) => occ.part.hasUserAnswer?.()),
|
|
21239
21548
|
requiresToolArcSkeleton,
|
|
21240
21549
|
readInput() {
|
|
21241
21550
|
for (const occ of occurrences) {
|
|
@@ -21287,6 +21596,7 @@ function buildToolTarget(part, message, tagId) {
|
|
|
21287
21596
|
return setToolContentOrText(part, `[dropped §${tagId}§]`) ? "truncated" : "absent";
|
|
21288
21597
|
},
|
|
21289
21598
|
cannotRemove: () => part.setToolInput !== undefined,
|
|
21599
|
+
...part.hasUserAnswer?.() ? { canDrop: () => false } : {},
|
|
21290
21600
|
inputStringBytes() {
|
|
21291
21601
|
return part.setToolInput ? toolInputStringBytes(part.getToolInput?.() ?? null) : 0;
|
|
21292
21602
|
},
|
|
@@ -23812,8 +24122,10 @@ async function runHistorianSubagentWithTransientRetriesGuarded(args) {
|
|
|
23812
24122
|
try {
|
|
23813
24123
|
const key = piModelRefToCanonical(args.options.model ?? "");
|
|
23814
24124
|
const window = args.resolveContextLimit?.(key) ?? resolveKnownHistorianContextLimit(key);
|
|
23815
|
-
const
|
|
23816
|
-
|
|
24125
|
+
const limits = args.resolveContextLimit ? { context: window, input: undefined } : resolveHistorianProducerLimits(key);
|
|
24126
|
+
const context = limits.context ?? (limits.input === undefined ? window : undefined);
|
|
24127
|
+
const reserve = historianProducerReserve(context, args.options.maxOutputTokens, args.resolveOutputLimit?.(key));
|
|
24128
|
+
if (window !== undefined && producerInputTokenLimit(context, reserve, limits.input) === undefined && !loggedInconsistentWindows.has(key)) {
|
|
23817
24129
|
loggedInconsistentWindows.add(key);
|
|
23818
24130
|
sessionLog(args.sessionId, `producer window inconsistent for ${key}: window=${window} reserve=${reserve}; sending unguarded`);
|
|
23819
24131
|
}
|
|
@@ -23822,7 +24134,8 @@ async function runHistorianSubagentWithTransientRetriesGuarded(args) {
|
|
|
23822
24134
|
systemLocal: estimateTokens(args.options.systemPrompt),
|
|
23823
24135
|
toolsLocal: 0,
|
|
23824
24136
|
modelKey: key,
|
|
23825
|
-
contextLimitTokens:
|
|
24137
|
+
contextLimitTokens: context,
|
|
24138
|
+
inputLimitTokens: limits.input,
|
|
23826
24139
|
maxOutputTokens: reserve
|
|
23827
24140
|
});
|
|
23828
24141
|
if (failure)
|
|
@@ -24964,6 +25277,8 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
24964
25277
|
if (!matched)
|
|
24965
25278
|
continue;
|
|
24966
25279
|
const target = targets.get(tag.tagNumber);
|
|
25280
|
+
if (target?.canDrop?.() === false)
|
|
25281
|
+
continue;
|
|
24967
25282
|
const { result, mode } = applyNewToolDrop(target, { inWindow: false });
|
|
24968
25283
|
if (result === "incomplete")
|
|
24969
25284
|
continue;
|
|
@@ -25048,6 +25363,8 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
25048
25363
|
for (let i = 0;i < group.length - 1; i++) {
|
|
25049
25364
|
const tag = group[i];
|
|
25050
25365
|
const target = targets.get(tag.tagNumber);
|
|
25366
|
+
if (target?.canDrop?.() === false)
|
|
25367
|
+
continue;
|
|
25051
25368
|
const { result, mode } = applyNewToolDrop(target, {
|
|
25052
25369
|
inWindow: false
|
|
25053
25370
|
});
|
|
@@ -26091,7 +26408,7 @@ var EMPTY_PI_HARD_SIGNALS = {
|
|
|
26091
26408
|
lastResponseTime: 0
|
|
26092
26409
|
};
|
|
26093
26410
|
function renderBudgetIdentityPi(state) {
|
|
26094
|
-
return `m${state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
|
|
26411
|
+
return `m${state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state.historyBudgetPolicyIdentity ?? state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
|
|
26095
26412
|
}
|
|
26096
26413
|
function piMaterializeMismatch(reason, signal, cached, current) {
|
|
26097
26414
|
return { value: true, reason, mismatch: { signal, cached, current } };
|
|
@@ -26226,7 +26543,8 @@ function getCachedMarkers(db, state, compartmentsForNormalization, metaOverride,
|
|
|
26226
26543
|
modelKey: meta.cachedM0ModelKey ?? "",
|
|
26227
26544
|
projectIdentity: meta.cachedM0ProjectIdentity ?? null,
|
|
26228
26545
|
muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
|
|
26229
|
-
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
|
|
26546
|
+
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? "",
|
|
26547
|
+
renderedBudgets: cachedUpgradeIdentity.renderedBudgets
|
|
26230
26548
|
};
|
|
26231
26549
|
}
|
|
26232
26550
|
function lastBaselineEndMessageId(compartments) {
|
|
@@ -26261,7 +26579,8 @@ function readCurrentMarkersFromCompartments(db, state, compartments, projectDocs
|
|
|
26261
26579
|
modelKey: piModelRefToCanonical((state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
|
|
26262
26580
|
projectIdentity: state.projectIdentity,
|
|
26263
26581
|
muralEnabled: state.muralEnabled === true,
|
|
26264
|
-
renderBudgetIdentity: renderBudgetIdentityPi(state)
|
|
26582
|
+
renderBudgetIdentity: renderBudgetIdentityPi(state),
|
|
26583
|
+
renderedBudgets: renderedBudgetSnapshot(state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS, state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS)
|
|
26265
26584
|
};
|
|
26266
26585
|
}
|
|
26267
26586
|
function mustMaterializePi(state, db, currentCompartmentsOverride, passSnapshot) {
|
|
@@ -26283,10 +26602,14 @@ function mustMaterializePi(state, db, currentCompartmentsOverride, passSnapshot)
|
|
|
26283
26602
|
return piMaterializeMismatch("compartment_render_epoch", "compartmentRenderEpoch", cached.compartmentRenderEpoch, current.compartmentRenderEpoch);
|
|
26284
26603
|
}
|
|
26285
26604
|
if (cached.muralEnabled !== current.muralEnabled) {
|
|
26286
|
-
return piMaterializeMismatch(
|
|
26605
|
+
return piMaterializeMismatch(`render_config:mural(${cached.muralEnabled}→${current.muralEnabled})`, "muralEnabled", cached.muralEnabled, current.muralEnabled);
|
|
26287
26606
|
}
|
|
26288
|
-
if (cached.renderBudgetIdentity
|
|
26289
|
-
return piMaterializeMismatch(
|
|
26607
|
+
if (renderBudgetIdentityChanged(cached.renderBudgetIdentity, current.renderBudgetIdentity)) {
|
|
26608
|
+
return piMaterializeMismatch(`render_config:budget(${cached.renderBudgetIdentity}→${current.renderBudgetIdentity})`, "renderBudgetIdentity", cached.renderBudgetIdentity, current.renderBudgetIdentity);
|
|
26609
|
+
}
|
|
26610
|
+
const budgetShrinkReason = renderedBudgetShrinkReason(cached.renderedBudgets, current.renderedBudgets);
|
|
26611
|
+
if (budgetShrinkReason) {
|
|
26612
|
+
return piMaterializeMismatch(budgetShrinkReason, "renderedBudgets", cached.renderedBudgets ?? null, current.renderedBudgets ?? null);
|
|
26290
26613
|
}
|
|
26291
26614
|
const hard = state.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
|
|
26292
26615
|
const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
|
|
@@ -26428,7 +26751,8 @@ function readFrozenM0InputsPi(state, db, docs = readProjectDocsForPiM0(state), m
|
|
|
26428
26751
|
modelKey: piModelRefToCanonical((state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
|
|
26429
26752
|
projectIdentity: state.projectIdentity,
|
|
26430
26753
|
muralEnabled: state.memoryEnabled !== false && state.muralEnabled === true,
|
|
26431
|
-
renderBudgetIdentity: renderBudgetIdentityPi(state)
|
|
26754
|
+
renderBudgetIdentity: renderBudgetIdentityPi(state),
|
|
26755
|
+
renderedBudgets: renderedBudgetSnapshot(state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS, state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS)
|
|
26432
26756
|
};
|
|
26433
26757
|
return { docs, markers, compartments, memories, userProfile, workspace };
|
|
26434
26758
|
});
|
|
@@ -26518,7 +26842,7 @@ function materializeM0Pi(state, db, passSnapshot) {
|
|
|
26518
26842
|
projectDocsHash: snapshotMarkers.projectDocsHash,
|
|
26519
26843
|
materializedAt: snapshotMarkers.materializedAt,
|
|
26520
26844
|
sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
|
|
26521
|
-
upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch),
|
|
26845
|
+
upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null),
|
|
26522
26846
|
systemHash: snapshotMarkers.systemHash,
|
|
26523
26847
|
modelKey: snapshotMarkers.modelKey,
|
|
26524
26848
|
projectIdentity: snapshotMarkers.projectIdentity
|
|
@@ -26778,7 +27102,8 @@ function markersFromCachedPiRow(row, compartmentsForNormalization) {
|
|
|
26778
27102
|
modelKey: row.cached_m0_model_key ?? "",
|
|
26779
27103
|
projectIdentity: row.cached_m0_project_identity ?? null,
|
|
26780
27104
|
muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
|
|
26781
|
-
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
|
|
27105
|
+
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? "",
|
|
27106
|
+
renderedBudgets: cachedUpgradeIdentity.renderedBudgets
|
|
26782
27107
|
};
|
|
26783
27108
|
}
|
|
26784
27109
|
function cachedPiRowMatchesSnapshot(args) {
|
|
@@ -27559,162 +27884,6 @@ function registerPiGuardedContext(pi, handler) {
|
|
|
27559
27884
|
});
|
|
27560
27885
|
}
|
|
27561
27886
|
|
|
27562
|
-
// ../plugin/src/hooks/magic-context/lkg-persist.ts
|
|
27563
|
-
function parseStringArray(value) {
|
|
27564
|
-
if (typeof value !== "string")
|
|
27565
|
-
return null;
|
|
27566
|
-
let parsed;
|
|
27567
|
-
try {
|
|
27568
|
-
parsed = JSON.parse(value);
|
|
27569
|
-
} catch {
|
|
27570
|
-
return null;
|
|
27571
|
-
}
|
|
27572
|
-
if (!Array.isArray(parsed))
|
|
27573
|
-
return null;
|
|
27574
|
-
const result = [];
|
|
27575
|
-
for (const entry of parsed) {
|
|
27576
|
-
if (typeof entry !== "string" || entry.length === 0)
|
|
27577
|
-
return null;
|
|
27578
|
-
result.push(entry);
|
|
27579
|
-
}
|
|
27580
|
-
return result;
|
|
27581
|
-
}
|
|
27582
|
-
function parseNullableString(value) {
|
|
27583
|
-
if (value === null || value === undefined)
|
|
27584
|
-
return null;
|
|
27585
|
-
return typeof value === "string" ? value : undefined;
|
|
27586
|
-
}
|
|
27587
|
-
function parseNullableInteger(value) {
|
|
27588
|
-
if (value === null || value === undefined)
|
|
27589
|
-
return;
|
|
27590
|
-
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
27591
|
-
}
|
|
27592
|
-
function parsePersistedLkgSlot(row) {
|
|
27593
|
-
if (!row || typeof row !== "object")
|
|
27594
|
-
return;
|
|
27595
|
-
const record = row;
|
|
27596
|
-
const jsonPrefix = record.json_prefix;
|
|
27597
|
-
const lastInputMessageId = record.last_input_message_id;
|
|
27598
|
-
const capturedAt = record.captured_at;
|
|
27599
|
-
let inputIdsRaw = record.input_id_seq;
|
|
27600
|
-
let piOutputEntryIds;
|
|
27601
|
-
if (typeof inputIdsRaw === "string") {
|
|
27602
|
-
try {
|
|
27603
|
-
const metadata = JSON.parse(inputIdsRaw);
|
|
27604
|
-
if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
|
|
27605
|
-
if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
|
|
27606
|
-
return;
|
|
27607
|
-
piOutputEntryIds = metadata.piOutputEntryIds;
|
|
27608
|
-
inputIdsRaw = JSON.stringify(metadata.inputIds);
|
|
27609
|
-
}
|
|
27610
|
-
} catch {
|
|
27611
|
-
return;
|
|
27612
|
-
}
|
|
27613
|
-
}
|
|
27614
|
-
const inputIdSeq = parseStringArray(inputIdsRaw);
|
|
27615
|
-
const inputContentDigests = parseStringArray(record.input_content_digests);
|
|
27616
|
-
const modelKey = parseNullableString(record.model_key);
|
|
27617
|
-
const providerKey = parseNullableString(record.provider_key);
|
|
27618
|
-
if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
|
|
27619
|
-
return;
|
|
27620
|
-
}
|
|
27621
|
-
if (piOutputEntryIds) {
|
|
27622
|
-
try {
|
|
27623
|
-
const output = JSON.parse(jsonPrefix);
|
|
27624
|
-
const inputs = new Set(inputIdSeq);
|
|
27625
|
-
if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
|
|
27626
|
-
return;
|
|
27627
|
-
} catch {
|
|
27628
|
-
return;
|
|
27629
|
-
}
|
|
27630
|
-
}
|
|
27631
|
-
let inputContentSignatures;
|
|
27632
|
-
if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
|
|
27633
|
-
const parsed = parseStringArray(record.input_content_signatures);
|
|
27634
|
-
if (parsed === null || parsed.length !== inputIdSeq.length)
|
|
27635
|
-
return;
|
|
27636
|
-
inputContentSignatures = parsed;
|
|
27637
|
-
}
|
|
27638
|
-
const slot = {
|
|
27639
|
-
jsonPrefix,
|
|
27640
|
-
inputIdSeq,
|
|
27641
|
-
inputContentDigests,
|
|
27642
|
-
lastInputMessageId,
|
|
27643
|
-
modelKey,
|
|
27644
|
-
providerKey,
|
|
27645
|
-
capturedAt
|
|
27646
|
-
};
|
|
27647
|
-
if (inputContentSignatures)
|
|
27648
|
-
slot.inputContentSignatures = inputContentSignatures;
|
|
27649
|
-
if (piOutputEntryIds)
|
|
27650
|
-
slot.piOutputEntryIds = piOutputEntryIds;
|
|
27651
|
-
const rowVersion = parseNullableInteger(record.row_version);
|
|
27652
|
-
if (rowVersion !== undefined)
|
|
27653
|
-
slot.rowVersion = rowVersion;
|
|
27654
|
-
const captureSequence = parseNullableInteger(record.capture_sequence);
|
|
27655
|
-
if (captureSequence !== undefined)
|
|
27656
|
-
slot.captureSequence = captureSequence;
|
|
27657
|
-
return slot;
|
|
27658
|
-
}
|
|
27659
|
-
function saveLkgSlotToDb(db, sessionId, slot) {
|
|
27660
|
-
try {
|
|
27661
|
-
db.prepare(`INSERT INTO lkg_slots (
|
|
27662
|
-
session_id, json_prefix, input_id_seq, input_content_digests,
|
|
27663
|
-
input_content_signatures, last_input_message_id, model_key, provider_key,
|
|
27664
|
-
captured_at, row_version, capture_sequence
|
|
27665
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
27666
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
27667
|
-
json_prefix = excluded.json_prefix,
|
|
27668
|
-
input_id_seq = excluded.input_id_seq,
|
|
27669
|
-
input_content_digests = excluded.input_content_digests,
|
|
27670
|
-
input_content_signatures = excluded.input_content_signatures,
|
|
27671
|
-
last_input_message_id = excluded.last_input_message_id,
|
|
27672
|
-
model_key = excluded.model_key,
|
|
27673
|
-
provider_key = excluded.provider_key,
|
|
27674
|
-
captured_at = excluded.captured_at,
|
|
27675
|
-
row_version = excluded.row_version,
|
|
27676
|
-
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
|
|
27677
|
-
version: 1,
|
|
27678
|
-
inputIds: slot.inputIdSeq,
|
|
27679
|
-
piOutputEntryIds: slot.piOutputEntryIds
|
|
27680
|
-
} : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
|
|
27681
|
-
return true;
|
|
27682
|
-
} catch (error) {
|
|
27683
|
-
sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
|
|
27684
|
-
return false;
|
|
27685
|
-
}
|
|
27686
|
-
}
|
|
27687
|
-
function clearPersistedLkgSlot(db, sessionId) {
|
|
27688
|
-
try {
|
|
27689
|
-
db.prepare("DELETE FROM lkg_slots WHERE session_id = ?").run(sessionId);
|
|
27690
|
-
} catch (error) {
|
|
27691
|
-
sessionLog(sessionId, "LKG snapshot durable clear failed:", error);
|
|
27692
|
-
}
|
|
27693
|
-
}
|
|
27694
|
-
function loadPersistedLkgSlot(db, sessionId) {
|
|
27695
|
-
let row;
|
|
27696
|
-
try {
|
|
27697
|
-
row = db.prepare("SELECT * FROM lkg_slots WHERE session_id = ?").get(sessionId);
|
|
27698
|
-
} catch (error) {
|
|
27699
|
-
sessionLog(sessionId, "LKG snapshot durable load failed:", error);
|
|
27700
|
-
return;
|
|
27701
|
-
}
|
|
27702
|
-
if (!row)
|
|
27703
|
-
return;
|
|
27704
|
-
const slot = parsePersistedLkgSlot(row);
|
|
27705
|
-
if (!slot) {
|
|
27706
|
-
clearPersistedLkgSlot(db, sessionId);
|
|
27707
|
-
return;
|
|
27708
|
-
}
|
|
27709
|
-
return slot;
|
|
27710
|
-
}
|
|
27711
|
-
function createDbLkgPersistence(db) {
|
|
27712
|
-
return {
|
|
27713
|
-
load: (sessionId) => loadPersistedLkgSlot(db, sessionId),
|
|
27714
|
-
clear: (sessionId) => clearPersistedLkgSlot(db, sessionId)
|
|
27715
|
-
};
|
|
27716
|
-
}
|
|
27717
|
-
|
|
27718
27887
|
// ../plugin/src/hooks/magic-context/openai-compat-adjacency.ts
|
|
27719
27888
|
function assertOpenAiCompatAdjacency(messages) {
|
|
27720
27889
|
const violations = [];
|
|
@@ -29350,7 +29519,7 @@ function replayStrippedInlineThinkingPi(args) {
|
|
|
29350
29519
|
}
|
|
29351
29520
|
|
|
29352
29521
|
// src/served-array-ledger.ts
|
|
29353
|
-
import { createHash as
|
|
29522
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
29354
29523
|
import * as fs2 from "node:fs";
|
|
29355
29524
|
import * as path6 from "node:path";
|
|
29356
29525
|
var PI_SERVED_ARRAY_TAIL_MESSAGES = 40;
|
|
@@ -29365,7 +29534,7 @@ var flushTimer = null;
|
|
|
29365
29534
|
var swallowedWriteCount = 0;
|
|
29366
29535
|
var lastWriteError = null;
|
|
29367
29536
|
function sha256(value) {
|
|
29368
|
-
return
|
|
29537
|
+
return createHash13("sha256").update(value).digest("hex");
|
|
29369
29538
|
}
|
|
29370
29539
|
function safeSessionFileStem(sessionId) {
|
|
29371
29540
|
const readable = sessionId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 96);
|
|
@@ -29673,7 +29842,7 @@ function stripPiProcessedImages(args) {
|
|
|
29673
29842
|
}
|
|
29674
29843
|
|
|
29675
29844
|
// src/system-prompt.ts
|
|
29676
|
-
import { createHash as
|
|
29845
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
29677
29846
|
var MAGIC_CONTEXT_MARKER = "## Magic Context";
|
|
29678
29847
|
var stickyDateBySession = new Map;
|
|
29679
29848
|
function buildMagicContextBlock(opts) {
|
|
@@ -29704,7 +29873,7 @@ function processSystemPromptForCache(args) {
|
|
|
29704
29873
|
const liveDate = dateMatch ? dateMatch[0] : null;
|
|
29705
29874
|
const stickyDate = stickyDateBySession.get(sessionId);
|
|
29706
29875
|
const stableCandidate = liveDate && stickyDate && liveDate !== stickyDate ? systemPrompt.replace(DATE_PATTERN, stickyDate) : systemPrompt;
|
|
29707
|
-
const stableCandidateHash =
|
|
29876
|
+
const stableCandidateHash = createHash14("md5").update(promptSurfaceHashMaterial(stableCandidate, args.promptSurfacePreset)).digest("hex");
|
|
29708
29877
|
const contentOrPresetChanged = !isFirstHash && stableCandidateHash !== previousHash;
|
|
29709
29878
|
const dateMayAdvance = isCacheBusting || contentOrPresetChanged;
|
|
29710
29879
|
if (liveDate && !stickyDate) {
|
|
@@ -29718,7 +29887,7 @@ function processSystemPromptForCache(args) {
|
|
|
29718
29887
|
sessionLog(sessionId, `system prompt date frozen: real=${liveDate}, using=${stickyDate} (cache-stable pass)`);
|
|
29719
29888
|
}
|
|
29720
29889
|
}
|
|
29721
|
-
const currentHash =
|
|
29890
|
+
const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(frozenPrompt, args.promptSurfacePreset)).digest("hex");
|
|
29722
29891
|
const hashChanged = !isFirstHash && currentHash !== previousHash;
|
|
29723
29892
|
if (hashChanged) {
|
|
29724
29893
|
sessionLog(sessionId, `system prompt hash changed: ${previousHash} → ${currentHash} (len=${frozenPrompt.length})`);
|
|
@@ -30331,6 +30500,9 @@ function createPiToolResultPart(working, messageIndex, partIndex, markDirty) {
|
|
|
30331
30500
|
inputTokenCount: 0
|
|
30332
30501
|
};
|
|
30333
30502
|
},
|
|
30503
|
+
hasUserAnswer() {
|
|
30504
|
+
return hasUserAnswerMetadata(working[messageIndex].details);
|
|
30505
|
+
},
|
|
30334
30506
|
replaceWithSentinel(sentinelText) {
|
|
30335
30507
|
const current = working[messageIndex].content;
|
|
30336
30508
|
const newContent = current.slice();
|
|
@@ -31639,6 +31811,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
31639
31811
|
injection: options.injection ? {
|
|
31640
31812
|
...options.injection,
|
|
31641
31813
|
memoryEnabled: options.injection.memoryEnabled,
|
|
31814
|
+
historyBudgetPolicyIdentity: historyBudgetPolicyIdentity(options.historian?.historyBudgetPercentage, options.historian?.executeThresholdPercentage, liveModelBySession.get(sessionId), options.historian?.executeThresholdTokens),
|
|
31642
31815
|
historyBudgetTokens: resolveHistoryBudgetTokensForPi({
|
|
31643
31816
|
historyBudgetPercentage: options.historian?.historyBudgetPercentage,
|
|
31644
31817
|
usagePercentage,
|
|
@@ -32514,6 +32687,7 @@ async function runCompactionOffPipeline(args) {
|
|
|
32514
32687
|
injectDocs: args.injection.injectDocs,
|
|
32515
32688
|
injectionBudgetTokens: args.injection.injectionBudgetTokens,
|
|
32516
32689
|
historyBudgetTokens: args.injection.historyBudgetTokens,
|
|
32690
|
+
historyBudgetPolicyIdentity: args.injection.historyBudgetPolicyIdentity,
|
|
32517
32691
|
muralEnabled: args.injection.muralEnabled === true,
|
|
32518
32692
|
compactionOff: true
|
|
32519
32693
|
}, args.db, args.messages, args.entryIds, false, args.injectionPassSnapshot);
|
|
@@ -32632,6 +32806,7 @@ async function runPipeline(args) {
|
|
|
32632
32806
|
injectDocs: args.injection.injectDocs,
|
|
32633
32807
|
injectionBudgetTokens: args.injection.injectionBudgetTokens,
|
|
32634
32808
|
historyBudgetTokens: args.injection.historyBudgetTokens,
|
|
32809
|
+
historyBudgetPolicyIdentity: args.injection.historyBudgetPolicyIdentity,
|
|
32635
32810
|
hardSignals: piHardSignals,
|
|
32636
32811
|
muralEnabled: args.injection.muralEnabled === true,
|
|
32637
32812
|
freezePrefixForPass: true,
|
|
@@ -35816,7 +35991,7 @@ function buildStatusView(source, options) {
|
|
|
35816
35991
|
// package.json
|
|
35817
35992
|
var package_default = {
|
|
35818
35993
|
name: "@cortexkit/pi-magic-context",
|
|
35819
|
-
version: "0.44.
|
|
35994
|
+
version: "0.44.4",
|
|
35820
35995
|
type: "module",
|
|
35821
35996
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
35822
35997
|
main: "dist/index.js",
|
|
@@ -35864,7 +36039,6 @@ var package_default = {
|
|
|
35864
36039
|
"comment-json": "^5.0.0",
|
|
35865
36040
|
"onnxruntime-web": "1.26.0-dev.20260416-b7804b056c",
|
|
35866
36041
|
"quickjs-emscripten": "^0.32.0",
|
|
35867
|
-
typebox: "^1.3.1",
|
|
35868
36042
|
zod: "^4.1.8"
|
|
35869
36043
|
},
|
|
35870
36044
|
optionalDependencies: {
|
|
@@ -35884,11 +36058,13 @@ var package_default = {
|
|
|
35884
36058
|
"pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
|
|
35885
36059
|
"pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
|
|
35886
36060
|
"pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
|
|
36061
|
+
typebox: "^1.3.1",
|
|
35887
36062
|
typescript: "^5.8.0"
|
|
35888
36063
|
},
|
|
35889
36064
|
peerDependencies: {
|
|
35890
|
-
"@earendil-works/pi-coding-agent": "
|
|
35891
|
-
"@earendil-works/pi-tui": "
|
|
36065
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
36066
|
+
"@earendil-works/pi-tui": "*",
|
|
36067
|
+
typebox: "*"
|
|
35892
36068
|
},
|
|
35893
36069
|
peerDependenciesMeta: {
|
|
35894
36070
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -35896,6 +36072,9 @@ var package_default = {
|
|
|
35896
36072
|
},
|
|
35897
36073
|
"@earendil-works/pi-tui": {
|
|
35898
36074
|
optional: true
|
|
36075
|
+
},
|
|
36076
|
+
typebox: {
|
|
36077
|
+
optional: true
|
|
35899
36078
|
}
|
|
35900
36079
|
},
|
|
35901
36080
|
exports: {
|
|
@@ -37557,6 +37736,7 @@ async function src_default(pi) {
|
|
|
37557
37736
|
const bootProjectDir = process.cwd();
|
|
37558
37737
|
ensureConfigLocationsMigrated(bootProjectDir);
|
|
37559
37738
|
const bootConfig = loadPiConfig({ cwd: bootProjectDir });
|
|
37739
|
+
setHomeProjectPermission(bootConfig.config.allow_home_project);
|
|
37560
37740
|
if (!bootConfig.config.enabled) {
|
|
37561
37741
|
info("plugin DISABLED via config (enabled: false) — skipping registration");
|
|
37562
37742
|
return;
|