@retaw106/mmc-oc 2.5.0 → 2.7.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/{context-xx09sh1g.js → context-9q17e52a.js} +553 -214
- package/dist/features/magic-context/auto-search-diagnostics.d.ts +27 -0
- package/dist/features/magic-context/auto-search-diagnostics.d.ts.map +1 -0
- package/dist/features/magic-context/compaction-marker.d.ts +34 -6
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +1 -24
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +4 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -1
- package/dist/features/magic-context/session-retention.fixture.d.ts +4 -0
- package/dist/features/magic-context/session-retention.fixture.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts +21 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-native-replay.d.ts +2 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +4 -11
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +113 -58
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/work-metrics.d.ts +5 -3
- package/dist/features/magic-context/work-metrics.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +32 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/ask-answer-notice.d.ts +25 -0
- package/dist/hooks/magic-context/ask-answer-notice.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-observation.d.ts +13 -0
- package/dist/hooks/magic-context/auto-search-observation.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts +14 -0
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +11 -3
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-history-wait.d.ts +16 -0
- package/dist/hooks/magic-context/historian-history-wait.d.ts.map +1 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts +1 -1
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +2 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +8 -2
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +20 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts +42 -0
- package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +2 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-bpjjcdy9.js → index-8rmt6s4f.js} +77 -31
- package/dist/{index-mjf0p7yq.js → index-cgjyhwdk.js} +1 -1
- package/dist/{index-k25thxq7.js → index-s3ebcy63.js} +1 -1
- package/dist/{index-1vxffj5j.js → index-t0zx3tgz.js} +408 -89
- package/dist/{index-0d40b4q8.js → index-xrxpbe74.js} +9355 -9215
- package/dist/index.js +14 -4
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-eb3fy45y.js → read-session-chunk-2s8x6xps.js} +2 -2
- package/dist/{recomp-orchestrator-mmpy5cb7.js → recomp-orchestrator-gzd1at06.js} +5 -5
- package/dist/{send-session-notification-zpqs213d.js → send-session-notification-vdppp5x6.js} +2 -2
- package/dist/shared/search-text.d.ts +2 -0
- package/dist/shared/search-text.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts +2 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +3 -1
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts +5 -3
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts +2 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +10 -10
- package/dist/tools/parameter-descriptions.d.ts.map +1 -1
- package/dist/tui.js +2144 -0
- package/dist/v2/hooks/context.d.ts +5 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/message-times.d.ts +17 -0
- package/dist/v2/message-times.d.ts.map +1 -0
- package/dist/v2/server.js +11211 -10345
- package/dist/v2/store-reader.d.ts +14 -4
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/tui/client.d.ts +57 -0
- package/dist/v2/tui/client.d.ts.map +1 -0
- package/dist/v2/tui/context-rpc.d.ts +63 -0
- package/dist/v2/tui/context-rpc.d.ts.map +1 -0
- package/dist/v2/tui/entry.d.ts +8 -0
- package/dist/v2/tui/entry.d.ts.map +1 -0
- package/dist/v2/tui/notification-socket.d.ts +26 -0
- package/dist/v2/tui/notification-socket.d.ts.map +1 -0
- package/dist/v2/tui/session-directory.d.ts +22 -0
- package/dist/v2/tui/session-directory.d.ts.map +1 -0
- package/dist/v2/tui/types.d.ts +110 -0
- package/dist/v2/tui/types.d.ts.map +1 -0
- package/dist/web/main.js +85 -11
- package/dist/{wrapup-orchestrator-jq589pgr.js → wrapup-orchestrator-ghq4y406.js} +5 -5
- package/package.json +13 -3
- package/src/config/latch-permanence-guard.test.ts +0 -5
- package/src/shared/prompt-surface-a1-golden.md +8 -9
- package/src/shared/search-text.test.ts +36 -1
- package/src/shared/search-text.ts +48 -0
- package/src/shared/sqlite-transaction-mode-guard.test.ts +2 -0
- package/src/shared/tag-transcript.ts +47 -4
- package/src/shared/transcript.ts +1 -1
- package/src/shared/write-transaction-attribution.test.ts +1 -6
- package/tui.js +4 -0
- package/dist/features/magic-context/message-index-sweep.d.ts +0 -11
- package/dist/features/magic-context/message-index-sweep.d.ts.map +0 -1
|
@@ -71,21 +71,10 @@ import {
|
|
|
71
71
|
searchMemoriesFTSUnion,
|
|
72
72
|
clearMemoryVerifications,
|
|
73
73
|
queueMemoryMutation,
|
|
74
|
-
|
|
75
|
-
registerOwnRpcServerInstance,
|
|
76
|
-
rpcPortDir,
|
|
77
|
-
rpcPortFilePath,
|
|
78
|
-
parseRpcPortFile,
|
|
79
|
-
inspectProcessesAsync,
|
|
80
|
-
dirtyLkgRecoveryRevision,
|
|
81
|
-
ownsLkgDirtyFence,
|
|
82
|
-
invalidateCleanLkgRecoveryFence,
|
|
74
|
+
scheduleAfterBootQuiet,
|
|
83
75
|
cleanSearchText,
|
|
84
|
-
|
|
76
|
+
hintKeywordRelevance,
|
|
85
77
|
matchedSearchSnippet,
|
|
86
|
-
gaDatabasePath,
|
|
87
|
-
RAW_MESSAGE_TYPES,
|
|
88
|
-
V2StoreReaderPool,
|
|
89
78
|
getLastIndexedOrdinal,
|
|
90
79
|
getIndexedMessageIdAtOrdinal,
|
|
91
80
|
getIndexedMessageCorpusSize,
|
|
@@ -93,8 +82,11 @@ import {
|
|
|
93
82
|
isMessageIndexReconciledThrough,
|
|
94
83
|
clearIndexedMessages,
|
|
95
84
|
indexMessagesAfterOrdinal,
|
|
96
|
-
|
|
97
|
-
|
|
85
|
+
registerOwnRpcServerInstance,
|
|
86
|
+
rpcPortDir,
|
|
87
|
+
rpcPortFilePath,
|
|
88
|
+
parseRpcPortFile,
|
|
89
|
+
inspectProcessesAsync,
|
|
98
90
|
acquireCompartmentLease,
|
|
99
91
|
releaseCompartmentLeaseBestEffort,
|
|
100
92
|
isCompartmentLeaseHeld,
|
|
@@ -103,7 +95,7 @@ import {
|
|
|
103
95
|
ensureSessionMetaRow,
|
|
104
96
|
clearCachedM0M1,
|
|
105
97
|
clearCachedM0,
|
|
106
|
-
|
|
98
|
+
getTableColumnNames,
|
|
107
99
|
getLastCompartmentEndMessage,
|
|
108
100
|
getLastCompartmentEndMessageId,
|
|
109
101
|
getAuthorityManagedMarker,
|
|
@@ -163,6 +155,7 @@ import {
|
|
|
163
155
|
clearEmergencyRecovery,
|
|
164
156
|
clearDetectedContextLimit,
|
|
165
157
|
getPersistedCompactionMarkerState,
|
|
158
|
+
clearCompactionMarkerPublicationIntent,
|
|
166
159
|
setPersistedCompactionMarkerState,
|
|
167
160
|
getDeferredClearedCompactionMarkerState,
|
|
168
161
|
retireDeferredClearedCompactionMarkerState,
|
|
@@ -191,10 +184,16 @@ import {
|
|
|
191
184
|
resolveEpochFloorForPass,
|
|
192
185
|
providerResponseFailed,
|
|
193
186
|
isSuccessfulProviderCompletion,
|
|
187
|
+
dirtyLkgRecoveryRevision,
|
|
188
|
+
ownsLkgDirtyFence,
|
|
189
|
+
invalidateCleanLkgRecoveryFence,
|
|
194
190
|
rememberUnpublishedAutoSearchNoHint,
|
|
195
191
|
getUnpublishedAutoSearchNoHint,
|
|
196
192
|
forgetUnpublishedAutoSearchNoHint,
|
|
197
193
|
registerAutoSearchWork,
|
|
194
|
+
gaDatabasePath,
|
|
195
|
+
RAW_MESSAGE_TYPES,
|
|
196
|
+
V2StoreReaderPool,
|
|
198
197
|
getOrCreateSessionMeta,
|
|
199
198
|
updateSessionMeta,
|
|
200
199
|
advanceToolReclaimWatermark,
|
|
@@ -226,6 +225,7 @@ import {
|
|
|
226
225
|
lkgDirtyRevision,
|
|
227
226
|
readLkgRecoveryPrefix,
|
|
228
227
|
noteLkgHealthyPrefix,
|
|
228
|
+
lkgInputIdentity,
|
|
229
229
|
beginLkgPass,
|
|
230
230
|
getInMemorySlot,
|
|
231
231
|
getSlot,
|
|
@@ -277,6 +277,7 @@ import {
|
|
|
277
277
|
HISTORIAN_RECOMP_AGENT,
|
|
278
278
|
HISTORIAN_EDITOR_AGENT,
|
|
279
279
|
runTokenLog,
|
|
280
|
+
shouldWaitForNewHistorianHistory,
|
|
280
281
|
extractM0Block,
|
|
281
282
|
TEMPORAL_MARKER_REPLAY_PATTERN,
|
|
282
283
|
collectTemporalCandidates,
|
|
@@ -307,7 +308,7 @@ import {
|
|
|
307
308
|
recordHighPressureNoEligibleHead,
|
|
308
309
|
getActiveCompartmentRun,
|
|
309
310
|
startCompartmentAgent
|
|
310
|
-
} from "./index-
|
|
311
|
+
} from "./index-xrxpbe74.js";
|
|
311
312
|
import {
|
|
312
313
|
getHarness,
|
|
313
314
|
getDataDir,
|
|
@@ -450,8 +451,9 @@ import {
|
|
|
450
451
|
createDroppedInputGuard,
|
|
451
452
|
assertExecutableToolInput,
|
|
452
453
|
isEditTool,
|
|
454
|
+
BoundedSessionMap,
|
|
455
|
+
recordToolDefinitionSet,
|
|
453
456
|
getCurrentToolSetHash,
|
|
454
|
-
recordToolDefinition,
|
|
455
457
|
getMeasuredToolDefinitionTokens,
|
|
456
458
|
describeFinalWireTail,
|
|
457
459
|
estimatePartImageTokens,
|
|
@@ -487,13 +489,12 @@ import {
|
|
|
487
489
|
hasRawSessionMessageById2,
|
|
488
490
|
readRawSessionMessageById2,
|
|
489
491
|
readSessionChunk2
|
|
490
|
-
} from "./index-
|
|
492
|
+
} from "./index-t0zx3tgz.js";
|
|
491
493
|
import {
|
|
492
494
|
normalizeModelEntry2,
|
|
493
495
|
resolveHistorianModel2
|
|
494
496
|
} from "./index-azbmnekv.js";
|
|
495
497
|
import {
|
|
496
|
-
Database,
|
|
497
498
|
getSqliteMemoryStats,
|
|
498
499
|
withSqliteBackgroundWriter,
|
|
499
500
|
withSqliteTransformPass,
|
|
@@ -520,7 +521,7 @@ import {
|
|
|
520
521
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
521
522
|
getMessageTimesFromOpenCodeDb,
|
|
522
523
|
findLastAssistantModelFromOpenCodeDb
|
|
523
|
-
} from "./index-
|
|
524
|
+
} from "./index-8rmt6s4f.js";
|
|
524
525
|
import {
|
|
525
526
|
registerNotificationSink2,
|
|
526
527
|
pushNotification2,
|
|
@@ -533,7 +534,7 @@ import {
|
|
|
533
534
|
getErrorMessage,
|
|
534
535
|
flushIgnoredMessages2,
|
|
535
536
|
sendStatusNotification2
|
|
536
|
-
} from "./index-
|
|
537
|
+
} from "./index-s3ebcy63.js";
|
|
537
538
|
import {
|
|
538
539
|
logSlowWriteTransaction
|
|
539
540
|
} from "./index-yjv8dpht.js";
|
|
@@ -6371,6 +6372,26 @@ class EmergencyFailClosedError extends Error {
|
|
|
6371
6372
|
}
|
|
6372
6373
|
|
|
6373
6374
|
// src/hooks/magic-context/history-boundary-repair.ts
|
|
6375
|
+
function readStoreBoundaries(db, sessionId) {
|
|
6376
|
+
const columns = getTableColumnNames(db, "compartments");
|
|
6377
|
+
const numbers = ["id", "sequence", "start_message", "end_message", "created_at"];
|
|
6378
|
+
const strings = ["session_id", "start_message_id", "end_message_id", "title", "content"];
|
|
6379
|
+
const predicates = [...numbers, ...strings].every((column) => columns.has(column)) ? [
|
|
6380
|
+
...numbers.map((column) => `typeof(${column}) IN ('integer', 'real')`),
|
|
6381
|
+
...strings.map((column) => `typeof(${column}) = 'text'`)
|
|
6382
|
+
] : ["0"];
|
|
6383
|
+
for (const column of ["p1", "p2", "p3", "p4", "episode_type"]) {
|
|
6384
|
+
if (columns.has(column))
|
|
6385
|
+
predicates.push(`typeof(${column}) IN ('text', 'null')`);
|
|
6386
|
+
}
|
|
6387
|
+
for (const column of ["importance", "legacy"]) {
|
|
6388
|
+
if (columns.has(column))
|
|
6389
|
+
predicates.push(`typeof(${column}) IN ('integer', 'real', 'null')`);
|
|
6390
|
+
}
|
|
6391
|
+
return db.prepare(`SELECT sequence, ${columns.has("end_message_id") ? "end_message_id" : "NULL"} AS endMessageId
|
|
6392
|
+
FROM compartments WHERE session_id = ? AND ${predicates.join(" AND ")}
|
|
6393
|
+
ORDER BY sequence ASC`).all(sessionId);
|
|
6394
|
+
}
|
|
6374
6395
|
function readBaseline(db, sessionId) {
|
|
6375
6396
|
const row = db.prepare("SELECT cached_m0_bytes IS NOT NULL AS hasM0, cached_m0_last_baseline_end_message_id AS boundary FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
6376
6397
|
return {
|
|
@@ -6436,7 +6457,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
|
|
|
6436
6457
|
}
|
|
6437
6458
|
function repairMissingHistoryBoundary(args) {
|
|
6438
6459
|
const { db, sessionId, isInHostStore, scope = "store" } = args;
|
|
6439
|
-
const compartments = scope === "active-branch" ? db.prepare("SELECT sequence, COALESCE(end_message_id, '') AS endMessageId FROM compartments WHERE session_id = ? ORDER BY sequence").all(sessionId) :
|
|
6460
|
+
const compartments = scope === "active-branch" ? db.prepare("SELECT sequence, COALESCE(end_message_id, '') AS endMessageId FROM compartments WHERE session_id = ? ORDER BY sequence").all(sessionId) : readStoreBoundaries(db, sessionId);
|
|
6440
6461
|
let latestIndex = compartments.length - 1;
|
|
6441
6462
|
while (latestIndex >= 0 && !compartments[latestIndex]?.endMessageId)
|
|
6442
6463
|
latestIndex -= 1;
|
|
@@ -6480,7 +6501,7 @@ function repairMissingHistoryBoundary(args) {
|
|
|
6480
6501
|
let dropped;
|
|
6481
6502
|
let anchorForDrop = anchor;
|
|
6482
6503
|
try {
|
|
6483
|
-
if (
|
|
6504
|
+
if (anchor) {
|
|
6484
6505
|
const row = db.prepare("SELECT end_message AS endMessage FROM compartments WHERE session_id = ? AND sequence = ?").get(sessionId, anchor.sequence);
|
|
6485
6506
|
if (!row)
|
|
6486
6507
|
return { kind: "unresolved", reason: "busy", missingEndMessageId: missing };
|
|
@@ -6571,6 +6592,38 @@ function seedSessionCacheTtlIfUnsynced(args) {
|
|
|
6571
6592
|
return true;
|
|
6572
6593
|
}
|
|
6573
6594
|
|
|
6595
|
+
// src/features/magic-context/auto-search-diagnostics.ts
|
|
6596
|
+
var memoryHintContent = new WeakMap;
|
|
6597
|
+
function withMemoryHintContent(result, fullContent) {
|
|
6598
|
+
memoryHintContent.set(result, fullContent);
|
|
6599
|
+
return result;
|
|
6600
|
+
}
|
|
6601
|
+
function createAutoSearchDiagnostics(threshold) {
|
|
6602
|
+
return {
|
|
6603
|
+
threshold,
|
|
6604
|
+
lanes: {},
|
|
6605
|
+
pool: "unknown",
|
|
6606
|
+
poolRows: null,
|
|
6607
|
+
peek: "not-run",
|
|
6608
|
+
workerStarted: false
|
|
6609
|
+
};
|
|
6610
|
+
}
|
|
6611
|
+
function autoSearchRelevance(query, result) {
|
|
6612
|
+
const content = result.source === "memory" ? memoryHintContent.get(result) ?? result.content : result.content;
|
|
6613
|
+
if (cleanSearchText(content).length === 0)
|
|
6614
|
+
return 0;
|
|
6615
|
+
return result.source === "message" || "matchType" in result ? hintKeywordRelevance(query, content) : result.score;
|
|
6616
|
+
}
|
|
6617
|
+
function recordAutoSearchLane(diagnostics, lane, query, results) {
|
|
6618
|
+
if (!diagnostics)
|
|
6619
|
+
return;
|
|
6620
|
+
const scores = results.map((result) => result.relevanceScore ?? autoSearchRelevance(query, result));
|
|
6621
|
+
diagnostics.lanes[lane] = {
|
|
6622
|
+
top: scores.length ? Math.max(...scores) : null,
|
|
6623
|
+
nearMisses: scores.filter((score) => score >= 0.5 && score < diagnostics.threshold).length
|
|
6624
|
+
};
|
|
6625
|
+
}
|
|
6626
|
+
|
|
6574
6627
|
// src/features/magic-context/literal-probes.ts
|
|
6575
6628
|
var MAX_PROBES = 5;
|
|
6576
6629
|
var MIN_PROBE_LENGTH = 3;
|
|
@@ -7043,7 +7096,7 @@ function mergeMemoryResults(args) {
|
|
|
7043
7096
|
suppressedVisibleIds.push(id);
|
|
7044
7097
|
continue;
|
|
7045
7098
|
}
|
|
7046
|
-
results.push({
|
|
7099
|
+
results.push(withMemoryHintContent({
|
|
7047
7100
|
source: "memory",
|
|
7048
7101
|
content: previewText(memory.content),
|
|
7049
7102
|
score,
|
|
@@ -7051,7 +7104,7 @@ function mergeMemoryResults(args) {
|
|
|
7051
7104
|
category: memory.category,
|
|
7052
7105
|
matchType: "fts",
|
|
7053
7106
|
sourceName: args.sourceNameByMemoryId?.get(memory.id)
|
|
7054
|
-
});
|
|
7107
|
+
}, memory.content));
|
|
7055
7108
|
}
|
|
7056
7109
|
return {
|
|
7057
7110
|
results: results.sort((left, right) => {
|
|
@@ -7648,8 +7701,12 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
7648
7701
|
options.diagnostics.suppressedLiveMessageMatches = outcome.suppressedLiveMessageMatches;
|
|
7649
7702
|
}
|
|
7650
7703
|
messageResults = outcome.results.filter((result) => result.messageId !== options.excludeMessageId);
|
|
7704
|
+
recordAutoSearchLane(options.autoSearchDiagnostics, "messages", trimmedQuery, messageResults);
|
|
7705
|
+
options.onAutoSearchDiagnostics?.();
|
|
7651
7706
|
}
|
|
7652
7707
|
const workspace = resolveSearchWorkspaceContext(db, projectPath);
|
|
7708
|
+
if (options.autoSearchDiagnostics)
|
|
7709
|
+
options.autoSearchDiagnostics.pool = "off";
|
|
7653
7710
|
const [memoryOutcome, primerResults, noteResults] = await Promise.all([
|
|
7654
7711
|
runMemory ? searchMemories({
|
|
7655
7712
|
db,
|
|
@@ -7684,6 +7741,10 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
7684
7741
|
if (options.diagnostics) {
|
|
7685
7742
|
options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
|
|
7686
7743
|
}
|
|
7744
|
+
recordAutoSearchLane(options.autoSearchDiagnostics, "memory", trimmedQuery, memoryOutcome.results);
|
|
7745
|
+
recordAutoSearchLane(options.autoSearchDiagnostics, "primers", trimmedQuery, primerResults);
|
|
7746
|
+
recordAutoSearchLane(options.autoSearchDiagnostics, "notes", trimmedQuery, noteResults);
|
|
7747
|
+
options.onAutoSearchDiagnostics?.();
|
|
7687
7748
|
const results = [...memoryOutcome.results, ...primerResults, ...messageResults, ...noteResults].sort(compareUnifiedResults).slice(0, limit);
|
|
7688
7749
|
const countRetrievals = options.countRetrievals ?? true;
|
|
7689
7750
|
if (countRetrievals) {
|
|
@@ -7705,7 +7766,7 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
7705
7766
|
if (options.autoHint) {
|
|
7706
7767
|
return results.map((result) => ({
|
|
7707
7768
|
...result,
|
|
7708
|
-
relevanceScore:
|
|
7769
|
+
relevanceScore: autoSearchRelevance(trimmedQuery, result)
|
|
7709
7770
|
}));
|
|
7710
7771
|
}
|
|
7711
7772
|
return results;
|
|
@@ -8381,6 +8442,32 @@ function selectAutoSearchResults(results, threshold) {
|
|
|
8381
8442
|
return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
|
|
8382
8443
|
}
|
|
8383
8444
|
|
|
8445
|
+
// src/hooks/magic-context/auto-search-observation.ts
|
|
8446
|
+
var disabledTurns = new WeakMap;
|
|
8447
|
+
function logDisabledAutoSearch(db, sessionId, messageId, threshold, startedAt) {
|
|
8448
|
+
const sessions = disabledTurns.get(db) ?? new Map;
|
|
8449
|
+
disabledTurns.set(db, sessions);
|
|
8450
|
+
if (sessions.get(sessionId) === messageId)
|
|
8451
|
+
return;
|
|
8452
|
+
sessions.set(sessionId, messageId);
|
|
8453
|
+
observeAutoSearch(sessionId, threshold, startedAt).finish("disabled");
|
|
8454
|
+
}
|
|
8455
|
+
function observeAutoSearch(sessionId, threshold, startedAt) {
|
|
8456
|
+
const diagnostics = createAutoSearchDiagnostics(threshold);
|
|
8457
|
+
let logged = false;
|
|
8458
|
+
return {
|
|
8459
|
+
diagnostics,
|
|
8460
|
+
finish(outcome, reason) {
|
|
8461
|
+
if (logged)
|
|
8462
|
+
return;
|
|
8463
|
+
logged = true;
|
|
8464
|
+
const lanes = Object.entries(diagnostics.lanes).map(([lane, value]) => `${lane}:${value.top?.toFixed(3) ?? "none"}`).join(",");
|
|
8465
|
+
const nearMisses = Object.values(diagnostics.lanes).reduce((sum, lane) => sum + lane.nearMisses, 0);
|
|
8466
|
+
sessionLog(sessionId, `auto-search: decision outcome=${outcome}${reason ? ` reason=${reason}` : ""} lanes=${lanes || "none"} nearMisses=${nearMisses} threshold=${threshold} pool=${diagnostics.pool} rows=${diagnostics.poolRows ?? "unknown"} workerStarted=${diagnostics.workerStarted ?? "unknown"} peek=${diagnostics.peek} elapsedMs=${Math.round(performance.now() - startedAt)}`);
|
|
8467
|
+
}
|
|
8468
|
+
};
|
|
8469
|
+
}
|
|
8470
|
+
|
|
8384
8471
|
// src/hooks/magic-context/transform-message-helpers.ts
|
|
8385
8472
|
function isMeaningfulUserMessage(msg) {
|
|
8386
8473
|
return msg.info.role === "user" && hasMeaningfulUserText2(msg.parts);
|
|
@@ -8571,8 +8658,12 @@ async function coalesceAutoSearchTurn(db, sessionId, messageId, operation, repla
|
|
|
8571
8658
|
async function runAutoSearchHint(args) {
|
|
8572
8659
|
const startedAt = performance.now();
|
|
8573
8660
|
const { sessionId, db, messages, options } = args;
|
|
8574
|
-
if (!options.enabled)
|
|
8661
|
+
if (!options.enabled) {
|
|
8662
|
+
const tail = findLatestMeaningfulUserMessage(messages);
|
|
8663
|
+
if (tail && typeof tail.info.id === "string" && messages.at(-1) === tail)
|
|
8664
|
+
logDisabledAutoSearch(db, sessionId, tail.info.id, options.scoreThreshold, startedAt);
|
|
8575
8665
|
return AUTO_SEARCH_OK;
|
|
8666
|
+
}
|
|
8576
8667
|
const userMsg = findLatestMeaningfulUserMessage(messages);
|
|
8577
8668
|
if (!userMsg || typeof userMsg.info.id !== "string")
|
|
8578
8669
|
return AUTO_SEARCH_OK;
|
|
@@ -8615,6 +8706,7 @@ async function runAutoSearchHint(args) {
|
|
|
8615
8706
|
} catch {}
|
|
8616
8707
|
return AUTO_SEARCH_OK;
|
|
8617
8708
|
}
|
|
8709
|
+
const observation = observeAutoSearch(sessionId, options.scoreThreshold, startedAt);
|
|
8618
8710
|
const writeNoHintAndReconcile = (reason) => {
|
|
8619
8711
|
let outcome;
|
|
8620
8712
|
try {
|
|
@@ -8626,20 +8718,23 @@ async function runAutoSearchHint(args) {
|
|
|
8626
8718
|
} catch (error) {
|
|
8627
8719
|
if (isTransientSqliteError(error)) {
|
|
8628
8720
|
rememberUnpublishedAutoSearchNoHint(sessionId, userMsgId, reason);
|
|
8721
|
+
observation.finish("error", "storage-busy");
|
|
8629
8722
|
return { ok: false, kind: "storage-busy" };
|
|
8630
8723
|
}
|
|
8631
8724
|
throw error;
|
|
8632
8725
|
}
|
|
8633
|
-
if (!outcome.ok)
|
|
8726
|
+
if (!outcome.ok) {
|
|
8727
|
+
observation.finish("error", "cas-exhausted");
|
|
8634
8728
|
return { ok: false, kind: "cas-exhaustion" };
|
|
8729
|
+
}
|
|
8635
8730
|
if (outcome.kind === "already-present" && outcome.decision.decision === "hint") {
|
|
8636
8731
|
appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
|
|
8637
8732
|
}
|
|
8733
|
+
observation.finish(outcome.decision.decision === "hint" ? "attached" : reason === "below-threshold" ? "below-threshold" : reason === "error" ? "error" : "no-candidates", reason);
|
|
8638
8734
|
return AUTO_SEARCH_OK;
|
|
8639
8735
|
};
|
|
8640
8736
|
const rawPartsText = collectUserPromptParts(userMsg);
|
|
8641
8737
|
if (hasStackedAugmentation(rawPartsText)) {
|
|
8642
|
-
sessionLog(sessionId, "auto-search: skipping — user message already carries augmentation/hint");
|
|
8643
8738
|
return writeNoHintAndReconcile("stacked");
|
|
8644
8739
|
}
|
|
8645
8740
|
const rawPrompt = extractUserPromptText(userMsg);
|
|
@@ -8655,6 +8750,7 @@ async function runAutoSearchHint(args) {
|
|
|
8655
8750
|
if (checkDeadline())
|
|
8656
8751
|
return null;
|
|
8657
8752
|
const searchOptions = {
|
|
8753
|
+
autoSearchDiagnostics: observation.diagnostics,
|
|
8658
8754
|
limit: 10,
|
|
8659
8755
|
autoHint: true,
|
|
8660
8756
|
maxMessageOrdinal: Math.max(0, getLastCompartmentEndMessage(db, sessionId)),
|
|
@@ -8668,16 +8764,15 @@ async function runAutoSearchHint(args) {
|
|
|
8668
8764
|
countRetrievals: false
|
|
8669
8765
|
});
|
|
8670
8766
|
}, startedAt);
|
|
8671
|
-
} catch
|
|
8767
|
+
} catch {
|
|
8672
8768
|
if (lifecycleSignal.aborted)
|
|
8673
8769
|
return AUTO_SEARCH_OK;
|
|
8674
|
-
log(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
|
|
8675
8770
|
const outcome = writeNoHintAndReconcile("error");
|
|
8676
8771
|
return outcome.ok ? { ok: false, kind: "search-failure" } : outcome;
|
|
8677
8772
|
}
|
|
8678
8773
|
if (results === null) {
|
|
8679
8774
|
persistAutoSearchSkip(db, sessionId, userMsgId, "timeout");
|
|
8680
|
-
|
|
8775
|
+
observation.finish("timeout");
|
|
8681
8776
|
return { ok: false, kind: "timeout" };
|
|
8682
8777
|
}
|
|
8683
8778
|
if (results.length === 0) {
|
|
@@ -8685,7 +8780,6 @@ async function runAutoSearchHint(args) {
|
|
|
8685
8780
|
}
|
|
8686
8781
|
results = selectAutoSearchResults(results, options.scoreThreshold);
|
|
8687
8782
|
if (results.length === 0) {
|
|
8688
|
-
sessionLog(sessionId, `auto-search: no fragment meets relevance threshold ${options.scoreThreshold}`);
|
|
8689
8783
|
return writeNoHintAndReconcile("below-threshold");
|
|
8690
8784
|
}
|
|
8691
8785
|
const hintText = buildAutoSearchHint(results, {
|
|
@@ -8704,13 +8798,13 @@ ${hintText}`;
|
|
|
8704
8798
|
text: payload
|
|
8705
8799
|
});
|
|
8706
8800
|
if (!outcome.ok) {
|
|
8707
|
-
|
|
8801
|
+
observation.finish("error", "cas-exhausted");
|
|
8708
8802
|
return { ok: false, kind: "cas-exhaustion" };
|
|
8709
8803
|
}
|
|
8710
8804
|
if (outcome.decision.decision === "hint") {
|
|
8711
8805
|
appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
|
|
8712
8806
|
}
|
|
8713
|
-
|
|
8807
|
+
observation.finish(outcome.decision.decision === "hint" ? "attached" : "no-candidates");
|
|
8714
8808
|
return AUTO_SEARCH_OK;
|
|
8715
8809
|
}, replayServedDecision);
|
|
8716
8810
|
}
|
|
@@ -11363,6 +11457,8 @@ function reconcileCompactionMode(args) {
|
|
|
11363
11457
|
return NO_TRANSITION;
|
|
11364
11458
|
if (stored === "off_cleanup_pending") {
|
|
11365
11459
|
const markerCleanup = (args.cleanupMarkers ?? cleanupOffMarkers)(sessionId);
|
|
11460
|
+
if (markerCleanup.verified)
|
|
11461
|
+
clearCompactionMarkerPublicationIntent(db, sessionId);
|
|
11366
11462
|
return {
|
|
11367
11463
|
...NO_TRANSITION,
|
|
11368
11464
|
recordToWrite: markerCleanup.verified ? "off" : null,
|
|
@@ -11377,7 +11473,9 @@ function reconcileCompactionMode(args) {
|
|
|
11377
11473
|
if (markerCleanup.removedRows > 0)
|
|
11378
11474
|
clearedSomething = true;
|
|
11379
11475
|
if (getPersistedCompactionMarkerState(db, sessionId) !== null) {
|
|
11380
|
-
setPersistedCompactionMarkerState(db, sessionId, null
|
|
11476
|
+
setPersistedCompactionMarkerState(db, sessionId, null, {
|
|
11477
|
+
preservePending: !markerCleanup.verified
|
|
11478
|
+
});
|
|
11381
11479
|
clearedSomething = true;
|
|
11382
11480
|
}
|
|
11383
11481
|
const pendingMarker = getPendingCompactionMarkerState(db, sessionId);
|
|
@@ -11920,6 +12018,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
11920
12018
|
}
|
|
11921
12019
|
return { shouldFire: false };
|
|
11922
12020
|
}
|
|
12021
|
+
if (tailInfo.boundarySnapshot && shouldWaitForNewHistorianHistory(tailInfo.boundarySnapshot, {
|
|
12022
|
+
usagePercentage: usage.percentage,
|
|
12023
|
+
emergency: getOverflowState(db, sessionId).needsEmergencyRecovery
|
|
12024
|
+
})) {
|
|
12025
|
+
sessionLog(sessionId, "compartment trigger: waiting for new history after no forward progress");
|
|
12026
|
+
return { shouldFire: false };
|
|
12027
|
+
}
|
|
11923
12028
|
const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
|
|
11924
12029
|
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
|
|
11925
12030
|
const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
|
|
@@ -12104,6 +12209,27 @@ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, execu
|
|
|
12104
12209
|
}) / 100) * historyBudgetPercentage);
|
|
12105
12210
|
}
|
|
12106
12211
|
|
|
12212
|
+
// src/hooks/magic-context/signed-thinking-fit-snapshot.ts
|
|
12213
|
+
function takeSignedThinkingFitSnapshot(args) {
|
|
12214
|
+
let snapshot = null;
|
|
12215
|
+
if (args.held && !args.compactionOff) {
|
|
12216
|
+
try {
|
|
12217
|
+
snapshot = cloneKeepingCoveredInstructionMarks(args.entryOrder);
|
|
12218
|
+
} catch (error) {
|
|
12219
|
+
sessionLog(args.sessionId, `signed thinking fit: could not copy the pass input (${error instanceof Error ? error.message : String(error)}); an over-window held request will be refused rather than retried`);
|
|
12220
|
+
}
|
|
12221
|
+
}
|
|
12222
|
+
snapshotObserver?.({
|
|
12223
|
+
sessionId: args.sessionId,
|
|
12224
|
+
held: args.held,
|
|
12225
|
+
activeAnthropicThinkingTurn: args.activeAnthropicThinkingTurn,
|
|
12226
|
+
compactionOff: args.compactionOff,
|
|
12227
|
+
snapshot
|
|
12228
|
+
});
|
|
12229
|
+
return snapshot;
|
|
12230
|
+
}
|
|
12231
|
+
var snapshotObserver;
|
|
12232
|
+
|
|
12107
12233
|
// src/hooks/magic-context/temporal-served-projection.ts
|
|
12108
12234
|
function readLkgTemporalDecisions(db, sessionId, runtime) {
|
|
12109
12235
|
const slot = getInMemorySlot(sessionId) ?? loadPersistedLkgSlot(db, sessionId);
|
|
@@ -12601,6 +12727,14 @@ var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
|
12601
12727
|
function buildReplacementContent(tagId) {
|
|
12602
12728
|
return `[dropped §${tagId}§]`;
|
|
12603
12729
|
}
|
|
12730
|
+
var FROZEN_TEXT_ANNOTATION_SUFFIX = /(?:\n\n(?:<instruction name="deferred_notes">(?:(?!<\/instruction>)[\s\S])*<\/instruction>|<ctx-search-hint>(?:(?!<\/ctx-search-hint>)[\s\S])*<\/ctx-search-hint>))+$/;
|
|
12731
|
+
function renderDroppedText(tagId, renderedText) {
|
|
12732
|
+
const placeholder = buildReplacementContent(tagId);
|
|
12733
|
+
if (renderedText?.startsWith(placeholder))
|
|
12734
|
+
return renderedText;
|
|
12735
|
+
const annotations = renderedText?.match(FROZEN_TEXT_ANNOTATION_SUFFIX)?.[0] ?? "";
|
|
12736
|
+
return placeholder + annotations;
|
|
12737
|
+
}
|
|
12604
12738
|
function applyNewToolDrop(target, options) {
|
|
12605
12739
|
const plan = planNewToolDrop(target, options, !!options.persist);
|
|
12606
12740
|
if (!plan)
|
|
@@ -12682,6 +12816,7 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
|
|
|
12682
12816
|
AND drop_mode IN ('truncated', 'full')
|
|
12683
12817
|
ORDER BY tag_number`).all(sessionId);
|
|
12684
12818
|
const rows = readRows(db);
|
|
12819
|
+
options.prepareRemovals?.(rows);
|
|
12685
12820
|
const identity = JSON.stringify(rows);
|
|
12686
12821
|
const converted = new Map;
|
|
12687
12822
|
for (const row of rows) {
|
|
@@ -12721,13 +12856,21 @@ function renderConvertedToolSkeletons(targets, converted) {
|
|
|
12721
12856
|
return didMutate;
|
|
12722
12857
|
}
|
|
12723
12858
|
var PENDING_OPERATION_CHUNK_SIZE = 64;
|
|
12859
|
+
var PENDING_OPERATION_REJECTED_LOG_CHUNK = 20;
|
|
12724
12860
|
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
|
|
12725
12861
|
let didMutateMessage = false;
|
|
12726
12862
|
let diagnostics;
|
|
12727
|
-
const reject = (reason) => {
|
|
12863
|
+
const reject = (tagNumber, reason, state = {}) => {
|
|
12728
12864
|
if (!diagnostics)
|
|
12729
12865
|
return;
|
|
12730
12866
|
diagnostics.reasons[reason] = (diagnostics.reasons[reason] ?? 0) + 1;
|
|
12867
|
+
const persisted = state.persisted === true;
|
|
12868
|
+
(diagnostics.rejected ??= []).push({
|
|
12869
|
+
tagNumber,
|
|
12870
|
+
reason,
|
|
12871
|
+
persisted,
|
|
12872
|
+
queueState: state.queueState ?? (persisted ? "removed" : "retained")
|
|
12873
|
+
});
|
|
12731
12874
|
};
|
|
12732
12875
|
let admitted = false;
|
|
12733
12876
|
let startedAt = 0;
|
|
@@ -12787,29 +12930,39 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12787
12930
|
for (const { op: pendingOp, synthetic } of chunk) {
|
|
12788
12931
|
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
12789
12932
|
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
12790
|
-
reject("already_reduced"
|
|
12933
|
+
reject(pendingOp.tagId, "already_reduced", {
|
|
12934
|
+
queueState: synthetic ? "none" : "removed"
|
|
12935
|
+
});
|
|
12791
12936
|
if (!synthetic)
|
|
12792
12937
|
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12793
12938
|
continue;
|
|
12794
12939
|
}
|
|
12795
12940
|
if (removedTagIds.has(pendingOp.tagId)) {
|
|
12796
|
-
reject("drop_incomplete"
|
|
12941
|
+
reject(pendingOp.tagId, "drop_incomplete", {
|
|
12942
|
+
queueState: synthetic ? "none" : "retained"
|
|
12943
|
+
});
|
|
12797
12944
|
continue;
|
|
12798
12945
|
}
|
|
12799
12946
|
const target = targets.get(pendingOp.tagId);
|
|
12800
12947
|
const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
|
|
12801
12948
|
if (veto) {
|
|
12802
|
-
reject(veto
|
|
12949
|
+
reject(pendingOp.tagId, veto, {
|
|
12950
|
+
queueState: synthetic ? "none" : "retained"
|
|
12951
|
+
});
|
|
12803
12952
|
continue;
|
|
12804
12953
|
}
|
|
12805
12954
|
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
12806
12955
|
if (synthetic) {
|
|
12807
12956
|
if (!isToolTag) {
|
|
12808
|
-
reject("synthetic_non_tool"
|
|
12957
|
+
reject(pendingOp.tagId, "synthetic_non_tool", {
|
|
12958
|
+
queueState: "none"
|
|
12959
|
+
});
|
|
12809
12960
|
continue;
|
|
12810
12961
|
}
|
|
12811
12962
|
if (target?.canDrop?.() !== true) {
|
|
12812
|
-
reject("synthetic_target_not_droppable"
|
|
12963
|
+
reject(pendingOp.tagId, "synthetic_target_not_droppable", {
|
|
12964
|
+
queueState: "none"
|
|
12965
|
+
});
|
|
12813
12966
|
continue;
|
|
12814
12967
|
}
|
|
12815
12968
|
}
|
|
@@ -12822,14 +12975,19 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12822
12975
|
if (editMarkerTagIds.has(pendingOp.tagId)) {
|
|
12823
12976
|
const strip = target?.hasAttachments?.() === true;
|
|
12824
12977
|
if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
|
|
12825
|
-
reject("edit_marker_incomplete"
|
|
12978
|
+
reject(pendingOp.tagId, "edit_marker_incomplete", {
|
|
12979
|
+
queueState: synthetic ? "none" : "retained"
|
|
12980
|
+
});
|
|
12826
12981
|
continue;
|
|
12827
12982
|
}
|
|
12828
12983
|
persistDrop(strip ? "edit_marker_stripped" : "edit_marker");
|
|
12829
12984
|
mutations.push(() => {
|
|
12830
12985
|
const markResult = (strip ? target?.editMarkerStripped?.() : target?.editMarker?.()) ?? "absent";
|
|
12831
12986
|
if (markResult === "incomplete" || markResult === "absent") {
|
|
12832
|
-
reject(`edit_marker_${markResult}
|
|
12987
|
+
reject(pendingOp.tagId, `edit_marker_${markResult}`, {
|
|
12988
|
+
persisted: true,
|
|
12989
|
+
queueState: synthetic ? "none" : "removed"
|
|
12990
|
+
});
|
|
12833
12991
|
return;
|
|
12834
12992
|
}
|
|
12835
12993
|
record(true);
|
|
@@ -12841,7 +12999,9 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12841
12999
|
} else {
|
|
12842
13000
|
const plan = planNewToolDrop(target, { inWindow: skeletonWindow.has(pendingOp.tagId) }, true, plannedRemovals);
|
|
12843
13001
|
if (!plan) {
|
|
12844
|
-
reject("drop_incomplete"
|
|
13002
|
+
reject(pendingOp.tagId, "drop_incomplete", {
|
|
13003
|
+
queueState: synthetic ? "none" : "retained"
|
|
13004
|
+
});
|
|
12845
13005
|
continue;
|
|
12846
13006
|
}
|
|
12847
13007
|
persistDrop(plan.mode);
|
|
@@ -12852,7 +13012,10 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12852
13012
|
mutations.push(() => {
|
|
12853
13013
|
const { result: dropResult, mode: appliedMode } = plan.apply();
|
|
12854
13014
|
if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
|
|
12855
|
-
reject(`drop_${dropResult}
|
|
13015
|
+
reject(pendingOp.tagId, `drop_${dropResult}`, {
|
|
13016
|
+
persisted: true,
|
|
13017
|
+
queueState: synthetic ? "none" : "removed"
|
|
13018
|
+
});
|
|
12856
13019
|
return;
|
|
12857
13020
|
}
|
|
12858
13021
|
if (dropResult === "removed" || dropResult === "truncated") {
|
|
@@ -12862,15 +13025,18 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12862
13025
|
mode: appliedMode === "full" ? "full" : "truncated"
|
|
12863
13026
|
});
|
|
12864
13027
|
} else {
|
|
12865
|
-
reject(`drop_${dropResult}
|
|
13028
|
+
reject(pendingOp.tagId, `drop_${dropResult}`, {
|
|
13029
|
+
persisted: true,
|
|
13030
|
+
queueState: synthetic ? "none" : "removed"
|
|
13031
|
+
});
|
|
12866
13032
|
record(false);
|
|
12867
13033
|
}
|
|
12868
13034
|
});
|
|
12869
13035
|
}
|
|
12870
13036
|
} else if (target) {
|
|
12871
|
-
const replacement =
|
|
13037
|
+
const replacement = renderDroppedText(pendingOp.tagId, target.getContent?.());
|
|
12872
13038
|
if (target.canSetContent?.(replacement) === false) {
|
|
12873
|
-
reject("content_unchanged");
|
|
13039
|
+
reject(pendingOp.tagId, "content_unchanged");
|
|
12874
13040
|
continue;
|
|
12875
13041
|
}
|
|
12876
13042
|
persistDrop();
|
|
@@ -12886,12 +13052,18 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12886
13052
|
removedCharacters: Math.max(0, originalCharacters - replacement.length)
|
|
12887
13053
|
});
|
|
12888
13054
|
} else {
|
|
12889
|
-
reject("content_unchanged"
|
|
13055
|
+
reject(pendingOp.tagId, "content_unchanged", {
|
|
13056
|
+
persisted: true,
|
|
13057
|
+
queueState: "removed"
|
|
13058
|
+
});
|
|
12890
13059
|
}
|
|
12891
13060
|
});
|
|
12892
13061
|
} else if (!synthetic) {
|
|
12893
|
-
reject("target_absent");
|
|
12894
13062
|
persistDrop();
|
|
13063
|
+
reject(pendingOp.tagId, "target_absent", {
|
|
13064
|
+
persisted: true,
|
|
13065
|
+
queueState: "removed"
|
|
13066
|
+
});
|
|
12895
13067
|
mutations.push(() => record(false));
|
|
12896
13068
|
}
|
|
12897
13069
|
}
|
|
@@ -12918,6 +13090,15 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12918
13090
|
const reasons = Object.entries(diagnostics.reasons).sort(([left], [right]) => left.localeCompare(right)).map(([reason, count]) => `${reason}:${count}`).join(",");
|
|
12919
13091
|
sessionLog(sessionId, `pending operations no-op: source=${diagnostics.source} total=${diagnostics.total} persisted=${diagnostics.persistedWithoutMutation} reasons=${reasons || "none"}`);
|
|
12920
13092
|
}
|
|
13093
|
+
const rejected = diagnostics.rejected;
|
|
13094
|
+
if (rejected && rejected.length > 0) {
|
|
13095
|
+
const lineCount = Math.ceil(rejected.length / PENDING_OPERATION_REJECTED_LOG_CHUNK);
|
|
13096
|
+
for (let offset = 0;offset < rejected.length; offset += PENDING_OPERATION_REJECTED_LOG_CHUNK) {
|
|
13097
|
+
const entries = rejected.slice(offset, offset + PENDING_OPERATION_REJECTED_LOG_CHUNK).map((entry) => `${entry.tagNumber}:${entry.reason}:${entry.queueState}${entry.persisted ? ":persisted" : ""}`).join(",");
|
|
13098
|
+
const chunkLabel = lineCount > 1 ? ` chunk=${Math.floor(offset / PENDING_OPERATION_REJECTED_LOG_CHUNK) + 1}/${lineCount}` : "";
|
|
13099
|
+
sessionLog(sessionId, `pending operations rejected: source=${diagnostics.source} total=${diagnostics.total} mutated=${diagnostics.mutated} persisted=${diagnostics.persistedWithoutMutation}${chunkLabel} rejected=${entries}`);
|
|
13100
|
+
}
|
|
13101
|
+
}
|
|
12921
13102
|
}
|
|
12922
13103
|
return didMutateMessage;
|
|
12923
13104
|
}
|
|
@@ -12958,7 +13139,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
12958
13139
|
}
|
|
12959
13140
|
}
|
|
12960
13141
|
} else if (target) {
|
|
12961
|
-
const changed = target.setContent(
|
|
13142
|
+
const changed = target.setContent(renderDroppedText(tag.tagNumber, target.getContent?.()));
|
|
12962
13143
|
if (changed)
|
|
12963
13144
|
didMutateMessage = true;
|
|
12964
13145
|
}
|
|
@@ -16463,7 +16644,7 @@ function createTransform(deps) {
|
|
|
16463
16644
|
const startTime = performance.now();
|
|
16464
16645
|
const historianRun = deps.resolveHistorianRun?.();
|
|
16465
16646
|
const messages = output.messages;
|
|
16466
|
-
const
|
|
16647
|
+
const entryOrderForThinkingFit = messages.slice();
|
|
16467
16648
|
const coveredHostInstructions = takeCoveredInstructionRows(messages);
|
|
16468
16649
|
const passOutcome = createPassOutcome();
|
|
16469
16650
|
const tSessionId = performance.now();
|
|
@@ -16478,8 +16659,21 @@ function createTransform(deps) {
|
|
|
16478
16659
|
const temporalReplayIds = temporalCandidates ? messages.flatMap((message) => message.info.id ? [message.info.id] : []) : undefined;
|
|
16479
16660
|
logTransformTiming(sessionId, "findSessionId", tSessionId, `messages=${messages.length}`);
|
|
16480
16661
|
const tLkgEntry = performance.now();
|
|
16481
|
-
const lkgInput = projectEntry(sessionId,
|
|
16662
|
+
const lkgInput = projectEntry(sessionId, entryOrderForThinkingFit);
|
|
16482
16663
|
const recovery = deps.compactionOff ? {} : readLkgRecoveryPrefix(sessionId, lkgInput, messages, deps.db);
|
|
16664
|
+
const recoveryTailSources = [];
|
|
16665
|
+
if (recovery.prefix) {
|
|
16666
|
+
const priorIdentities = new Set(recovery.prefix.inputs.map((input) => input.id));
|
|
16667
|
+
lkgInput.forEach((input, index) => {
|
|
16668
|
+
const identity = lkgInputIdentity(input.id, input.role, index);
|
|
16669
|
+
if (!identity || priorIdentities.has(identity))
|
|
16670
|
+
return;
|
|
16671
|
+
recoveryTailSources.push({
|
|
16672
|
+
identity,
|
|
16673
|
+
pristineSystem: input.id === null && input.role === "system" ? structuredClone(entryOrderForThinkingFit[index]) : undefined
|
|
16674
|
+
});
|
|
16675
|
+
});
|
|
16676
|
+
}
|
|
16483
16677
|
logTransformTiming(sessionId, "lkg.entryProjection", tLkgEntry, entryReuse ? `reused=${entryReuse.reused} retained=${entryReuse.retained} retainedBytes=${entryReuse.retainedBytes}` : undefined);
|
|
16484
16678
|
const resolvedSessionId = sessionId;
|
|
16485
16679
|
const runNotificationParams = (sid) => {
|
|
@@ -16781,6 +16975,13 @@ function createTransform(deps) {
|
|
|
16781
16975
|
activeThinkingTurn ||= hasActiveAnthropicThinkingTurn(messages, resolvedProviderID, modelForBudget?.modelID);
|
|
16782
16976
|
activeThinkingPrefixHold ||= activeThinkingTurn && isPrefixBoundThinkingModel(resolvedProviderID, modelForBudget?.modelID);
|
|
16783
16977
|
freezeM0M1 ||= activeThinkingPrefixHold;
|
|
16978
|
+
const originalForThinkingFit = takeSignedThinkingFitSnapshot({
|
|
16979
|
+
sessionId,
|
|
16980
|
+
entryOrder: entryOrderForThinkingFit,
|
|
16981
|
+
held: activeThinkingPrefixHold,
|
|
16982
|
+
activeAnthropicThinkingTurn: activeThinkingTurn,
|
|
16983
|
+
compactionOff
|
|
16984
|
+
});
|
|
16784
16985
|
if (freezeM0M1 && prefixHoldLogTurnIds.get(sessionId) !== currentTurnId) {
|
|
16785
16986
|
prefixHoldLogTurnIds.set(sessionId, currentTurnId);
|
|
16786
16987
|
const reason = activeThinkingPrefixHold ? "active thinking turn (prefix-bound model)" : "session directory unresolved";
|
|
@@ -16805,7 +17006,8 @@ function createTransform(deps) {
|
|
|
16805
17006
|
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
16806
17007
|
providerID: modelForBudget?.providerID,
|
|
16807
17008
|
modelID: modelForBudget?.modelID,
|
|
16808
|
-
agentName: runNotificationParams(sessionId)?.agent
|
|
17009
|
+
agentName: runNotificationParams(sessionId)?.agent,
|
|
17010
|
+
sessionId
|
|
16809
17011
|
});
|
|
16810
17012
|
const incomingTokens = incoming.messageTokens.conversation + incoming.messageTokens.toolCall;
|
|
16811
17013
|
if (unmanagedOverWindowCarried || isClearlyOverWindow(incomingTokens, resolvedContextLimit)) {
|
|
@@ -17293,7 +17495,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17293
17495
|
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
17294
17496
|
providerID: modelForBudget?.providerID,
|
|
17295
17497
|
modelID: modelForBudget?.modelID,
|
|
17296
|
-
agentName: notificationParams.agent
|
|
17498
|
+
agentName: notificationParams.agent,
|
|
17499
|
+
sessionId
|
|
17297
17500
|
});
|
|
17298
17501
|
contextUsage = resolveUnknownUsageFromWireEstimate({
|
|
17299
17502
|
usage: contextUsage,
|
|
@@ -17424,9 +17627,15 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17424
17627
|
}
|
|
17425
17628
|
});
|
|
17426
17629
|
if (recovery.prefix && !recoveryNormalized) {
|
|
17427
|
-
const
|
|
17428
|
-
|
|
17429
|
-
|
|
17630
|
+
const renderedById = new Map;
|
|
17631
|
+
for (const message of messages) {
|
|
17632
|
+
if (!message.info.id)
|
|
17633
|
+
continue;
|
|
17634
|
+
const group = renderedById.get(message.info.id) ?? [];
|
|
17635
|
+
group.push(message);
|
|
17636
|
+
renderedById.set(message.info.id, group);
|
|
17637
|
+
}
|
|
17638
|
+
const suffix = recoveryTailSources.flatMap(({ identity, pristineSystem }) => pristineSystem ? [pristineSystem] : renderedById.get(identity) ?? []);
|
|
17430
17639
|
messages.splice(0, messages.length, ...JSON.parse(recovery.prefix.json), ...suffix);
|
|
17431
17640
|
}
|
|
17432
17641
|
const recoveryReleaseReason = recovery.rebuildReason ?? (recoveryNormalized ? "recovery_tail_normalized" : undefined);
|
|
@@ -17443,6 +17652,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17443
17652
|
providerID: modelForBudget?.providerID,
|
|
17444
17653
|
modelID: modelForBudget?.modelID,
|
|
17445
17654
|
agentName: notificationParams.agent,
|
|
17655
|
+
sessionId,
|
|
17446
17656
|
systemPromptHash: sessionMeta.systemPromptHash
|
|
17447
17657
|
}, boundaryContextLimit);
|
|
17448
17658
|
} catch {
|
|
@@ -17457,13 +17667,15 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17457
17667
|
providerID: modelForBudget?.providerID,
|
|
17458
17668
|
modelID: modelForBudget?.modelID,
|
|
17459
17669
|
agentName: notificationParams.agent,
|
|
17670
|
+
sessionId,
|
|
17460
17671
|
systemPromptHash: sessionMeta.systemPromptHash
|
|
17461
17672
|
}, boundaryContextLimit) : undefined);
|
|
17462
17673
|
if (finalWireEstimate) {
|
|
17463
17674
|
sessionLog(sessionId, `transform: final-wire telemetry estimate=${finalWireEstimate.tokens} trusted=${finalWireEstimate.trusted} conversation=${finalWireEstimate.messageTokens.conversation} tools=${finalWireEstimate.messageTokens.toolCall} system=${finalWireEstimate.systemTokens} toolDefinitions=${finalWireEstimate.toolDefinitionTokens ?? "unknown"} tail=${finalWireTail}`);
|
|
17464
17675
|
}
|
|
17465
17676
|
if ((finalWireEstimate?.refusalGrade || finalWireEstimate?.refusalBasis === "byte-bound" && finalWireEstimate.refusalTokens !== undefined) && boundaryContextLimit > 0 && (finalWireEstimate.refusalTokens ?? finalWireEstimate.tokens) > boundaryContextLimit) {
|
|
17466
|
-
|
|
17677
|
+
const signedFitRetryWanted = !thinkingFitRetries.has(sessionId) && activeThinkingPrefixHold && hasActiveAnthropicThinkingTurn(messages, resolvedProviderID, modelForBudget?.modelID);
|
|
17678
|
+
if (signedFitRetryWanted && originalForThinkingFit) {
|
|
17467
17679
|
thinkingFitRetries.add(sessionId);
|
|
17468
17680
|
requestPendingMaterialization(deps.pendingMaterializationSessions, sessionId, "fit_retry");
|
|
17469
17681
|
messages.splice(0, messages.length, ...originalForThinkingFit);
|
|
@@ -17474,7 +17686,10 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17474
17686
|
}
|
|
17475
17687
|
return;
|
|
17476
17688
|
}
|
|
17477
|
-
if (
|
|
17689
|
+
if (signedFitRetryWanted) {
|
|
17690
|
+
sessionLog(sessionId, "signed thinking fit: the held request is over the window and no copy of the pass input exists to retry from; refusing it");
|
|
17691
|
+
}
|
|
17692
|
+
if (signedFitRetryWanted || thinkingFitRetries.has(sessionId) || postTransformResult.thinkingReleasedForFit)
|
|
17478
17693
|
throw contextRefusalError("The request remains over the model window after stripping signed thinking and reclaiming context");
|
|
17479
17694
|
}
|
|
17480
17695
|
if (postTransformResult.prefixTrimStatus === "refused") {
|
|
@@ -17483,7 +17698,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17483
17698
|
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
17484
17699
|
providerID: modelForBudget?.providerID,
|
|
17485
17700
|
modelID: modelForBudget?.modelID,
|
|
17486
|
-
agentName: notificationParams.agent
|
|
17701
|
+
agentName: notificationParams.agent,
|
|
17702
|
+
sessionId
|
|
17487
17703
|
});
|
|
17488
17704
|
if (untrimmed.tokens > boundaryContextLimit) {
|
|
17489
17705
|
sessionLog(sessionId, `history boundary unresolved: prefix trim refused and the untrimmed request estimate ${untrimmed.tokens} (trusted=${untrimmed.trusted}) exceeds the context limit ${boundaryContextLimit}; not sending it`);
|
|
@@ -17496,7 +17712,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17496
17712
|
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
17497
17713
|
providerID: modelForBudget?.providerID,
|
|
17498
17714
|
modelID: modelForBudget?.modelID,
|
|
17499
|
-
agentName: notificationParams.agent
|
|
17715
|
+
agentName: notificationParams.agent,
|
|
17716
|
+
sessionId
|
|
17500
17717
|
});
|
|
17501
17718
|
const servedTokens = served.toolDefinitionsMeasured ? served.rawTokens ?? served.tokens : Math.max(0, sessionMeta.systemPromptTokens) + served.messageTokens.conversation + served.messageTokens.toolCall;
|
|
17502
17719
|
if (!Number.isFinite(servedTokens) || servedTokens > unmanagedOverWindowPass.limit) {
|
|
@@ -17574,7 +17791,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17574
17791
|
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
17575
17792
|
providerID: modelForBudget?.providerID,
|
|
17576
17793
|
modelID: modelForBudget?.modelID,
|
|
17577
|
-
agentName: notificationParams.agent
|
|
17794
|
+
agentName: notificationParams.agent,
|
|
17795
|
+
sessionId
|
|
17578
17796
|
});
|
|
17579
17797
|
} catch (error) {
|
|
17580
17798
|
sessionLog(sessionId, "degraded pass size guard could not estimate:", error);
|
|
@@ -17786,6 +18004,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17786
18004
|
providerID: modelForBudget?.providerID,
|
|
17787
18005
|
modelID: modelForBudget?.modelID,
|
|
17788
18006
|
agentName: notificationParams.agent,
|
|
18007
|
+
sessionId,
|
|
17789
18008
|
systemPromptHash: sessionMeta.systemPromptHash
|
|
17790
18009
|
});
|
|
17791
18010
|
try {
|
|
@@ -18257,8 +18476,26 @@ WHERE session_id = ?
|
|
|
18257
18476
|
AND data IS NOT NULL
|
|
18258
18477
|
AND (time_created > ? OR (time_created = ? AND id > ?))
|
|
18259
18478
|
ORDER BY time_created, id`;
|
|
18260
|
-
|
|
18261
|
-
|
|
18479
|
+
var V2_ASSISTANT_USAGE_ROWS_AFTER_SQL = `
|
|
18480
|
+
WITH newer AS (
|
|
18481
|
+
SELECT id, seq, data FROM session_message
|
|
18482
|
+
WHERE session_id = ? AND type = 'assistant' AND data IS NOT NULL AND seq > ?
|
|
18483
|
+
UNION ALL
|
|
18484
|
+
SELECT id, seq, data FROM session_message
|
|
18485
|
+
WHERE session_id = ? AND type = 'assistant' AND data IS NOT NULL AND seq = ? AND id > ?
|
|
18486
|
+
)
|
|
18487
|
+
SELECT
|
|
18488
|
+
json_extract(data, '$.agent') AS agent,
|
|
18489
|
+
seq AS time_created,
|
|
18490
|
+
id AS id,
|
|
18491
|
+
COALESCE(json_extract(data, '$.tokens.input'), 0)
|
|
18492
|
+
+ COALESCE(json_extract(data, '$.tokens.cache.read'), 0)
|
|
18493
|
+
+ COALESCE(json_extract(data, '$.tokens.cache.write'), 0) AS prompt,
|
|
18494
|
+
COALESCE(json_extract(data, '$.tokens.output'), 0) AS output
|
|
18495
|
+
FROM newer
|
|
18496
|
+
ORDER BY seq, id`;
|
|
18497
|
+
function readAssistantUsageRowsAfter(openCodeDb, sessionId, afterTimeCreated, afterId, generation = "v1") {
|
|
18498
|
+
const rows = openCodeDb.prepare(generation === "v2" ? V2_ASSISTANT_USAGE_ROWS_AFTER_SQL : ASSISTANT_USAGE_ROWS_AFTER_SQL).all(...generation === "v2" ? [sessionId, afterTimeCreated, sessionId, afterTimeCreated, afterId] : [sessionId, afterTimeCreated, afterTimeCreated, afterId]);
|
|
18262
18499
|
return rows.map((r) => ({
|
|
18263
18500
|
agent: r.agent ?? null,
|
|
18264
18501
|
timeCreated: Number(r.time_created ?? 0),
|
|
@@ -18267,8 +18504,8 @@ function readAssistantUsageRowsAfter(openCodeDb, sessionId, afterTimeCreated, af
|
|
|
18267
18504
|
output: Number(r.output ?? 0)
|
|
18268
18505
|
}));
|
|
18269
18506
|
}
|
|
18270
|
-
function computeOpenCodeWorkMetricsIncremental(openCodeDb, sessionId, carry) {
|
|
18271
|
-
const rows = readAssistantUsageRowsAfter(openCodeDb, sessionId, carry.lastTimeCreated, carry.lastId);
|
|
18507
|
+
function computeOpenCodeWorkMetricsIncremental(openCodeDb, sessionId, carry, generation = "v1") {
|
|
18508
|
+
const rows = readAssistantUsageRowsAfter(openCodeDb, sessionId, carry.lastTimeCreated, carry.lastId, generation);
|
|
18272
18509
|
if (rows.length === 0) {
|
|
18273
18510
|
return { carry, metrics: metricsFromCarry(carry) };
|
|
18274
18511
|
}
|
|
@@ -18466,13 +18703,15 @@ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
|
|
|
18466
18703
|
// src/plugin/rpc-handlers.ts
|
|
18467
18704
|
var workMetricsCarryBySession = new Map;
|
|
18468
18705
|
function resolveSidebarWorkMetrics(db, sessionId, persistedNewWork, persistedTotalInput) {
|
|
18469
|
-
|
|
18706
|
+
const generation = getHarness() === "opencode2" ? "v2" : "v1";
|
|
18707
|
+
if (!openCodeDbExists(generation)) {
|
|
18470
18708
|
return { newWorkTokens: persistedNewWork, totalInputTokens: persistedTotalInput };
|
|
18471
18709
|
}
|
|
18472
18710
|
try {
|
|
18473
|
-
const
|
|
18474
|
-
const
|
|
18475
|
-
|
|
18711
|
+
const carryKey = `${generation}:${sessionId}`;
|
|
18712
|
+
const carry = workMetricsCarryBySession.get(carryKey) ?? emptyWorkMetricsCarry();
|
|
18713
|
+
const { carry: nextCarry, metrics } = withReadOnlySessionDb((openCodeDb) => computeOpenCodeWorkMetricsIncremental(openCodeDb, sessionId, carry, generation), generation);
|
|
18714
|
+
workMetricsCarryBySession.set(carryKey, nextCarry);
|
|
18476
18715
|
try {
|
|
18477
18716
|
setSessionWorkMetrics(db, sessionId, metrics.newWorkTokens, metrics.totalInputTokens);
|
|
18478
18717
|
} catch {}
|
|
@@ -18591,7 +18830,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
18591
18830
|
if (model) {
|
|
18592
18831
|
activeProviderID = model.providerID;
|
|
18593
18832
|
activeModelID = model.modelID;
|
|
18594
|
-
measuredToolDefTokens = getMeasuredToolDefinitionTokens(model.providerID, model.modelID, agent) ?? 0;
|
|
18833
|
+
measuredToolDefTokens = getMeasuredToolDefinitionTokens(model.providerID, model.modelID, agent, sessionId) ?? 0;
|
|
18595
18834
|
}
|
|
18596
18835
|
}
|
|
18597
18836
|
const contextLimit = activeProviderID && activeModelID ? resolveContextLimit(activeProviderID, activeModelID, {
|
|
@@ -19077,8 +19316,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
19077
19316
|
const db = readDatabase();
|
|
19078
19317
|
if (!db)
|
|
19079
19318
|
return { ok: false, error: "db unavailable" };
|
|
19080
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
19081
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
19319
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-gzd1at06.js");
|
|
19320
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-vdppp5x6.js");
|
|
19082
19321
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
19083
19322
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
19084
19323
|
return {
|
|
@@ -19127,7 +19366,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
19127
19366
|
const db = readDatabase();
|
|
19128
19367
|
if (!db)
|
|
19129
19368
|
return { ok: false, error: "db unavailable" };
|
|
19130
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
19369
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-ghq4y406.js");
|
|
19131
19370
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
19132
19371
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
19133
19372
|
const ctx = {
|
|
@@ -19822,18 +20061,18 @@ var FULL_PARAMETER_DESCRIPTIONS = {
|
|
|
19822
20061
|
message: "Message ordinal from a <session-history> heading or a mmc_search hit, not a tag number. Returns that one message in full. Use alone."
|
|
19823
20062
|
},
|
|
19824
20063
|
mmc_note: {
|
|
19825
|
-
action: "write | read | update | dismiss.
|
|
20064
|
+
action: "write | read | update | dismiss.",
|
|
19826
20065
|
content: "Note text for write/update: first line is the title (under 80 chars), then the detail.",
|
|
19827
20066
|
filter: "Read filter: active (default), all, dismissed.",
|
|
19828
20067
|
limit: "Rows per read (default 25).",
|
|
19829
20068
|
offset: "Skip this many newest rows (default 0).",
|
|
19830
|
-
note_ids: "Note ids: one for update, 1–50 for dismiss or
|
|
20069
|
+
note_ids: "Note ids: one for update, 1–50 for dismiss, or 1–50 to read those notes in full. Write and a plain read take an empty list."
|
|
19831
20070
|
},
|
|
19832
20071
|
mmc_memory: {
|
|
19833
20072
|
action: "write | update | archive | merge | get",
|
|
19834
|
-
content: "The memory text — one standalone fact (write, update, merge).",
|
|
19835
|
-
category: "Kind of fact
|
|
19836
|
-
ids: "Memory ids from <project-memory>: one for update, one or more for archive, two or more for merge, 1–20 for get.",
|
|
20073
|
+
content: "The memory text — one standalone fact (write, update, merge). Archive and get take an empty string.",
|
|
20074
|
+
category: "Kind of fact: the new fact's kind for write; on update/merge, the memory's current category to keep it. Archive and get ignore it.",
|
|
20075
|
+
ids: "Memory ids from <project-memory>: one for update, one or more for archive, two or more for merge, 1–20 for get. Write takes an empty list.",
|
|
19837
20076
|
reason: "Why it is being archived (optional)."
|
|
19838
20077
|
},
|
|
19839
20078
|
mmc_search: {
|
|
@@ -19856,18 +20095,18 @@ var LIGHT_PARAMETER_DESCRIPTIONS = {
|
|
|
19856
20095
|
message: "Message ordinal from a <session-history> heading or a mmc_search hit, not a tag number. Returns that one message in full. Use alone."
|
|
19857
20096
|
},
|
|
19858
20097
|
mmc_note: {
|
|
19859
|
-
action: "write | read | update | dismiss
|
|
20098
|
+
action: "write | read | update | dismiss.",
|
|
19860
20099
|
content: "Note text: first line title (<80 chars), then detail.",
|
|
19861
20100
|
filter: "Read filter: active (default), all, dismissed.",
|
|
19862
20101
|
limit: "Rows per read (default 25).",
|
|
19863
20102
|
offset: "Skip newest rows (default 0).",
|
|
19864
|
-
note_ids: "One id for update, 1–50 for dismiss or read
|
|
20103
|
+
note_ids: "One id for update, 1–50 for dismiss, or 1–50 to read those notes in full. Write and a plain read take an empty list."
|
|
19865
20104
|
},
|
|
19866
20105
|
mmc_memory: {
|
|
19867
20106
|
action: "write | update | archive | merge | get",
|
|
19868
|
-
content: "One standalone fact (write, update, merge).",
|
|
19869
|
-
category: "Kind of fact (
|
|
19870
|
-
ids: "Ids from <project-memory>: one for update, 1+ for archive, 2+ for merge, 1–20 for get.",
|
|
20107
|
+
content: "One standalone fact (write, update, merge). Archive and get: empty string.",
|
|
20108
|
+
category: "Kind of fact (write; on update/merge pass the current category to keep it). Archive and get ignore it.",
|
|
20109
|
+
ids: "Ids from <project-memory>: one for update, 1+ for archive, 2+ for merge, 1–20 for get. Write: empty list.",
|
|
19871
20110
|
reason: "Why it is archived (optional)."
|
|
19872
20111
|
},
|
|
19873
20112
|
mmc_search: {
|
|
@@ -22427,6 +22666,96 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
22427
22666
|
};
|
|
22428
22667
|
}
|
|
22429
22668
|
|
|
22669
|
+
// src/v2/message-times.ts
|
|
22670
|
+
function isSettled(entry, readAt) {
|
|
22671
|
+
return (entry.version.type === "user" || entry.time.completed !== undefined) && typeof entry.version.updated === "number" && Number.isFinite(entry.version.updated) && entry.version.updated <= readAt - 1000;
|
|
22672
|
+
}
|
|
22673
|
+
function sameVersion(a, b) {
|
|
22674
|
+
return a.type === b.type && a.seq === b.seq && a.created === b.created && a.updated === b.updated;
|
|
22675
|
+
}
|
|
22676
|
+
|
|
22677
|
+
class V2MessageTimesCache {
|
|
22678
|
+
capacity;
|
|
22679
|
+
sessions = new Map;
|
|
22680
|
+
constructor(capacity = 64) {
|
|
22681
|
+
this.capacity = capacity;
|
|
22682
|
+
}
|
|
22683
|
+
delete(sessionID) {
|
|
22684
|
+
this.sessions.delete(sessionID);
|
|
22685
|
+
}
|
|
22686
|
+
deleteMessage(sessionID, messageID) {
|
|
22687
|
+
this.sessions.get(sessionID)?.entries.delete(messageID);
|
|
22688
|
+
}
|
|
22689
|
+
clear() {
|
|
22690
|
+
this.sessions.clear();
|
|
22691
|
+
}
|
|
22692
|
+
pass(sessionID) {
|
|
22693
|
+
const previous = this.sessions.get(sessionID);
|
|
22694
|
+
const current = { entries: new Map };
|
|
22695
|
+
this.sessions.delete(sessionID);
|
|
22696
|
+
this.sessions.set(sessionID, current);
|
|
22697
|
+
while (this.sessions.size > this.capacity) {
|
|
22698
|
+
const oldest = this.sessions.keys().next().value;
|
|
22699
|
+
if (oldest === undefined)
|
|
22700
|
+
break;
|
|
22701
|
+
this.sessions.delete(oldest);
|
|
22702
|
+
}
|
|
22703
|
+
const passTimes = new Map;
|
|
22704
|
+
return (reader, ids) => {
|
|
22705
|
+
const missing = [...new Set(ids)].filter((id) => !passTimes.has(id));
|
|
22706
|
+
if (missing.length > 0) {
|
|
22707
|
+
const readAt = Date.now();
|
|
22708
|
+
const identity = reader.hostIdentity();
|
|
22709
|
+
current.identity = identity;
|
|
22710
|
+
const reusable = previous?.identity === identity ? previous.entries : undefined;
|
|
22711
|
+
const known = [];
|
|
22712
|
+
const refresh = [];
|
|
22713
|
+
let first = Infinity;
|
|
22714
|
+
let last = -Infinity;
|
|
22715
|
+
for (const id of missing) {
|
|
22716
|
+
const entry = reusable?.get(id);
|
|
22717
|
+
if (entry && isSettled(entry, readAt)) {
|
|
22718
|
+
known.push(id);
|
|
22719
|
+
first = Math.min(first, entry.version.seq);
|
|
22720
|
+
last = Math.max(last, entry.version.seq);
|
|
22721
|
+
} else
|
|
22722
|
+
refresh.push(id);
|
|
22723
|
+
}
|
|
22724
|
+
const versions = reader.messageTimeVersions(sessionID, known, { first, last });
|
|
22725
|
+
for (const id of known) {
|
|
22726
|
+
const version = versions.get(id);
|
|
22727
|
+
const cached = reusable?.get(id);
|
|
22728
|
+
if (!version) {
|
|
22729
|
+
passTimes.set(id, null);
|
|
22730
|
+
} else if (cached && sameVersion(cached.version, version) && (version.type === "user" || cached.time.completed !== undefined)) {
|
|
22731
|
+
current.entries.set(id, cached);
|
|
22732
|
+
passTimes.set(id, cached.time);
|
|
22733
|
+
} else
|
|
22734
|
+
refresh.push(id);
|
|
22735
|
+
}
|
|
22736
|
+
const times = reader.messageTimes(sessionID, refresh, versions);
|
|
22737
|
+
for (const id of refresh) {
|
|
22738
|
+
const time = times.get(id);
|
|
22739
|
+
const version = versions.get(id);
|
|
22740
|
+
passTimes.set(id, time ?? null);
|
|
22741
|
+
if (time && version) {
|
|
22742
|
+
const entry = { version, time };
|
|
22743
|
+
if (isSettled(entry, readAt))
|
|
22744
|
+
current.entries.set(id, entry);
|
|
22745
|
+
}
|
|
22746
|
+
}
|
|
22747
|
+
}
|
|
22748
|
+
const result = new Map;
|
|
22749
|
+
for (const id of ids) {
|
|
22750
|
+
const time = passTimes.get(id);
|
|
22751
|
+
if (time)
|
|
22752
|
+
result.set(id, { ...time });
|
|
22753
|
+
}
|
|
22754
|
+
return result;
|
|
22755
|
+
};
|
|
22756
|
+
}
|
|
22757
|
+
}
|
|
22758
|
+
|
|
22430
22759
|
// src/v2/hooks/channel2.ts
|
|
22431
22760
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
22432
22761
|
var pendingCandidates = new WeakMap;
|
|
@@ -23365,7 +23694,7 @@ function projectRawMessages(rows, ordinalFor) {
|
|
|
23365
23694
|
const message = {
|
|
23366
23695
|
id: row.id,
|
|
23367
23696
|
ordinal: ordinalFor(row, index),
|
|
23368
|
-
role: row.type === "assistant" ? "assistant" : "user",
|
|
23697
|
+
role: row.type === "assistant" ? "assistant" : row.type === "system" ? "system" : "user",
|
|
23369
23698
|
createdAt: row.time_created ?? row.data.time?.created,
|
|
23370
23699
|
parts: row.type === "assistant" ? (row.data.content ?? []).map((part) => {
|
|
23371
23700
|
if (part.type !== "tool")
|
|
@@ -23741,6 +24070,17 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
23741
24070
|
|
|
23742
24071
|
// src/tools/ctx-expand/render.ts
|
|
23743
24072
|
import { createHash as createHash5 } from "node:crypto";
|
|
24073
|
+
function recoveryParts(sessionId, message, attachments) {
|
|
24074
|
+
return attachments ? [...message.parts, ...attachments(sessionId, message.id)] : message.parts;
|
|
24075
|
+
}
|
|
24076
|
+
function attachmentNotice(part) {
|
|
24077
|
+
const field = (value) => typeof value === "string" ? value.trim().replace(/[\r\n]+/g, " ") : "";
|
|
24078
|
+
const source = isRecord4(part.source) ? part.source : {};
|
|
24079
|
+
const location = [part.url, part.path, source.uri, source.url, source.path].map(field).find((value) => value && !/^(data|blob):/i.test(value));
|
|
24080
|
+
const name = field(part.filename) || field(part.name);
|
|
24081
|
+
const mime = field(part.mime) || field(part.mimeType) || field(part.mediaType);
|
|
24082
|
+
return `[file]${name ? ` ${name}` : ""}${mime ? ` (${mime})` : ""}` + `${location ? ` — stored location: ${location}` : ""}` + "; content not recovered. If needed, ask the user to attach it again.";
|
|
24083
|
+
}
|
|
23744
24084
|
function isRecord4(value) {
|
|
23745
24085
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
23746
24086
|
}
|
|
@@ -23847,8 +24187,8 @@ function renderPartPreview(part, expandTools) {
|
|
|
23847
24187
|
if (reasoning !== null)
|
|
23848
24188
|
return ` • [reasoning] ${truncate2(reasoning, 120)}`;
|
|
23849
24189
|
const type = typeof part.type === "string" ? part.type : "part";
|
|
23850
|
-
if (type === "file")
|
|
23851
|
-
return
|
|
24190
|
+
if (type === "file" || type === "image")
|
|
24191
|
+
return ` • ${attachmentNotice(part)}`;
|
|
23852
24192
|
if (type === "step-start" || type === "step-finish")
|
|
23853
24193
|
return null;
|
|
23854
24194
|
return ` • [${type}]`;
|
|
@@ -23878,13 +24218,11 @@ ${tool.output}`);
|
|
|
23878
24218
|
`);
|
|
23879
24219
|
}
|
|
23880
24220
|
const type = typeof part.type === "string" ? part.type : "part";
|
|
23881
|
-
if (type === "file")
|
|
23882
|
-
|
|
23883
|
-
return ` [file]${name ? ` ${name}` : ""}`;
|
|
23884
|
-
}
|
|
24221
|
+
if (type === "file" || type === "image")
|
|
24222
|
+
return ` ${attachmentNotice(part)}`;
|
|
23885
24223
|
return null;
|
|
23886
24224
|
}
|
|
23887
|
-
function renderMessageByOrdinal(sessionId, ordinal) {
|
|
24225
|
+
function renderMessageByOrdinal(sessionId, ordinal, attachments) {
|
|
23888
24226
|
const found = [];
|
|
23889
24227
|
visitRawSessionMessages2(sessionId, ordinal, ordinal, (m) => {
|
|
23890
24228
|
if (m.ordinal === ordinal)
|
|
@@ -23895,7 +24233,7 @@ function renderMessageByOrdinal(sessionId, ordinal) {
|
|
|
23895
24233
|
if (!msg) {
|
|
23896
24234
|
return `No message at ordinal ${ordinal} is currently in this session's stored history — ` + `it may have been removed by a session prune/revert, or the ordinal may be wrong. ` + `Re-run the tool if you still need the data.`;
|
|
23897
24235
|
}
|
|
23898
|
-
const rendered = msg.
|
|
24236
|
+
const rendered = recoveryParts(sessionId, msg, attachments).map(renderPartFull).filter((l) => l !== null);
|
|
23899
24237
|
const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
|
|
23900
24238
|
if (rendered.length === 0) {
|
|
23901
24239
|
lines.push(" (no recoverable content — message had only structural/reasoning parts)");
|
|
@@ -23905,14 +24243,14 @@ function renderMessageByOrdinal(sessionId, ordinal) {
|
|
|
23905
24243
|
return lines.join(`
|
|
23906
24244
|
`);
|
|
23907
24245
|
}
|
|
23908
|
-
function renderVerboseRange(sessionId, start, end, tokenBudget, expandTools) {
|
|
24246
|
+
function renderVerboseRange(sessionId, start, end, tokenBudget, expandTools, attachments) {
|
|
23909
24247
|
const out = [];
|
|
23910
24248
|
let usedTokens = 0;
|
|
23911
24249
|
let lastOrdinal = start - 1;
|
|
23912
24250
|
let truncated = false;
|
|
23913
24251
|
visitRawSessionMessages2(sessionId, start, end, (msg) => {
|
|
23914
24252
|
const header = `[${msg.ordinal}] ${verboseRoleLabel(msg)}`;
|
|
23915
|
-
const partLines = msg.
|
|
24253
|
+
const partLines = recoveryParts(sessionId, msg, attachments).map((part) => renderPartPreview(part, expandTools)).filter((l) => l !== null);
|
|
23916
24254
|
const block = partLines.length > 0 ? `${header}
|
|
23917
24255
|
${partLines.join(`
|
|
23918
24256
|
`)}` : header;
|
|
@@ -23930,7 +24268,23 @@ ${partLines.join(`
|
|
|
23930
24268
|
|
|
23931
24269
|
`), lastOrdinal, truncated };
|
|
23932
24270
|
}
|
|
23933
|
-
function
|
|
24271
|
+
function renderVerboseRangeForTool(sessionId, start, end, tokenBudget, expandTools, attachments) {
|
|
24272
|
+
const v = renderVerboseRange(sessionId, start, end, tokenBudget, expandTools, attachments);
|
|
24273
|
+
if (!v.text) {
|
|
24274
|
+
return `No messages found in range ${start}-${end}. The range may be outside this session's history.`;
|
|
24275
|
+
}
|
|
24276
|
+
const out = [
|
|
24277
|
+
`Messages ${start}-${v.lastOrdinal} (verbose). Recover any one in full with mmc_expand(message=<ordinal>):`,
|
|
24278
|
+
"",
|
|
24279
|
+
v.text
|
|
24280
|
+
];
|
|
24281
|
+
if (v.truncated) {
|
|
24282
|
+
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${tokenBudget} tokens). Call again with start=${v.lastOrdinal + 1} end=${end} verbose=true for more.`);
|
|
24283
|
+
}
|
|
24284
|
+
return out.join(`
|
|
24285
|
+
`);
|
|
24286
|
+
}
|
|
24287
|
+
function renderItemByTag(db, sessionId, number, textIndexDomain = "part", attachments) {
|
|
23934
24288
|
const tag = getTagById(db, sessionId, number);
|
|
23935
24289
|
if (!tag)
|
|
23936
24290
|
return `no tag ${number} in this session; if ${number} came from a <session-history> heading or a ctx_search hit, it is an ordinal: use message=${number}`;
|
|
@@ -23955,17 +24309,19 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
23955
24309
|
return rendered.length ? rendered.join(`
|
|
23956
24310
|
`) : `Tag ${number}'s original tool call is no longer in stored history.`;
|
|
23957
24311
|
}
|
|
23958
|
-
const scoped = /^(.*):p(\d+)$/.exec(tag.messageId);
|
|
24312
|
+
const scoped = /^(.*):(?:p|file)(\d+)$/.exec(tag.messageId);
|
|
23959
24313
|
const derived = /^(.*):mc-text-v1:([a-f0-9]+):([a-f0-9]+):o(\d+)$/.exec(tag.messageId);
|
|
23960
24314
|
const owner = scoped?.[1] ?? derived?.[1] ?? tag.messageId;
|
|
23961
24315
|
const message = readRawSessionMessageById2(sessionId, owner);
|
|
23962
24316
|
if (!message)
|
|
23963
24317
|
return `Tag ${number}'s original text is no longer in stored history.`;
|
|
23964
24318
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
23965
|
-
const
|
|
23966
|
-
const
|
|
24319
|
+
const attached = attachments?.(sessionId, message.id) ?? [];
|
|
24320
|
+
const parts = [...message.parts, ...attached];
|
|
24321
|
+
const piText = parts.filter((part) => isRecord4(part) && part.type === "text");
|
|
24322
|
+
const part = tag.type === "file" ? attached.find((part) => isRecord4(part) && part.partIndex === index) ?? message.parts[index] : parts[index];
|
|
23967
24323
|
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" && createHash5("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
23968
|
-
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
24324
|
+
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" && tag.type !== "file" ? piText[index] : part;
|
|
23969
24325
|
if (!selected)
|
|
23970
24326
|
return `Tag ${number}'s original text part is no longer in stored history.`;
|
|
23971
24327
|
const renderedPart = renderPartFull(selected);
|
|
@@ -24053,10 +24409,10 @@ function createCtxExpandTool(deps) {
|
|
|
24053
24409
|
return mode.message;
|
|
24054
24410
|
}
|
|
24055
24411
|
if (mode.kind === "tag") {
|
|
24056
|
-
return renderItemByTag(deps.db, sessionId, mode.tag);
|
|
24412
|
+
return renderItemByTag(deps.db, sessionId, mode.tag, "part", deps.recoveryAttachments);
|
|
24057
24413
|
}
|
|
24058
24414
|
if (mode.kind === "message") {
|
|
24059
|
-
return renderSearchArchive(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal(sessionId, mode.message);
|
|
24415
|
+
return renderSearchArchive(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal(sessionId, mode.message, deps.recoveryAttachments);
|
|
24060
24416
|
}
|
|
24061
24417
|
const { start, end, verbose } = mode;
|
|
24062
24418
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
@@ -24068,20 +24424,7 @@ function createCtxExpandTool(deps) {
|
|
|
24068
24424
|
if (archived)
|
|
24069
24425
|
return archived;
|
|
24070
24426
|
if (verbose) {
|
|
24071
|
-
|
|
24072
|
-
if (!v.text) {
|
|
24073
|
-
return `No messages found in range ${start}-${effectiveEnd}. The range may be outside this session's history.`;
|
|
24074
|
-
}
|
|
24075
|
-
const out = [
|
|
24076
|
-
`Messages ${start}-${v.lastOrdinal} (verbose). Recover any one in full with mmc_expand(message=<ordinal>):`,
|
|
24077
|
-
"",
|
|
24078
|
-
v.text
|
|
24079
|
-
];
|
|
24080
|
-
if (v.truncated) {
|
|
24081
|
-
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
|
|
24082
|
-
}
|
|
24083
|
-
return out.join(`
|
|
24084
|
-
`);
|
|
24427
|
+
return renderVerboseRangeForTool(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools, deps.recoveryAttachments);
|
|
24085
24428
|
}
|
|
24086
24429
|
const chunk = readSessionChunk2(sessionId, CTX_EXPAND_TOKEN_BUDGET, start, effectiveEnd + 1, { expand: false });
|
|
24087
24430
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
@@ -24296,10 +24639,10 @@ function updateMemoryContentInCurrentTransaction(db, memory, content, normalized
|
|
|
24296
24639
|
clearMemoryVerifications(db, memory.id);
|
|
24297
24640
|
}
|
|
24298
24641
|
var ctxMemoryArgsShape = {
|
|
24299
|
-
action: tool2.schema.enum([...CTX_MEMORY_ACTIONS]).
|
|
24300
|
-
content: tool2.schema.string().
|
|
24301
|
-
category: tool2.schema.enum([...V2_MEMORY_CATEGORIES]).
|
|
24302
|
-
ids: tool2.schema.array(tool2.schema.number()).
|
|
24642
|
+
action: tool2.schema.enum([...CTX_MEMORY_ACTIONS]).describe("write | update | archive | merge | get"),
|
|
24643
|
+
content: tool2.schema.string().describe("The memory text — one standalone fact (write, update, merge)."),
|
|
24644
|
+
category: tool2.schema.enum([...V2_MEMORY_CATEGORIES]).describe("Kind of fact (required for write; on update/merge, pass the memory's current category to keep it)."),
|
|
24645
|
+
ids: tool2.schema.array(tool2.schema.number()).describe("Memory ids from <project-memory>: one for update, one or more for archive, two or more for merge, 1–20 for get."),
|
|
24303
24646
|
reason: tool2.schema.string().optional().describe("Why it is being archived (optional).")
|
|
24304
24647
|
};
|
|
24305
24648
|
var ctxMemoryArgsSchema = tool2.schema.object({ ...ctxMemoryArgsShape }).passthrough();
|
|
@@ -24657,7 +25000,7 @@ function renderGlance(notes, options) {
|
|
|
24657
25000
|
const remaining = ordered.length - options.offset - page.length;
|
|
24658
25001
|
const footer = remaining > 0 ? `
|
|
24659
25002
|
|
|
24660
|
-
Showing ${page.length} of ${ordered.length} — ${remaining} older: mmc_note(action="read", offset=${options.offset + page.length})` : "";
|
|
25003
|
+
Showing ${page.length} of ${ordered.length} — ${remaining} older: mmc_note(action="read", content="", note_ids=[], offset=${options.offset + page.length})` : "";
|
|
24661
25004
|
return `## Notes
|
|
24662
25005
|
|
|
24663
25006
|
${rows}${footer}`;
|
|
@@ -24695,7 +25038,7 @@ function captureAnchorOrdinal(db, sessionId) {
|
|
|
24695
25038
|
}
|
|
24696
25039
|
var DISMISS_FOOTER = `
|
|
24697
25040
|
|
|
24698
|
-
To dismiss a stale note: mmc_note(action="dismiss", note_ids=[N])`;
|
|
25041
|
+
To dismiss a stale note: mmc_note(action="dismiss", note_ids=[N], content="")`;
|
|
24699
25042
|
var DEFAULT_READ_LIMIT = 25;
|
|
24700
25043
|
function readGlanceNotes(args) {
|
|
24701
25044
|
if (args.filter === undefined) {
|
|
@@ -24725,12 +25068,12 @@ function noteAuthorityRefusal(action) {
|
|
|
24725
25068
|
return renderCapabilityRefusal(isMutation ? "note_change" : "note_access");
|
|
24726
25069
|
}
|
|
24727
25070
|
var ctxNoteArgsShape = {
|
|
24728
|
-
action: tool3.schema.enum(["write", "read", "dismiss", "update"]).
|
|
24729
|
-
content: tool3.schema.string().
|
|
25071
|
+
action: tool3.schema.enum(["write", "read", "dismiss", "update"]).describe("write | read | update | dismiss."),
|
|
25072
|
+
content: tool3.schema.string().describe("Note text for write/update: first line is the title (under 80 chars), then the detail."),
|
|
24730
25073
|
filter: tool3.schema.enum(["all", "active", "dismissed"]).optional().describe("Read filter: active (default), all, dismissed."),
|
|
24731
25074
|
limit: tool3.schema.number().optional().describe("Rows per read (default 25)."),
|
|
24732
25075
|
offset: tool3.schema.number().optional().describe("Skip this many newest rows (default 0)."),
|
|
24733
|
-
note_ids: tool3.schema.array(tool3.schema.number().int().min(1)).
|
|
25076
|
+
note_ids: tool3.schema.array(tool3.schema.number().int().min(1)).max(50).describe("Note ids: one for update, 1–50 for dismiss, or 1–50 to read those notes in full. Write and a plain read take an empty list.")
|
|
24734
25077
|
};
|
|
24735
25078
|
var ctxNoteArgsSchema = tool3.schema.object(ctxNoteArgsShape).passthrough();
|
|
24736
25079
|
function formatDismissResults(results) {
|
|
@@ -24769,7 +25112,8 @@ function createCtxNoteTool(deps) {
|
|
|
24769
25112
|
});
|
|
24770
25113
|
const sessionId = toolContext.sessionID;
|
|
24771
25114
|
const action = args.action ?? (args.content?.trim() ? "write" : "read");
|
|
24772
|
-
const
|
|
25115
|
+
const targetedReadIds = action === "read" && Array.isArray(args.note_ids) && args.note_ids.length === 0 ? undefined : args.note_ids;
|
|
25116
|
+
const noteIds = action === "dismiss" || action === "update" || action === "read" && targetedReadIds !== undefined ? parseNoteIds(action, targetedReadIds) : undefined;
|
|
24773
25117
|
if (typeof noteIds === "string")
|
|
24774
25118
|
return noteIds;
|
|
24775
25119
|
const projectIdentity = deps.resolveProjectPath?.(toolContext.directory);
|
|
@@ -25511,16 +25855,23 @@ function applyV2PromptSurfaceTools(draft, runtime, config) {
|
|
|
25511
25855
|
function recordV2ToolDefinitions(draft) {
|
|
25512
25856
|
if (!draft.tools)
|
|
25513
25857
|
return;
|
|
25858
|
+
const tools = [];
|
|
25514
25859
|
for (const [id, tool] of Object.entries(draft.tools)) {
|
|
25515
25860
|
if (!tool)
|
|
25516
25861
|
continue;
|
|
25517
25862
|
recordToolParameters(id, tool.input);
|
|
25518
|
-
|
|
25863
|
+
tools.push({
|
|
25864
|
+
id,
|
|
25865
|
+
description: typeof tool.description === "string" ? tool.description : "",
|
|
25866
|
+
parameters: tool.input
|
|
25867
|
+
});
|
|
25519
25868
|
}
|
|
25869
|
+
recordToolDefinitionSet(draft.model.providerID, draft.model.id, draft.agent, tools, draft.sessionID);
|
|
25520
25870
|
}
|
|
25521
25871
|
async function registerContext(context) {
|
|
25522
25872
|
const directory = context.location.directory;
|
|
25523
25873
|
const config = loadPluginConfigDetailed(directory).config;
|
|
25874
|
+
log(`[magic-context] OpenCode 2 keep_subagents=${config.keep_subagents === true}`);
|
|
25524
25875
|
setHomeProjectPermission(config.allow_home_project);
|
|
25525
25876
|
if (!config.enabled)
|
|
25526
25877
|
return;
|
|
@@ -25642,6 +25993,7 @@ async function registerContext(context) {
|
|
|
25642
25993
|
};
|
|
25643
25994
|
let hiddenAgentsReady;
|
|
25644
25995
|
const readerPool = new V2StoreReaderPool;
|
|
25996
|
+
const messageTimesCache = new V2MessageTimesCache;
|
|
25645
25997
|
const openStoreReader = () => readerPool.open(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
25646
25998
|
const createHiddenExecutor = async (database) => {
|
|
25647
25999
|
await cleanupLegacyOnce(database);
|
|
@@ -25762,17 +26114,11 @@ async function registerContext(context) {
|
|
|
25762
26114
|
}
|
|
25763
26115
|
});
|
|
25764
26116
|
const pagedRead = createV2RawMessageReader(openStoreReader);
|
|
25765
|
-
let orphanSweep;
|
|
25766
|
-
let orphanSweepTimer;
|
|
25767
26117
|
const prepareHistorySession = (sessionID) => {
|
|
25768
26118
|
if (!rawProviders.has(sessionID))
|
|
25769
26119
|
rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID, createV2RawMessageProvider(pagedRead, sessionID)));
|
|
25770
26120
|
};
|
|
25771
26121
|
if (db && isDatabasePersisted(db)) {
|
|
25772
|
-
const sweepDb = db;
|
|
25773
|
-
orphanSweepTimer = scheduleAfterBootQuiet(() => {
|
|
25774
|
-
orphanSweep = sweepOrphanedOpenCodeMessageIndexesCooperatively(sweepDb, () => new Database(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), { readonly: true, fileMustExist: true })).catch((error) => log("[magic-context] v2 orphan sweep failed:", error));
|
|
25775
|
-
});
|
|
25776
26122
|
const backfillDb = db;
|
|
25777
26123
|
scheduleAfterBootQuiet(() => {
|
|
25778
26124
|
runV2SessionProjectBackfill(backfillDb, openStoreReader, config.allow_home_project).catch((error) => log("[session-project-backfill] OpenCode 2 backfill failed:", error));
|
|
@@ -25912,6 +26258,12 @@ async function registerContext(context) {
|
|
|
25912
26258
|
if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
|
|
25913
26259
|
nativeFoldReplay?.onEvent(event);
|
|
25914
26260
|
restoredRows.forget(sessionID);
|
|
26261
|
+
messageTimesCache.delete(sessionID);
|
|
26262
|
+
}
|
|
26263
|
+
if (event.type === "session.step.started" || event.type === "session.step.ended" || event.type === "session.step.failed") {
|
|
26264
|
+
const messageID = event.data.assistantMessageID;
|
|
26265
|
+
if (typeof messageID === "string")
|
|
26266
|
+
messageTimesCache.deleteMessage(sessionID, messageID);
|
|
25915
26267
|
}
|
|
25916
26268
|
if (event.type === "session.revert.committed") {
|
|
25917
26269
|
committedSourceRefreshes.set(sessionID, {});
|
|
@@ -25951,6 +26303,7 @@ async function registerContext(context) {
|
|
|
25951
26303
|
rawProviders.get(sessionID)?.();
|
|
25952
26304
|
rawProviders.delete(sessionID);
|
|
25953
26305
|
usage.delete(sessionID);
|
|
26306
|
+
messageTimesCache.delete(sessionID);
|
|
25954
26307
|
hiddenSessionErrors.delete(sessionID);
|
|
25955
26308
|
storageNoticeBySession.delete(sessionID);
|
|
25956
26309
|
liveModels.delete(sessionID);
|
|
@@ -26022,7 +26375,7 @@ async function registerContext(context) {
|
|
|
26022
26375
|
memoryInjectionBudgetTokens: config.memory.injection_budget_tokens,
|
|
26023
26376
|
hardSignals: {
|
|
26024
26377
|
systemHash: foldDigest(JSON.stringify(draft.system)),
|
|
26025
|
-
toolSetHash: getCurrentToolSetHash(draft.model.providerID, draft.model.id, draft.agent),
|
|
26378
|
+
toolSetHash: getCurrentToolSetHash(draft.model.providerID, draft.model.id, draft.agent, draft.sessionID),
|
|
26026
26379
|
modelKey: `${draft.model.providerID}/${draft.model.id}`,
|
|
26027
26380
|
cacheExpired: false,
|
|
26028
26381
|
lastResponseTime: state.lastResponseTime
|
|
@@ -26110,6 +26463,65 @@ async function registerContext(context) {
|
|
|
26110
26463
|
}
|
|
26111
26464
|
return ids;
|
|
26112
26465
|
};
|
|
26466
|
+
const initializeTransform = (database) => transform ??= createTransform({
|
|
26467
|
+
cacheTtlConfig: config.cache_ttl,
|
|
26468
|
+
cacheTtlConfigured: config.cacheTtlConfigured,
|
|
26469
|
+
sampleCacheTtlConfig: () => liveConfigReader.poll().effective,
|
|
26470
|
+
db: database,
|
|
26471
|
+
tagger,
|
|
26472
|
+
...createV2ThresholdDeps(config),
|
|
26473
|
+
contextUsageMap: usage,
|
|
26474
|
+
compactionOff,
|
|
26475
|
+
storeGeneration: "v2",
|
|
26476
|
+
normalizeRestoredAssistantText: (text, providerID) => {
|
|
26477
|
+
const normalized = stripCopiedTagNotation(text);
|
|
26478
|
+
return normalized === "" && !modelAcceptsEmptyContent(providerID) ? text : normalized;
|
|
26479
|
+
},
|
|
26480
|
+
refreshSourceContents: (sessionID) => committedSourceRefreshes.has(sessionID),
|
|
26481
|
+
hostCleanupCompactionMarkers: () => ({
|
|
26482
|
+
verified: true,
|
|
26483
|
+
removedLineages: 0,
|
|
26484
|
+
removedRows: 0,
|
|
26485
|
+
retainedLineages: 0
|
|
26486
|
+
}),
|
|
26487
|
+
protectedTokens: config.protected_tokens,
|
|
26488
|
+
protectedTokenTierOverrides: getProtectedTokensTierOverrides(config),
|
|
26489
|
+
protectedTools: config.protected_tools,
|
|
26490
|
+
liveModelBySession: liveModels,
|
|
26491
|
+
getToolSetHash: (sessionId) => {
|
|
26492
|
+
const model = liveModels.get(sessionId);
|
|
26493
|
+
if (!model)
|
|
26494
|
+
return "";
|
|
26495
|
+
return getCurrentToolSetHash(model.providerID, model.modelID, agents.get(sessionId), sessionId);
|
|
26496
|
+
},
|
|
26497
|
+
channel1StateBySession: channel1,
|
|
26498
|
+
historyRefreshSessions,
|
|
26499
|
+
pendingMaterializationSessions,
|
|
26500
|
+
lastHeuristicsTurnId,
|
|
26501
|
+
variantBySession: variants,
|
|
26502
|
+
keepReasoningTokens: config.keep_reasoning_tokens,
|
|
26503
|
+
directory,
|
|
26504
|
+
sessionDirectoryBySession: sessionDirectories,
|
|
26505
|
+
projectPath: directory,
|
|
26506
|
+
agentBySession: agents,
|
|
26507
|
+
maintenanceConfig: config.maintenance ? () => inheritMaintenanceModelConfig(config) : undefined,
|
|
26508
|
+
hiddenCompletionExecutor,
|
|
26509
|
+
historianRunnable: !compactionOff && hiddenCompletionExecutor !== undefined && config.historian?.disable !== true,
|
|
26510
|
+
historianModel: historianModels.primary,
|
|
26511
|
+
fallbackModels: historianModels.fallbacks,
|
|
26512
|
+
resolveHistorianRun: sampleHistorian,
|
|
26513
|
+
historianTimeoutMs: config.historian_timeout_ms,
|
|
26514
|
+
historianMaxOutputTokens: config.historian?.maxTokens,
|
|
26515
|
+
historianTwoPass: config.historian?.two_pass,
|
|
26516
|
+
historianExpandTools: config.historian?.expand_tools,
|
|
26517
|
+
compactionMarkerStrategy: v2CompactionMarkerStrategy,
|
|
26518
|
+
memoryConfig: {
|
|
26519
|
+
enabled: config.memory.enabled,
|
|
26520
|
+
injectionBudgetTokens: config.memory.injection_budget_tokens,
|
|
26521
|
+
autoPromote: config.memory.auto_promote
|
|
26522
|
+
},
|
|
26523
|
+
...createHostSeams(context, readAllForConversion, pagedRead, liveModels)
|
|
26524
|
+
});
|
|
26113
26525
|
const runManagedContext = async (draft) => {
|
|
26114
26526
|
rememberHostMedia(draft.messages);
|
|
26115
26527
|
if (hiddenChildHook.apply(draft))
|
|
@@ -26139,22 +26551,9 @@ async function registerContext(context) {
|
|
|
26139
26551
|
}
|
|
26140
26552
|
await dropStorageNotices(draft.messages, isMagicContextSynthetic);
|
|
26141
26553
|
let hostMessagesAtEntry = [...draft.messages];
|
|
26142
|
-
const
|
|
26554
|
+
const cachedTimes = messageTimesCache.pass(draft.sessionID);
|
|
26143
26555
|
const readTimes = (reader, messages) => {
|
|
26144
|
-
|
|
26145
|
-
const missing = ids.filter((id) => !passTimes.has(id));
|
|
26146
|
-
if (missing.length) {
|
|
26147
|
-
const read = reader.messageTimes(draft.sessionID, missing);
|
|
26148
|
-
for (const id of missing)
|
|
26149
|
-
passTimes.set(id, read.get(id) ?? null);
|
|
26150
|
-
}
|
|
26151
|
-
const times = new Map;
|
|
26152
|
-
for (const id of ids) {
|
|
26153
|
-
const time = passTimes.get(id);
|
|
26154
|
-
if (time)
|
|
26155
|
-
times.set(id, time);
|
|
26156
|
-
}
|
|
26157
|
-
return times;
|
|
26556
|
+
return cachedTimes(reader, timeIds(messages));
|
|
26158
26557
|
};
|
|
26159
26558
|
liveModels.set(draft.sessionID, {
|
|
26160
26559
|
providerID: draft.model.providerID,
|
|
@@ -26405,65 +26804,7 @@ async function registerContext(context) {
|
|
|
26405
26804
|
}
|
|
26406
26805
|
});
|
|
26407
26806
|
}
|
|
26408
|
-
transform
|
|
26409
|
-
cacheTtlConfig: config.cache_ttl,
|
|
26410
|
-
cacheTtlConfigured: config.cacheTtlConfigured,
|
|
26411
|
-
sampleCacheTtlConfig: () => liveConfigReader.poll().effective,
|
|
26412
|
-
db,
|
|
26413
|
-
tagger,
|
|
26414
|
-
...createV2ThresholdDeps(config),
|
|
26415
|
-
contextUsageMap: usage,
|
|
26416
|
-
compactionOff,
|
|
26417
|
-
storeGeneration: "v2",
|
|
26418
|
-
normalizeRestoredAssistantText: (text, providerID) => {
|
|
26419
|
-
const normalized = stripCopiedTagNotation(text);
|
|
26420
|
-
return normalized === "" && !modelAcceptsEmptyContent(providerID) ? text : normalized;
|
|
26421
|
-
},
|
|
26422
|
-
refreshSourceContents: (sessionID) => committedSourceRefreshes.has(sessionID),
|
|
26423
|
-
hostCleanupCompactionMarkers: () => ({
|
|
26424
|
-
verified: true,
|
|
26425
|
-
removedLineages: 0,
|
|
26426
|
-
removedRows: 0,
|
|
26427
|
-
retainedLineages: 0
|
|
26428
|
-
}),
|
|
26429
|
-
protectedTokens: config.protected_tokens,
|
|
26430
|
-
protectedTokenTierOverrides: getProtectedTokensTierOverrides(config),
|
|
26431
|
-
protectedTools: config.protected_tools,
|
|
26432
|
-
liveModelBySession: liveModels,
|
|
26433
|
-
getToolSetHash: (sessionId) => {
|
|
26434
|
-
const model = liveModels.get(sessionId);
|
|
26435
|
-
if (!model)
|
|
26436
|
-
return "";
|
|
26437
|
-
return getCurrentToolSetHash(model.providerID, model.modelID, agents.get(sessionId));
|
|
26438
|
-
},
|
|
26439
|
-
channel1StateBySession: channel1,
|
|
26440
|
-
historyRefreshSessions,
|
|
26441
|
-
pendingMaterializationSessions,
|
|
26442
|
-
lastHeuristicsTurnId,
|
|
26443
|
-
variantBySession: variants,
|
|
26444
|
-
keepReasoningTokens: config.keep_reasoning_tokens,
|
|
26445
|
-
directory,
|
|
26446
|
-
sessionDirectoryBySession: sessionDirectories,
|
|
26447
|
-
projectPath: directory,
|
|
26448
|
-
agentBySession: agents,
|
|
26449
|
-
maintenanceConfig: config.maintenance ? () => inheritMaintenanceModelConfig(config) : undefined,
|
|
26450
|
-
hiddenCompletionExecutor,
|
|
26451
|
-
historianRunnable: !compactionOff && hiddenCompletionExecutor !== undefined && config.historian?.disable !== true,
|
|
26452
|
-
historianModel: historianModels.primary,
|
|
26453
|
-
fallbackModels: historianModels.fallbacks,
|
|
26454
|
-
resolveHistorianRun: sampleHistorian,
|
|
26455
|
-
historianTimeoutMs: config.historian_timeout_ms,
|
|
26456
|
-
historianMaxOutputTokens: config.historian?.maxTokens,
|
|
26457
|
-
historianTwoPass: config.historian?.two_pass,
|
|
26458
|
-
historianExpandTools: config.historian?.expand_tools,
|
|
26459
|
-
compactionMarkerStrategy: v2CompactionMarkerStrategy,
|
|
26460
|
-
memoryConfig: {
|
|
26461
|
-
enabled: config.memory.enabled,
|
|
26462
|
-
injectionBudgetTokens: config.memory.injection_budget_tokens,
|
|
26463
|
-
autoPromote: config.memory.auto_promote
|
|
26464
|
-
},
|
|
26465
|
-
...createHostSeams(context, readAllForConversion, pagedRead, liveModels)
|
|
26466
|
-
});
|
|
26807
|
+
transform = initializeTransform(db);
|
|
26467
26808
|
const refreshToken = committedSourceRefreshes.get(draft.sessionID);
|
|
26468
26809
|
if (refreshToken) {
|
|
26469
26810
|
clearCachedM0(db, draft.sessionID);
|
|
@@ -26762,12 +27103,10 @@ async function registerContext(context) {
|
|
|
26762
27103
|
}, 0);
|
|
26763
27104
|
return {
|
|
26764
27105
|
async dispose() {
|
|
27106
|
+
messageTimesCache.clear();
|
|
26765
27107
|
usageController.abort();
|
|
26766
|
-
if (orphanSweepTimer)
|
|
26767
|
-
clearTimeout(orphanSweepTimer);
|
|
26768
27108
|
await hiddenCompletionExecutor?.dispose();
|
|
26769
27109
|
await usageDone;
|
|
26770
|
-
await orphanSweep;
|
|
26771
27110
|
rpcStopped = true;
|
|
26772
27111
|
rpcServer.stop();
|
|
26773
27112
|
tools?.dispose();
|