@cortexkit/opencode-magic-context 0.41.0 → 0.41.2
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/config/schema/magic-context.d.ts +15 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-xj1r88a7.js → conflict-warning-hook-rf17b6et.js} +3 -3
- package/dist/{derive-budgets-3xfyphvk.js → derive-budgets-9q2d3r93.js} +2 -2
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +16 -17
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/curate-memory-safety.d.ts +21 -0
- package/dist/features/magic-context/dreamer/curate-memory-safety.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +1 -6
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-failure.d.ts +10 -2
- package/dist/features/magic-context/memory/embedding-failure.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +19 -2
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-synapse.d.ts +10 -1
- package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/onnxruntime-node-wasm-shim.d.ts +3 -0
- package/dist/features/magic-context/memory/onnxruntime-node-wasm-shim.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts +4 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/sharp-wasm-shim.d.ts +2 -0
- package/dist/features/magic-context/memory/sharp-wasm-shim.d.ts.map +1 -0
- package/dist/features/magic-context/memory/transformers-node-wasm-entry.d.ts +3 -0
- package/dist/features/magic-context/memory/transformers-node-wasm-entry.d.ts.map +1 -0
- package/dist/features/magic-context/memory/transformers-web-entry.d.ts +2 -0
- package/dist/features/magic-context/memory/transformers-web-entry.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts +28 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +15 -2
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +18 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +2 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +19 -2
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +3 -2
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +2 -2
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-ops.d.ts +2 -0
- package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +9 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +13 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +3 -0
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +4 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +3 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +3 -1
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +9 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +13 -37
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +12 -5
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-id-fallback.d.ts +3 -1
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +28 -2
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-b4gv9f7g.js → index-4x691bz5.js} +87 -2
- package/dist/{index-knna83k0.js → index-9j3tx8hy.js} +1 -1
- package/dist/{index-jmwq2wxr.js → index-b9j85d29.js} +1 -1
- package/dist/{index-2bykz3bx.js → index-cvda5jb3.js} +7 -2
- package/dist/{index-bf799gbq.js → index-d1mxrd3p.js} +0 -1
- package/dist/{index-dmgbar7r.js → index-eq9wr75c.js} +2 -2
- package/dist/{index-w8rkbhn6.js → index-j8r0ejb3.js} +1232 -261
- package/dist/{index-26ds03jd.js → index-vnz6jvdc.js} +1 -1
- package/dist/{index-x9dmzyp5.js → index-y1yr57fw.js} +81 -17
- package/dist/{index-88za3sz8.js → index-zwjhba2r.js} +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1771 -1109
- package/dist/{model-resolution-jgrkt0z2.js → model-resolution-6w6wzw18.js} +1 -1
- package/dist/plugin/dream-timer.d.ts +4 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-routing.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-1w4xj6jt.js → recomp-orchestrator-m37p3fq6.js} +6 -6
- package/dist/{safe-notification-target-p0c0csxw.js → safe-notification-target-2a8py95v.js} +2 -2
- package/dist/{send-session-notification-kn34g7mx.js → send-session-notification-bw7eex6w.js} +3 -3
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/model-resolution.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +3 -1
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/summarize-child-stderr.d.ts +2 -0
- package/dist/shared/summarize-child-stderr.d.ts.map +1 -0
- package/dist/shared/test-temp-dir.d.ts +40 -0
- package/dist/shared/test-temp-dir.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +2 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/{storage-meta-session-snbzd26z.js → storage-meta-session-dse3qv6s.js} +5 -3
- package/dist/{task-config-ty08ptc2.js → task-config-gv6s04fp.js} +2 -2
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/types.d.ts +2 -0
- package/dist/tools/ctx-memory/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/transformers-node-wasm.js +25676 -0
- package/dist/transformers-web.js +24570 -0
- package/dist/transformers.node-b1wa0hgx.js +28808 -0
- package/package.json +8 -3
- package/src/config/index.test.ts +50 -4
- package/src/config/latch-permanence-guard.test.ts +5 -0
- package/src/config/schema/magic-context.test.ts +20 -0
- package/src/config/schema/magic-context.ts +8 -0
- package/src/shared/conflict-detector.test.ts +6 -19
- package/src/shared/conflict-fixer.test.ts +5 -8
- package/src/shared/index.ts +1 -0
- package/src/shared/logger.test.ts +135 -40
- package/src/shared/logger.ts +115 -2
- package/src/shared/model-resolution.test.ts +21 -19
- package/src/shared/model-resolution.ts +0 -1
- package/src/shared/rpc-utils.test.ts +246 -5
- package/src/shared/rpc-utils.ts +340 -49
- package/src/shared/summarize-child-stderr.test.ts +55 -0
- package/src/shared/summarize-child-stderr.ts +33 -0
- package/src/shared/test-temp-dir.test.ts +57 -0
- package/src/shared/test-temp-dir.ts +165 -0
- package/src/shared/window-geometry.ts +9 -0
- /package/dist/{index-rpgg35ms.js → index-8sseka65.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ANNOUNCEMENT_FEATURES,
|
|
3
|
+
ANNOUNCEMENT_FOOTER,
|
|
4
|
+
ANNOUNCEMENT_VERSION,
|
|
5
|
+
compareSemverCore,
|
|
6
|
+
isValidSemver,
|
|
7
|
+
markAnnouncementSeen,
|
|
8
|
+
shouldShowAnnouncement
|
|
9
|
+
} from "./index-dmvy29z0.js";
|
|
1
10
|
import {
|
|
2
11
|
CANONICAL_DREAM_TASKS,
|
|
3
12
|
buildDreamTaskRuntimeConfigs,
|
|
@@ -8,12 +17,12 @@ import {
|
|
|
8
17
|
leaseKindFor,
|
|
9
18
|
processedDreamTaskItems,
|
|
10
19
|
userMemoryCollectionEnabled
|
|
11
|
-
} from "./index-
|
|
20
|
+
} from "./index-9j3tx8hy.js";
|
|
12
21
|
import {
|
|
13
22
|
resolveHistorianAgentOverrides,
|
|
14
23
|
resolveHistorianModel,
|
|
15
24
|
resolveOpenCodeAgentOverrides
|
|
16
|
-
} from "./index-
|
|
25
|
+
} from "./index-d1mxrd3p.js";
|
|
17
26
|
import {
|
|
18
27
|
AGE_RECLAIM_MIN_TOKENS,
|
|
19
28
|
AdmissionClass,
|
|
@@ -46,6 +55,7 @@ import {
|
|
|
46
55
|
MAX_EXECUTE_THRESHOLD,
|
|
47
56
|
MagicContextConfigSchema,
|
|
48
57
|
ModuleMemoryAuthorityError,
|
|
58
|
+
NEWEST_REASONING_BEARING_ASSISTANT,
|
|
49
59
|
PER_HARNESS_MIGRATION_INVENTORY,
|
|
50
60
|
PRIMER_CANDIDATE_MAX_AGE_MS,
|
|
51
61
|
PRIMER_CANDIDATE_TTL_MS,
|
|
@@ -58,6 +68,7 @@ import {
|
|
|
58
68
|
StaleRouteHandleError,
|
|
59
69
|
SubcClient,
|
|
60
70
|
SynapseEmbeddingProvider,
|
|
71
|
+
THINKING_BINDING_RECOVERY_FROZEN_PREFIX,
|
|
61
72
|
ToolMutationBatch,
|
|
62
73
|
USER_MEMORY_CANDIDATE_TTL_MS,
|
|
63
74
|
V2_MEMORY_CATEGORIES,
|
|
@@ -76,6 +87,7 @@ import {
|
|
|
76
87
|
applyMirroredNoteCompileFields,
|
|
77
88
|
applyStrippedPlaceholderDelta,
|
|
78
89
|
archiveMemory,
|
|
90
|
+
armThinkingBindingRecovery,
|
|
79
91
|
assertTailHygieneContentUnchanged,
|
|
80
92
|
backfillTagTokenCounts,
|
|
81
93
|
beginBootQuietPeriod,
|
|
@@ -114,6 +126,7 @@ import {
|
|
|
114
126
|
clearPersistedReasoningWatermark,
|
|
115
127
|
clearPersistedTodoSyntheticAnchor,
|
|
116
128
|
clearRecompStaging,
|
|
129
|
+
clearThinkingBindingRecoveryIf,
|
|
117
130
|
computeCueContentHash,
|
|
118
131
|
computeNormalizedHash,
|
|
119
132
|
computeSyntheticCallId,
|
|
@@ -139,6 +152,8 @@ import {
|
|
|
139
152
|
demoteTrailingBlankKeepDecisions,
|
|
140
153
|
deriveTagLoadFloor,
|
|
141
154
|
detectOverflow,
|
|
155
|
+
detectThinkingBindingMismatch,
|
|
156
|
+
directoryHasGitMetadata,
|
|
142
157
|
dismissNote,
|
|
143
158
|
dismissUserMemory,
|
|
144
159
|
drainAuthority,
|
|
@@ -177,6 +192,7 @@ import {
|
|
|
177
192
|
getActiveTagsBySession,
|
|
178
193
|
getActiveToolTagsForAgeReclaim,
|
|
179
194
|
getActiveUserMemories,
|
|
195
|
+
getAssignableTagNumberByMessageId,
|
|
180
196
|
getAuthorityManagedMarker,
|
|
181
197
|
getAutoSearchHintDecisions,
|
|
182
198
|
getCandidateToolOwners,
|
|
@@ -196,6 +212,7 @@ import {
|
|
|
196
212
|
getEmergencyRecoveryArmedAt,
|
|
197
213
|
getHistorianFailureState,
|
|
198
214
|
getIndexedMessageCorpusSize,
|
|
215
|
+
getInertWhitespaceAssistantTags,
|
|
199
216
|
getLastCompartmentEndMessage,
|
|
200
217
|
getLastCompartmentEndMessageId,
|
|
201
218
|
getLastHookInitFailure,
|
|
@@ -232,6 +249,7 @@ import {
|
|
|
232
249
|
getOverflowState,
|
|
233
250
|
getPendingCompactionMarkerState,
|
|
234
251
|
getPendingOps,
|
|
252
|
+
getPendingOpsCount,
|
|
235
253
|
getPendingSmartNotes,
|
|
236
254
|
getPersistedCompactionMarkerState,
|
|
237
255
|
getPersistedNoteNudge,
|
|
@@ -258,10 +276,12 @@ import {
|
|
|
258
276
|
getSourceContents,
|
|
259
277
|
getStaleReduceStrippedIds,
|
|
260
278
|
getStrippedPlaceholderIds,
|
|
279
|
+
getTagById,
|
|
261
280
|
getTagNumberByMessageId,
|
|
262
281
|
getTagsByNumbers,
|
|
263
282
|
getTagsBySession,
|
|
264
283
|
getTailHygieneTags,
|
|
284
|
+
getThinkingBindingRecoveryTarget,
|
|
265
285
|
getToolTagNumberByOwner,
|
|
266
286
|
getTrailingBlankDecisions,
|
|
267
287
|
getTriggerTagTokenUpperBound,
|
|
@@ -294,6 +314,7 @@ import {
|
|
|
294
314
|
isEditTool,
|
|
295
315
|
isEmbeddingEnabled,
|
|
296
316
|
isEmergencyRecoveryArmed,
|
|
317
|
+
isFable51ThinkingBindingModel,
|
|
297
318
|
isFailClosedBlockingError,
|
|
298
319
|
isFilePart,
|
|
299
320
|
isLinkedGitWorktree,
|
|
@@ -320,6 +341,7 @@ import {
|
|
|
320
341
|
markNoteNudgeDelivered,
|
|
321
342
|
markNoteReady,
|
|
322
343
|
markProjectLoadUntrusted,
|
|
344
|
+
markWhitespaceAssistantTagInert,
|
|
323
345
|
memoryNeedsCue,
|
|
324
346
|
mergeMemoryStats,
|
|
325
347
|
migrateMagicContextConfigLocations,
|
|
@@ -475,6 +497,7 @@ import {
|
|
|
475
497
|
tailHygieneStructuralSignature,
|
|
476
498
|
takeDubiousOwnershipProjectIdentityWarning,
|
|
477
499
|
textMentionsRecentCommit,
|
|
500
|
+
thinkingBindingRecoveryFrozenId,
|
|
478
501
|
toModelEntry,
|
|
479
502
|
toolOutputTokens,
|
|
480
503
|
trimMemoriesToBudgetV2,
|
|
@@ -494,7 +517,7 @@ import {
|
|
|
494
517
|
verificationFileExists,
|
|
495
518
|
withContentLanguageDirective,
|
|
496
519
|
withRawSessionMessageCache
|
|
497
|
-
} from "./index-
|
|
520
|
+
} from "./index-j8r0ejb3.js";
|
|
498
521
|
import {
|
|
499
522
|
deriveHistorianChunkTokens,
|
|
500
523
|
deriveTriggerBudget,
|
|
@@ -504,12 +527,13 @@ import {
|
|
|
504
527
|
isSaneLimit,
|
|
505
528
|
refreshModelLimitsAfterAuthOnce,
|
|
506
529
|
refreshModelLimitsFromApi,
|
|
530
|
+
reloadWindowOverlay,
|
|
507
531
|
resolveHistorianContextLimit,
|
|
508
532
|
setOutputReserveConfig,
|
|
509
533
|
setStoragePrivatePermissionEnforcement,
|
|
510
534
|
setWindowOverlayPath,
|
|
511
535
|
shouldEnforcePrivateStoragePermissions
|
|
512
|
-
} from "./index-
|
|
536
|
+
} from "./index-cvda5jb3.js";
|
|
513
537
|
import {
|
|
514
538
|
clearIgnoredMessages,
|
|
515
539
|
describeError,
|
|
@@ -517,16 +541,17 @@ import {
|
|
|
517
541
|
getErrorMessage,
|
|
518
542
|
sendIgnoredMessage,
|
|
519
543
|
sendUserPrompt
|
|
520
|
-
} from "./index-
|
|
544
|
+
} from "./index-zwjhba2r.js";
|
|
521
545
|
import {
|
|
522
546
|
advanceToolReclaimWatermark,
|
|
523
547
|
clearSession,
|
|
524
548
|
getOrCreateSessionMeta,
|
|
525
549
|
logSlowWriteTransaction,
|
|
526
550
|
markSessionCleanupPending,
|
|
551
|
+
retryPendingRustSessionCleanupsForProject,
|
|
527
552
|
retryPendingSessionCleanups,
|
|
528
553
|
updateSessionMeta
|
|
529
|
-
} from "./index-
|
|
554
|
+
} from "./index-y1yr57fw.js";
|
|
530
555
|
import {
|
|
531
556
|
modelRefLookupOrder,
|
|
532
557
|
piModelRefToCanonical
|
|
@@ -539,28 +564,19 @@ import {
|
|
|
539
564
|
isMidTurn,
|
|
540
565
|
openCodeDbExists,
|
|
541
566
|
withReadOnlySessionDb
|
|
542
|
-
} from "./index-
|
|
567
|
+
} from "./index-b9j85d29.js";
|
|
543
568
|
import {
|
|
544
569
|
cleanupConflictWarnings,
|
|
545
570
|
detectConflicts,
|
|
546
571
|
resolveCompactionForBoot,
|
|
547
572
|
sendConflictWarning
|
|
548
|
-
} from "./index-
|
|
573
|
+
} from "./index-eq9wr75c.js";
|
|
549
574
|
import {
|
|
550
575
|
detectConfigFile,
|
|
551
576
|
isPrototypePollutionKey,
|
|
552
577
|
parseJsonc,
|
|
553
578
|
stripJsonComments
|
|
554
579
|
} from "./index-8mtsfhyg.js";
|
|
555
|
-
import {
|
|
556
|
-
ANNOUNCEMENT_FEATURES,
|
|
557
|
-
ANNOUNCEMENT_FOOTER,
|
|
558
|
-
ANNOUNCEMENT_VERSION,
|
|
559
|
-
compareSemverCore,
|
|
560
|
-
isValidSemver,
|
|
561
|
-
markAnnouncementSeen,
|
|
562
|
-
shouldShowAnnouncement
|
|
563
|
-
} from "./index-dmvy29z0.js";
|
|
564
580
|
import {
|
|
565
581
|
acknowledgeNotifications,
|
|
566
582
|
drainNotifications,
|
|
@@ -568,13 +584,13 @@ import {
|
|
|
568
584
|
pushNotification,
|
|
569
585
|
registerNotificationSink
|
|
570
586
|
} from "./index-d62ypazr.js";
|
|
571
|
-
import"./index-
|
|
587
|
+
import"./index-vnz6jvdc.js";
|
|
572
588
|
import {
|
|
573
589
|
getLoggerDiagnostics,
|
|
574
590
|
hasShareabilitySensitiveText,
|
|
575
591
|
log,
|
|
576
592
|
sessionLog
|
|
577
|
-
} from "./index-
|
|
593
|
+
} from "./index-4x691bz5.js";
|
|
578
594
|
import {
|
|
579
595
|
getDataDir,
|
|
580
596
|
getHarness,
|
|
@@ -11861,15 +11877,15 @@ Project memory uses exactly 5 categories. Every memory belongs to one:
|
|
|
11861
11877
|
- **CONFIG_VALUES** — stable configuration keys/values and conventions. Not transient measurements (test counts, sizes, versions).
|
|
11862
11878
|
- **NAMING** — naming conventions and canonical names. Not inventories.
|
|
11863
11879
|
|
|
11864
|
-
**Legacy categories during transition:** older memories may still carry pre-v2 category names. When you touch one, map it to its 5-category home with \`action="update"\` (or \`merge\`): WORKFLOW_RULES→PROJECT_RULES, ARCHITECTURE_DECISIONS→ARCHITECTURE, CONFIG_DEFAULTS→CONFIG_VALUES, ENVIRONMENT→CONFIG_VALUES (paths) or CONSTRAINTS, KNOWN_ISSUES→CONSTRAINTS only if it's an external-system limit
|
|
11880
|
+
**Legacy categories during transition:** older memories may still carry pre-v2 category names. When you touch one, map it to its 5-category home with \`action="update"\` (or \`merge\`): WORKFLOW_RULES→PROJECT_RULES, ARCHITECTURE_DECISIONS→ARCHITECTURE, CONFIG_DEFAULTS→CONFIG_VALUES, ENVIRONMENT→CONFIG_VALUES (paths) or CONSTRAINTS, KNOWN_ISSUES→CONSTRAINTS only if it's an external-system limit. USER_DIRECTIVES / USER_PREFERENCES are NOT project categories. Do not compare project memories with the global user profile or use it to justify an archive.`;
|
|
11865
11881
|
var CURATE_SYSTEM_PROMPT = `You are a memory-pool curator for the magic-context system. You run during a scheduled dream window to keep a project's cross-session memory store lean and well-formed.
|
|
11866
11882
|
|
|
11867
11883
|
## Memory operations (ctx_memory)
|
|
11868
11884
|
- \`action="list"\` — browse active memories, optionally filter by category
|
|
11869
11885
|
- \`action="merge", ids=[N,M,...], content="...", category="..."\` — consolidate duplicates into one canonical memory
|
|
11870
|
-
- \`action="update", ids=[N], content="..."\` — rewrite
|
|
11886
|
+
- \`action="update", ids=[N], content="...", superseded_by=M\` — rewrite content; name where removed detail survives when cutting more than half
|
|
11871
11887
|
- \`action="write", category="...", content="..."\` — create a memory (SPLITS ONLY — never mint new facts)
|
|
11872
|
-
- \`action="archive", ids=[N], reason="..."\` —
|
|
11888
|
+
- \`action="archive", ids=[N], superseded_by=M, reason="..."\` — consolidate a redundant memory into the named active same-category survivor
|
|
11873
11889
|
|
|
11874
11890
|
## Rules
|
|
11875
11891
|
1. **Assume the pool is accurate.** A separate verify task checks memories against code. You handle QUALITY only — duplicates, wording, low-value entries — never correctness, and you do NOT read the codebase.
|
|
@@ -11912,34 +11928,25 @@ Mapped files: ${files}${memory.hasNoFileSentinel ? " (file-independent)" : ""}`;
|
|
|
11912
11928
|
|
|
11913
11929
|
`);
|
|
11914
11930
|
}
|
|
11915
|
-
function formatUserProfileList(userMemories) {
|
|
11916
|
-
if (!userMemories || userMemories.length === 0)
|
|
11917
|
-
return;
|
|
11918
|
-
return userMemories.map((um) => `- [U${um.id}] ${um.content}`).join(`
|
|
11919
|
-
`);
|
|
11920
|
-
}
|
|
11921
11931
|
function buildCuratePrompt(args) {
|
|
11922
11932
|
return `## Task: Curate Project Memory Pool (hygiene)
|
|
11923
11933
|
|
|
11924
11934
|
**Project:** ${args.projectPath}
|
|
11925
11935
|
|
|
11926
|
-
The memories below are assumed ACCURATE (a separate verify task keeps them true). Your job is pool QUALITY: remove duplicates, tighten wording, and
|
|
11936
|
+
The memories below are assumed ACCURATE (a separate verify task keeps them true). Your job is pool QUALITY: remove duplicates, tighten wording, and consolidate redundant entries that waste the ~6000-token injection budget. Explain each action in one line first. Do NOT mint new facts (that is the historian's job).
|
|
11927
11937
|
|
|
11928
11938
|
Work ALL THREE phases below in order (A → B → C) over the whole pool. Do NOT stop after consolidating — a run that only merges and never improves or archives is incomplete.
|
|
11929
11939
|
|
|
11930
11940
|
### Phase A — Consolidate duplicates
|
|
11931
|
-
Group by category, then merge near-identical / superset-subset / same-fact-different-angle clusters into one canonical memory with \`ctx_memory(action="merge", ids=[...], content="...", category="...")\`. Preserve every unique detail; terse present tense; paths/keys verbatim. Every id in a merge MUST share the same category — the system rejects cross-category merges. If two similar memories sit in different categories they are NOT duplicates
|
|
11941
|
+
Group by category, then merge near-identical / superset-subset / same-fact-different-angle clusters into one canonical memory with \`ctx_memory(action="merge", ids=[...], content="...", category="...")\`. Preserve every unique detail; terse present tense; paths/keys verbatim. Every id in a merge MUST share the same category — the system rejects cross-category merges. If two similar memories sit in different categories they are NOT duplicates; do not archive either as a consolidation. One fact per memory.
|
|
11932
11942
|
|
|
11933
11943
|
### Phase B — Improve wording
|
|
11934
|
-
Rewrite narrative/historical → operational present tense ("X uses Y because Z", not "we switched to Y"); drop session-local context and commit hashes (unless the hash is the point); add specifics where vague. \`write\` is for SPLITS ONLY (update the original down to its first fact, write the second) — a healthy run is net-neutral or net-shrinking, never net-adds facts.
|
|
11944
|
+
Rewrite narrative/historical → operational present tense ("X uses Y because Z", not "we switched to Y"); drop session-local context and commit hashes (unless the hash is the point); add specifics where vague. A rewrite that removes more than half the content must name the active same-category memory preserving that detail with \`superseded_by\`. \`write\` is for SPLITS ONLY (update the original down to its first fact, write the second) — a healthy run is net-neutral or net-shrinking, never net-adds facts.
|
|
11935
11945
|
|
|
11936
|
-
### Phase C — Archive
|
|
11937
|
-
Archive
|
|
11946
|
+
### Phase C — Archive only into a surviving project memory
|
|
11947
|
+
Archive a redundant memory only when a better ACTIVE memory in the same project and category preserves its information; name that survivor with \`superseded_by\`. A bare "redundant" verdict is deletion and will be refused. Leave standalone low-value or stale entries unchanged for a human to review. The global user profile describes the operator and is never a substitute for project knowledge, so it cannot justify an archive.
|
|
11938
11948
|
KEEP (overrides archive): constraint/rule language (must/never/always) · explains WHY (because/so that/to prevent) · EXTERNAL-system limit (CONSTRAINTS: archive only if word-for-word duplicated) · path/config WITH context · retrieval_count>0 · priority/philosophy.
|
|
11939
|
-
|
|
11940
|
-
### Global user profile (for the redundancy check)
|
|
11941
|
-
${args.userProfile}
|
|
11942
|
-
` : ""}
|
|
11949
|
+
|
|
11943
11950
|
### Memory pool
|
|
11944
11951
|
${renderMemoryList(args.memories)}`;
|
|
11945
11952
|
}
|
|
@@ -12148,8 +12155,7 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
12148
12155
|
case "curate":
|
|
12149
12156
|
return buildCuratePrompt({
|
|
12150
12157
|
projectPath: args.projectPath,
|
|
12151
|
-
memories: args.curate?.memories ?? []
|
|
12152
|
-
userProfile: formatUserProfileList(args.userMemories)
|
|
12158
|
+
memories: args.curate?.memories ?? []
|
|
12153
12159
|
});
|
|
12154
12160
|
case "maintain-docs":
|
|
12155
12161
|
return buildMaintainDocsPrompt(args.projectPath, args.lastDreamAt ?? null, args.existingDocs ?? { architecture: false, structure: false });
|
|
@@ -13401,6 +13407,7 @@ function showToast(ctx, title, message, variant = "info", duration = 3000) {
|
|
|
13401
13407
|
function createLiveSessionState() {
|
|
13402
13408
|
return {
|
|
13403
13409
|
liveModelBySession: new Map,
|
|
13410
|
+
latestAssistantMessageIdBySession: new Map,
|
|
13404
13411
|
variantBySession: new Map,
|
|
13405
13412
|
agentBySession: new Map,
|
|
13406
13413
|
channel1StateBySession: new Map,
|
|
@@ -16115,6 +16122,87 @@ function recordInvocation(args, startedAt, params) {
|
|
|
16115
16122
|
});
|
|
16116
16123
|
}
|
|
16117
16124
|
|
|
16125
|
+
// src/features/magic-context/dreamer/memory-claim-safety.ts
|
|
16126
|
+
var POLICY_SENTENCE_START = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:you\s+|we\s+)?(?:must(?:\s+not)?|never|always|do\s+not|don't|shall\s+not)\b/i;
|
|
16127
|
+
var ACTOR_POLICY = /\b(?:you|we|agents?|masons?|workers?|operators?|users?|maintainers?)\s+(?:must(?:\s+not)?|should(?:\s+not)?|need\s+to|shall(?:\s+not)?|cannot|can't|may\s+not)\b/i;
|
|
16128
|
+
var BEHAVIORAL_WHEN_CLAUSE = /\bwhen\s+(?:you(?:'re|\s+are)?|we(?:'re|\s+are)?|told|asked|requested|working|debugging|reviewing|checking|verifying|investigating|using|running|editing|changing)\b/i;
|
|
16129
|
+
var WORKFLOW_IMPERATIVE = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:please\s+)?(?:run|use|check|ask|avoid|prefer|ensure|keep|follow|brief|report|inspect|search|open|read|review|validate|confirm|delegate|stop|start|remember)\b/i;
|
|
16130
|
+
var DECISION_AUTHORITY = /\b(?:the\s+)?(?:user|operator|maintainer|owner)\s+(?:decides|chooses|approves|has\s+(?:the\s+)?final\s+say)\b/i;
|
|
16131
|
+
function isDirectiveShapedProjectRule(category, content) {
|
|
16132
|
+
if (category !== "PROJECT_RULES")
|
|
16133
|
+
return false;
|
|
16134
|
+
const text = content.trim();
|
|
16135
|
+
if (!text)
|
|
16136
|
+
return false;
|
|
16137
|
+
return POLICY_SENTENCE_START.test(text) || ACTOR_POLICY.test(text) || BEHAVIORAL_WHEN_CLAUSE.test(text) || WORKFLOW_IMPERATIVE.test(text) || DECISION_AUTHORITY.test(text);
|
|
16138
|
+
}
|
|
16139
|
+
|
|
16140
|
+
// src/features/magic-context/dreamer/curate-memory-safety.ts
|
|
16141
|
+
var PROJECT_SCOPED_CATEGORIES = new Set([
|
|
16142
|
+
"PROJECT_RULES",
|
|
16143
|
+
"ARCHITECTURE",
|
|
16144
|
+
"CONSTRAINTS",
|
|
16145
|
+
"CONFIG_VALUES",
|
|
16146
|
+
"NAMING"
|
|
16147
|
+
]);
|
|
16148
|
+
var USER_PROFILE_REFERENCE = /\buser(?:[\s_-]+)(?:profile|preferences?)\b|\bU\d+\b/i;
|
|
16149
|
+
var refusalCountsBySession = new Map;
|
|
16150
|
+
function isSurvivingConsolidationTarget(memory, successor, projectIdentity) {
|
|
16151
|
+
return successor !== null && successor.id !== memory.id && successor.status === "active" && successor.supersededByMemoryId === null && (successor.expiresAt === null || successor.expiresAt > Date.now()) && projectIdentity(successor) === projectIdentity(memory) && successor.category === memory.category;
|
|
16152
|
+
}
|
|
16153
|
+
function assessCurateMutationSafety(args) {
|
|
16154
|
+
const { memory, successor, verdict } = args;
|
|
16155
|
+
if (verdict === "archive") {
|
|
16156
|
+
if (!isSurvivingConsolidationTarget(memory, successor, args.projectIdentity)) {
|
|
16157
|
+
return {
|
|
16158
|
+
memoryId: memory.id,
|
|
16159
|
+
verdict,
|
|
16160
|
+
reason: "missing-active-same-category-successor"
|
|
16161
|
+
};
|
|
16162
|
+
}
|
|
16163
|
+
if (PROJECT_SCOPED_CATEGORIES.has(memory.category) && USER_PROFILE_REFERENCE.test(args.reason ?? "")) {
|
|
16164
|
+
return {
|
|
16165
|
+
memoryId: memory.id,
|
|
16166
|
+
verdict,
|
|
16167
|
+
reason: "user-profile-is-not-project-memory"
|
|
16168
|
+
};
|
|
16169
|
+
}
|
|
16170
|
+
}
|
|
16171
|
+
if (isDirectiveShapedProjectRule(memory.category, memory.content)) {
|
|
16172
|
+
return {
|
|
16173
|
+
memoryId: memory.id,
|
|
16174
|
+
verdict,
|
|
16175
|
+
reason: "directive-shaped-project-rule"
|
|
16176
|
+
};
|
|
16177
|
+
}
|
|
16178
|
+
if (verdict === "update") {
|
|
16179
|
+
const originalChars = memory.content.trim().length;
|
|
16180
|
+
const replacementChars = args.replacementContent?.trim().length ?? 0;
|
|
16181
|
+
if (replacementChars * 2 < originalChars && !isSurvivingConsolidationTarget(memory, successor, args.projectIdentity)) {
|
|
16182
|
+
return {
|
|
16183
|
+
memoryId: memory.id,
|
|
16184
|
+
verdict,
|
|
16185
|
+
reason: "content-loss",
|
|
16186
|
+
originalChars,
|
|
16187
|
+
replacementChars
|
|
16188
|
+
};
|
|
16189
|
+
}
|
|
16190
|
+
}
|
|
16191
|
+
return null;
|
|
16192
|
+
}
|
|
16193
|
+
function recordCurateSafetyRefusal(sessionId, refusal) {
|
|
16194
|
+
const count = (refusalCountsBySession.get(sessionId) ?? 0) + 1;
|
|
16195
|
+
refusalCountsBySession.set(sessionId, count);
|
|
16196
|
+
const lengths = refusal.originalChars === undefined ? "" : ` original_chars=${refusal.originalChars} replacement_chars=${refusal.replacementChars ?? 0}`;
|
|
16197
|
+
log(`[dreamer] curate safety refusal: session_id=${sessionId} memory_id=${refusal.memoryId} verdict=${refusal.verdict} reason=${refusal.reason}${lengths} refused=${count}`);
|
|
16198
|
+
return count;
|
|
16199
|
+
}
|
|
16200
|
+
function takeCurateSafetyRefusalCount(sessionId) {
|
|
16201
|
+
const count = refusalCountsBySession.get(sessionId) ?? 0;
|
|
16202
|
+
refusalCountsBySession.delete(sessionId);
|
|
16203
|
+
return count;
|
|
16204
|
+
}
|
|
16205
|
+
|
|
16118
16206
|
// src/agents/smart-note-compiler.ts
|
|
16119
16207
|
var SMART_NOTE_COMPILER_AGENT = "smart-note-compiler";
|
|
16120
16208
|
|
|
@@ -16680,7 +16768,7 @@ function getAsyncModule() {
|
|
|
16680
16768
|
asyncModulePromise ??= (async () => {
|
|
16681
16769
|
const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await Promise.all([
|
|
16682
16770
|
import("./index-rgdqj8nj.js").then((m)=>__toESM(m.default,1)),
|
|
16683
|
-
import("./index-
|
|
16771
|
+
import("./index-8sseka65.js")
|
|
16684
16772
|
]);
|
|
16685
16773
|
return newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
|
|
16686
16774
|
})();
|
|
@@ -18138,21 +18226,6 @@ function validateMapMemoriesManifest(text, expectedIds) {
|
|
|
18138
18226
|
return parsed;
|
|
18139
18227
|
}
|
|
18140
18228
|
|
|
18141
|
-
// src/features/magic-context/dreamer/memory-claim-safety.ts
|
|
18142
|
-
var POLICY_SENTENCE_START = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:you\s+|we\s+)?(?:must(?:\s+not)?|never|always|do\s+not|don't|shall\s+not)\b/i;
|
|
18143
|
-
var ACTOR_POLICY = /\b(?:you|we|agents?|masons?|workers?|operators?|users?|maintainers?)\s+(?:must(?:\s+not)?|should(?:\s+not)?|need\s+to|shall(?:\s+not)?|cannot|can't|may\s+not)\b/i;
|
|
18144
|
-
var BEHAVIORAL_WHEN_CLAUSE = /\bwhen\s+(?:you(?:'re|\s+are)?|we(?:'re|\s+are)?|told|asked|requested|working|debugging|reviewing|checking|verifying|investigating|using|running|editing|changing)\b/i;
|
|
18145
|
-
var WORKFLOW_IMPERATIVE = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:please\s+)?(?:run|use|check|ask|avoid|prefer|ensure|keep|follow|brief|report|inspect|search|open|read|review|validate|confirm|delegate|stop|start|remember)\b/i;
|
|
18146
|
-
var DECISION_AUTHORITY = /\b(?:the\s+)?(?:user|operator|maintainer|owner)\s+(?:decides|chooses|approves|has\s+(?:the\s+)?final\s+say)\b/i;
|
|
18147
|
-
function isDirectiveShapedProjectRule(category, content) {
|
|
18148
|
-
if (category !== "PROJECT_RULES")
|
|
18149
|
-
return false;
|
|
18150
|
-
const text = content.trim();
|
|
18151
|
-
if (!text)
|
|
18152
|
-
return false;
|
|
18153
|
-
return POLICY_SENTENCE_START.test(text) || ACTOR_POLICY.test(text) || BEHAVIORAL_WHEN_CLAUSE.test(text) || WORKFLOW_IMPERATIVE.test(text) || DECISION_AUTHORITY.test(text);
|
|
18154
|
-
}
|
|
18155
|
-
|
|
18156
18229
|
// src/features/magic-context/dreamer/map-memories.ts
|
|
18157
18230
|
var MAP_BATCH_SIZE = 80;
|
|
18158
18231
|
var MAP_BATCH_FLOOR_MS = 240000;
|
|
@@ -20423,7 +20496,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
20423
20496
|
deadline,
|
|
20424
20497
|
parent,
|
|
20425
20498
|
recordRun,
|
|
20426
|
-
computeMemoryDelta
|
|
20499
|
+
computeMemoryDelta,
|
|
20500
|
+
reportProgress
|
|
20427
20501
|
});
|
|
20428
20502
|
} catch (error) {
|
|
20429
20503
|
const { transient, brief } = classifyFailure(error);
|
|
@@ -20708,7 +20782,6 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
20708
20782
|
architecture: existsSync10(`${docsDir}/ARCHITECTURE.md`),
|
|
20709
20783
|
structure: existsSync10(`${docsDir}/STRUCTURE.md`)
|
|
20710
20784
|
} : undefined;
|
|
20711
|
-
const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
|
|
20712
20785
|
let curateMemories;
|
|
20713
20786
|
if (task === "curate") {
|
|
20714
20787
|
curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
|
|
@@ -20718,7 +20791,6 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
20718
20791
|
projectPath: projectIdentity,
|
|
20719
20792
|
lastDreamAt: lastRunAt ? String(lastRunAt) : null,
|
|
20720
20793
|
existingDocs,
|
|
20721
|
-
userMemories,
|
|
20722
20794
|
curate: curateMemories ? { memories: curateMemories } : undefined
|
|
20723
20795
|
});
|
|
20724
20796
|
const abortController = new AbortController;
|
|
@@ -20776,6 +20848,11 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
20776
20848
|
});
|
|
20777
20849
|
if (leaseLost)
|
|
20778
20850
|
throw new Error("Dream lease lost during task");
|
|
20851
|
+
const curateRefused = task === "curate" ? takeCurateSafetyRefusalCount(sessionId) : 0;
|
|
20852
|
+
if (curateRefused > 0) {
|
|
20853
|
+
helpers.reportProgress(curateRefused, curateRefused);
|
|
20854
|
+
log(`[dreamer] curate safety summary: refused=${curateRefused}`);
|
|
20855
|
+
}
|
|
20779
20856
|
if (parent) {
|
|
20780
20857
|
recordChildInvocation({
|
|
20781
20858
|
db,
|
|
@@ -20796,11 +20873,14 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
20796
20873
|
}
|
|
20797
20874
|
}
|
|
20798
20875
|
helpers.recordRun("completed", null, {
|
|
20799
|
-
memoryChanges: helpers.computeMemoryDelta(memoryBefore)
|
|
20876
|
+
memoryChanges: helpers.computeMemoryDelta(memoryBefore),
|
|
20877
|
+
progress: curateRefused > 0 ? `curate: refused ${curateRefused} unsafe mutation(s)` : null
|
|
20800
20878
|
});
|
|
20801
20879
|
return { status: "completed" };
|
|
20802
20880
|
} finally {
|
|
20803
20881
|
heartbeat.stop();
|
|
20882
|
+
if (childSessionId)
|
|
20883
|
+
takeCurateSafetyRefusalCount(childSessionId);
|
|
20804
20884
|
if (childSessionId) {
|
|
20805
20885
|
await deps.client.session.delete({ path: { id: childSessionId } }).catch(() => {});
|
|
20806
20886
|
}
|
|
@@ -21520,7 +21600,7 @@ function runTick(origin) {
|
|
|
21520
21600
|
const db = openTimerDatabaseOrNull("maintenance tick");
|
|
21521
21601
|
if (!db)
|
|
21522
21602
|
return;
|
|
21523
|
-
runMessageHistoryMaintenance(db);
|
|
21603
|
+
await runMessageHistoryMaintenance(db);
|
|
21524
21604
|
for (const reg of registeredProjects.values()) {
|
|
21525
21605
|
if (origin === "startup") {
|
|
21526
21606
|
scheduleInitialProjectRun(reg, db);
|
|
@@ -21536,11 +21616,26 @@ function runTick(origin) {
|
|
|
21536
21616
|
}
|
|
21537
21617
|
})();
|
|
21538
21618
|
}
|
|
21539
|
-
function runMessageHistoryMaintenance(db) {
|
|
21619
|
+
async function runMessageHistoryMaintenance(db) {
|
|
21540
21620
|
const cleanup = retryPendingSessionCleanups(db);
|
|
21541
21621
|
if (cleanup.cleared > 0 || cleanup.failedSessionIds.length > 0) {
|
|
21542
21622
|
log(`[message-index] pending session cleanup: cleared=${cleanup.cleared} failed=${cleanup.failedSessionIds.length}`);
|
|
21543
21623
|
}
|
|
21624
|
+
for (const registration of registeredProjects.values()) {
|
|
21625
|
+
const moduleClient = registration.sessionCleanupModuleClient;
|
|
21626
|
+
if (!moduleClient)
|
|
21627
|
+
continue;
|
|
21628
|
+
const rustCleanup = await retryPendingRustSessionCleanupsForProject(db, registration.projectIdentity, async (sessionId) => {
|
|
21629
|
+
try {
|
|
21630
|
+
await moduleClient.deleteSession(sessionId, registration.directory);
|
|
21631
|
+
} finally {
|
|
21632
|
+
moduleClient.closeSession?.(sessionId);
|
|
21633
|
+
}
|
|
21634
|
+
});
|
|
21635
|
+
if (rustCleanup.cleared > 0 || rustCleanup.failedSessionIds.length > 0) {
|
|
21636
|
+
log(`[message-index] pending Rust session cleanup: cleared=${rustCleanup.cleared} failed=${rustCleanup.failedSessionIds.length}`);
|
|
21637
|
+
}
|
|
21638
|
+
}
|
|
21544
21639
|
const sweep = sweepOrphanedOpenCodeMessageIndexes(db, openOpenCodeDb);
|
|
21545
21640
|
if (sweep.deleted > 0) {
|
|
21546
21641
|
log(`[message-index] orphan sweep: scanned=${sweep.scanned} deleted=${sweep.deleted} cursor=${sweep.cursor || "<complete>"}`);
|
|
@@ -21940,6 +22035,7 @@ function fallbackConfig(config, provider) {
|
|
|
21940
22035
|
return {
|
|
21941
22036
|
provider: "local",
|
|
21942
22037
|
model: model || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
22038
|
+
local_runtime: raw.local_runtime === "native" || raw.local_runtime === "wasm" ? raw.local_runtime : "auto",
|
|
21943
22039
|
...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
|
|
21944
22040
|
};
|
|
21945
22041
|
}
|
|
@@ -22539,7 +22635,7 @@ function createTagger() {
|
|
|
22539
22635
|
if (type === "tool") {
|
|
22540
22636
|
throw new Error("tagger.assignTag: type='tool' is forbidden — use assignToolTag(sessionId, callId, ownerMsgId, ...)");
|
|
22541
22637
|
}
|
|
22542
|
-
return allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, null, messageId, () =>
|
|
22638
|
+
return allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, null, messageId, () => getAssignableTagNumberByMessageId(db, sessionId, messageId), entryFingerprint, tokenThunk);
|
|
22543
22639
|
}
|
|
22544
22640
|
function backfillToolTokensIfNull(db, sessionId, tagNumber, tokenThunk) {
|
|
22545
22641
|
if (!tokenThunk)
|
|
@@ -23253,8 +23349,16 @@ var GIT_COMMIT_SOURCE_BOOST = 1.2;
|
|
|
23253
23349
|
var PRIMER_SOURCE_BOOST = 1.25;
|
|
23254
23350
|
var messageSearchStatements = new WeakMap;
|
|
23255
23351
|
var messageSearchStatementsWithCutoff = new WeakMap;
|
|
23352
|
+
var messageSearchDiagnosticStatements = new WeakMap;
|
|
23256
23353
|
var batchedMessageSearchStatements = new WeakMap;
|
|
23257
23354
|
var batchedFtsCountStatements = new WeakMap;
|
|
23355
|
+
function createUnifiedSearchDiagnostics() {
|
|
23356
|
+
return {
|
|
23357
|
+
suppressedVisibleMemoryIds: [],
|
|
23358
|
+
suppressedLiveMessageMatches: 0,
|
|
23359
|
+
gitCommitUnavailable: null
|
|
23360
|
+
};
|
|
23361
|
+
}
|
|
23258
23362
|
function normalizeLimit(limit) {
|
|
23259
23363
|
if (typeof limit !== "number" || !Number.isFinite(limit)) {
|
|
23260
23364
|
return DEFAULT_UNIFIED_SEARCH_LIMIT;
|
|
@@ -23345,6 +23449,51 @@ function getMessageSearchStatementWithCutoff(db) {
|
|
|
23345
23449
|
}
|
|
23346
23450
|
return stmt;
|
|
23347
23451
|
}
|
|
23452
|
+
function getMessageSearchDiagnosticStatement(db) {
|
|
23453
|
+
let stmt = messageSearchDiagnosticStatements.get(db);
|
|
23454
|
+
if (!stmt) {
|
|
23455
|
+
stmt = db.prepare(`
|
|
23456
|
+
WITH matches AS MATERIALIZED (
|
|
23457
|
+
SELECT
|
|
23458
|
+
message_ordinal AS messageOrdinal,
|
|
23459
|
+
message_id AS messageId,
|
|
23460
|
+
role,
|
|
23461
|
+
content,
|
|
23462
|
+
CAST(message_ordinal AS INTEGER) AS ordinalValue,
|
|
23463
|
+
bm25(message_history_fts) AS ftsRank
|
|
23464
|
+
FROM message_history_fts
|
|
23465
|
+
WHERE session_id = ? AND message_history_fts MATCH ?
|
|
23466
|
+
),
|
|
23467
|
+
eligible AS (
|
|
23468
|
+
SELECT * FROM matches
|
|
23469
|
+
WHERE ordinalValue <= ?
|
|
23470
|
+
ORDER BY ftsRank, ordinalValue ASC
|
|
23471
|
+
LIMIT ?
|
|
23472
|
+
),
|
|
23473
|
+
summary AS (
|
|
23474
|
+
SELECT COUNT(*) AS suppressedCount
|
|
23475
|
+
FROM matches
|
|
23476
|
+
WHERE ordinalValue > ?
|
|
23477
|
+
)
|
|
23478
|
+
SELECT
|
|
23479
|
+
eligible.messageOrdinal,
|
|
23480
|
+
eligible.messageId,
|
|
23481
|
+
eligible.role,
|
|
23482
|
+
eligible.content,
|
|
23483
|
+
eligible.ftsRank,
|
|
23484
|
+
summary.suppressedCount,
|
|
23485
|
+
0 AS summaryOnly
|
|
23486
|
+
FROM eligible CROSS JOIN summary
|
|
23487
|
+
UNION ALL
|
|
23488
|
+
SELECT NULL, NULL, NULL, NULL, NULL, summary.suppressedCount, 1
|
|
23489
|
+
FROM summary
|
|
23490
|
+
WHERE NOT EXISTS (SELECT 1 FROM eligible)
|
|
23491
|
+
ORDER BY summaryOnly ASC, ftsRank ASC, messageOrdinal ASC
|
|
23492
|
+
`);
|
|
23493
|
+
messageSearchDiagnosticStatements.set(db, stmt);
|
|
23494
|
+
}
|
|
23495
|
+
return stmt;
|
|
23496
|
+
}
|
|
23348
23497
|
function getBatchedFtsCountStatement(db, queryCount, cutoff) {
|
|
23349
23498
|
let statements = batchedFtsCountStatements.get(db);
|
|
23350
23499
|
if (!statements) {
|
|
@@ -23485,10 +23634,8 @@ function mergeMemoryResults(args) {
|
|
|
23485
23634
|
const memoryById = new Map(args.memories.map((memory) => [memory.id, memory]));
|
|
23486
23635
|
const candidateIds = new Set([...args.semanticScores.keys(), ...args.ftsScores.keys()]);
|
|
23487
23636
|
const results = [];
|
|
23637
|
+
const suppressedVisibleIds = [];
|
|
23488
23638
|
for (const id of candidateIds) {
|
|
23489
|
-
if (args.visibleMemoryIds?.has(id)) {
|
|
23490
|
-
continue;
|
|
23491
|
-
}
|
|
23492
23639
|
const memory = memoryById.get(id);
|
|
23493
23640
|
if (!memory) {
|
|
23494
23641
|
continue;
|
|
@@ -23510,6 +23657,10 @@ function mergeMemoryResults(args) {
|
|
|
23510
23657
|
if (score <= 0) {
|
|
23511
23658
|
continue;
|
|
23512
23659
|
}
|
|
23660
|
+
if (args.visibleMemoryIds?.has(id)) {
|
|
23661
|
+
suppressedVisibleIds.push(id);
|
|
23662
|
+
continue;
|
|
23663
|
+
}
|
|
23513
23664
|
results.push({
|
|
23514
23665
|
source: "memory",
|
|
23515
23666
|
content: previewText(memory.content),
|
|
@@ -23520,20 +23671,23 @@ function mergeMemoryResults(args) {
|
|
|
23520
23671
|
sourceName: args.sourceNameByMemoryId?.get(memory.id)
|
|
23521
23672
|
});
|
|
23522
23673
|
}
|
|
23523
|
-
return
|
|
23524
|
-
|
|
23525
|
-
|
|
23526
|
-
|
|
23527
|
-
|
|
23528
|
-
|
|
23674
|
+
return {
|
|
23675
|
+
results: results.sort((left, right) => {
|
|
23676
|
+
if (right.score !== left.score) {
|
|
23677
|
+
return right.score - left.score;
|
|
23678
|
+
}
|
|
23679
|
+
return left.memoryId - right.memoryId;
|
|
23680
|
+
}).slice(0, args.limit),
|
|
23681
|
+
suppressedVisibleIds: suppressedVisibleIds.sort((left, right) => left - right)
|
|
23682
|
+
};
|
|
23529
23683
|
}
|
|
23530
23684
|
async function searchMemories(args) {
|
|
23531
23685
|
if (!args.memoryEnabled) {
|
|
23532
|
-
return [];
|
|
23686
|
+
return { results: [], suppressedVisibleIds: [] };
|
|
23533
23687
|
}
|
|
23534
23688
|
const memories = args.workspace?.isWorkspaced ? getMemoriesByProjects(args.db, args.workspace.expandedIdentities, ["active", "permanent"], Date.now(), args.workspace.ownIdentities, args.workspace.shareCategories) : getMemoriesByProject(args.db, args.projectPath);
|
|
23535
23689
|
if (memories.length === 0) {
|
|
23536
|
-
return [];
|
|
23690
|
+
return { results: [], suppressedVisibleIds: [] };
|
|
23537
23691
|
}
|
|
23538
23692
|
const ftsMatches = getFtsMatches({
|
|
23539
23693
|
db: args.db,
|
|
@@ -23610,6 +23764,21 @@ function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
|
23610
23764
|
}
|
|
23611
23765
|
return result;
|
|
23612
23766
|
}
|
|
23767
|
+
function runMessageFtsQueryWithDiagnostics(args) {
|
|
23768
|
+
if (args.ftsQuery.length === 0)
|
|
23769
|
+
return { rows: [], suppressedCount: 0 };
|
|
23770
|
+
const rawRows = getMessageSearchDiagnosticStatement(args.db).all(args.sessionId, args.ftsQuery, args.cutoff, args.fetchLimit, args.cutoff).map((row) => row);
|
|
23771
|
+
const suppressedCount = rawRows[0]?.suppressedCount ?? 0;
|
|
23772
|
+
const rows = [];
|
|
23773
|
+
for (const row of rawRows) {
|
|
23774
|
+
if (row.summaryOnly === 1)
|
|
23775
|
+
continue;
|
|
23776
|
+
const normalized = normalizeMessageSearchRow(row, args.cutoff);
|
|
23777
|
+
if (normalized)
|
|
23778
|
+
rows.push(normalized);
|
|
23779
|
+
}
|
|
23780
|
+
return { rows, suppressedCount };
|
|
23781
|
+
}
|
|
23613
23782
|
function getBatchedMessageSearchStatement(db, queryCount, cutoff) {
|
|
23614
23783
|
let statements = batchedMessageSearchStatements.get(db);
|
|
23615
23784
|
if (!statements) {
|
|
@@ -23676,7 +23845,20 @@ function searchMessages(args) {
|
|
|
23676
23845
|
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
23677
23846
|
const probes = args.probes ?? [];
|
|
23678
23847
|
if (probes.length === 0) {
|
|
23679
|
-
const
|
|
23848
|
+
const outcome = args.diagnostics && cutoff !== null ? runMessageFtsQueryWithDiagnostics({
|
|
23849
|
+
db: args.db,
|
|
23850
|
+
sessionId: args.sessionId,
|
|
23851
|
+
ftsQuery: baseQuery,
|
|
23852
|
+
fetchLimit,
|
|
23853
|
+
cutoff
|
|
23854
|
+
}) : {
|
|
23855
|
+
rows: runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff),
|
|
23856
|
+
suppressedCount: 0
|
|
23857
|
+
};
|
|
23858
|
+
if (args.diagnostics) {
|
|
23859
|
+
args.diagnostics.suppressedLiveMessageMatches = outcome.suppressedCount;
|
|
23860
|
+
}
|
|
23861
|
+
const filtered = outcome.rows.slice(0, args.limit);
|
|
23680
23862
|
return filtered.map((row, rank) => ({
|
|
23681
23863
|
source: "message",
|
|
23682
23864
|
content: previewText(row.content),
|
|
@@ -23689,8 +23871,19 @@ function searchMessages(args) {
|
|
|
23689
23871
|
const sanitizedProbes = probes.map((probe) => ({ probe, query: sanitizeFtsQuery(probe) })).filter((entry) => entry.query.length > 0);
|
|
23690
23872
|
const corpusSize = getIndexedMessageCorpusSize(args.db, args.sessionId, cutoff);
|
|
23691
23873
|
const probeCounts = countSessionFtsMatchesBatch(args.db, args.sessionId, sanitizedProbes.map((entry) => entry.query), cutoff);
|
|
23874
|
+
const collectBaseDiagnostics = args.diagnostics !== undefined && cutoff !== null;
|
|
23875
|
+
const baseOutcome = collectBaseDiagnostics && baseQuery.length > 0 ? runMessageFtsQueryWithDiagnostics({
|
|
23876
|
+
db: args.db,
|
|
23877
|
+
sessionId: args.sessionId,
|
|
23878
|
+
ftsQuery: baseQuery,
|
|
23879
|
+
fetchLimit,
|
|
23880
|
+
cutoff
|
|
23881
|
+
}) : null;
|
|
23882
|
+
if (args.diagnostics) {
|
|
23883
|
+
args.diagnostics.suppressedLiveMessageMatches = baseOutcome?.suppressedCount ?? 0;
|
|
23884
|
+
}
|
|
23692
23885
|
const searchQueries = [
|
|
23693
|
-
|
|
23886
|
+
...!collectBaseDiagnostics && baseQuery.length > 0 ? [baseQuery] : [],
|
|
23694
23887
|
...sanitizedProbes.map((entry) => entry.query)
|
|
23695
23888
|
];
|
|
23696
23889
|
const rowsByQuery = runMessageFtsQueriesBatch(args.db, args.sessionId, searchQueries, fetchLimit, cutoff);
|
|
@@ -23698,10 +23891,11 @@ function searchMessages(args) {
|
|
|
23698
23891
|
let queryIndex = 0;
|
|
23699
23892
|
if (baseQuery.length > 0) {
|
|
23700
23893
|
queryLists.push({
|
|
23701
|
-
rows: rowsByQuery[queryIndex] ?? [],
|
|
23894
|
+
rows: baseOutcome?.rows ?? rowsByQuery[queryIndex] ?? [],
|
|
23702
23895
|
weight: 1
|
|
23703
23896
|
});
|
|
23704
|
-
|
|
23897
|
+
if (!collectBaseDiagnostics)
|
|
23898
|
+
queryIndex += 1;
|
|
23705
23899
|
}
|
|
23706
23900
|
const probeWeights = new Map;
|
|
23707
23901
|
sanitizedProbes.forEach((entry, probeIndex) => {
|
|
@@ -24088,6 +24282,9 @@ function memoriesToIdLookupResults(args) {
|
|
|
24088
24282
|
}));
|
|
24089
24283
|
}
|
|
24090
24284
|
function resolveMemoriesByIdsForSearch(args) {
|
|
24285
|
+
if (args.diagnostics) {
|
|
24286
|
+
args.diagnostics.suppressedVisibleMemoryIds = [];
|
|
24287
|
+
}
|
|
24091
24288
|
if (args.ids.length === 0) {
|
|
24092
24289
|
return null;
|
|
24093
24290
|
}
|
|
@@ -24098,16 +24295,22 @@ function resolveMemoriesByIdsForSearch(args) {
|
|
|
24098
24295
|
}
|
|
24099
24296
|
const memoriesById = new Map(fetched.map((memory) => [memory.id, memory]));
|
|
24100
24297
|
const ordered = [];
|
|
24298
|
+
const suppressedVisibleIds = new Set;
|
|
24101
24299
|
for (const id of args.ids) {
|
|
24102
24300
|
const memory = memoriesById.get(id);
|
|
24103
24301
|
if (!memory)
|
|
24104
24302
|
continue;
|
|
24105
|
-
if (args.visibleMemoryIds?.has(id))
|
|
24303
|
+
if (args.visibleMemoryIds?.has(id)) {
|
|
24304
|
+
suppressedVisibleIds.add(id);
|
|
24106
24305
|
continue;
|
|
24306
|
+
}
|
|
24107
24307
|
ordered.push(memory);
|
|
24108
24308
|
if (ordered.length >= args.limit)
|
|
24109
24309
|
break;
|
|
24110
24310
|
}
|
|
24311
|
+
if (args.diagnostics) {
|
|
24312
|
+
args.diagnostics.suppressedVisibleMemoryIds = [...suppressedVisibleIds].sort((left, right) => left - right);
|
|
24313
|
+
}
|
|
24111
24314
|
if (ordered.length === 0) {
|
|
24112
24315
|
return null;
|
|
24113
24316
|
}
|
|
@@ -24129,6 +24332,11 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24129
24332
|
}
|
|
24130
24333
|
const limit = normalizeLimit(options.limit);
|
|
24131
24334
|
const tierLimit = Math.max(limit * 3, DEFAULT_UNIFIED_SEARCH_LIMIT);
|
|
24335
|
+
if (options.diagnostics) {
|
|
24336
|
+
options.diagnostics.suppressedVisibleMemoryIds = [];
|
|
24337
|
+
options.diagnostics.suppressedLiveMessageMatches = 0;
|
|
24338
|
+
options.diagnostics.gitCommitUnavailable = null;
|
|
24339
|
+
}
|
|
24132
24340
|
const embeddingEnabled = options.embeddingEnabled ?? true;
|
|
24133
24341
|
const embedQuery = options.embedQuery ?? embedText;
|
|
24134
24342
|
const isEmbeddingRuntimeEnabled = options.isEmbeddingRuntimeEnabled ?? isEmbeddingEnabled;
|
|
@@ -24138,6 +24346,9 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24138
24346
|
const runMemory = activeSources.has("memory") && memoryFeatureEnabled;
|
|
24139
24347
|
const runMessages = activeSources.has("message");
|
|
24140
24348
|
const runGitCommits = activeSources.has("git_commit") && gitCommitsEnabled;
|
|
24349
|
+
if (options.diagnostics && activeSources.has("git_commit") && options.gitRepositoryAvailable === false) {
|
|
24350
|
+
options.diagnostics.gitCommitUnavailable = "no_git_repository";
|
|
24351
|
+
}
|
|
24141
24352
|
const runPrimers = activeSources.has("primer") && memoryFeatureEnabled;
|
|
24142
24353
|
const runNotes = activeSources.has("note");
|
|
24143
24354
|
const runCompartmentChunks = runMessages && memoryFeatureEnabled && embeddingEnabled;
|
|
@@ -24154,7 +24365,8 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24154
24365
|
query: trimmedQuery,
|
|
24155
24366
|
limit: tierLimit,
|
|
24156
24367
|
maxOrdinal: options.maxMessageOrdinal,
|
|
24157
|
-
probes: messageProbes
|
|
24368
|
+
probes: messageProbes,
|
|
24369
|
+
diagnostics: options.diagnostics
|
|
24158
24370
|
}) : [];
|
|
24159
24371
|
const capturedQuery = await queryEmbeddingPromise;
|
|
24160
24372
|
const embeddingSnapshot = getProjectEmbeddingSnapshot(projectPath);
|
|
@@ -24178,7 +24390,7 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24178
24390
|
compartments: compartmentResults,
|
|
24179
24391
|
limit: tierLimit
|
|
24180
24392
|
});
|
|
24181
|
-
const [
|
|
24393
|
+
const [memoryOutcome, gitCommitResults, primerResults, noteResults] = await Promise.all([
|
|
24182
24394
|
runMemory ? searchMemories({
|
|
24183
24395
|
db,
|
|
24184
24396
|
projectPath,
|
|
@@ -24189,7 +24401,10 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24189
24401
|
queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
|
|
24190
24402
|
workspace,
|
|
24191
24403
|
visibleMemoryIds: options.visibleMemoryIds
|
|
24192
|
-
}) : Promise.resolve(
|
|
24404
|
+
}) : Promise.resolve({
|
|
24405
|
+
results: [],
|
|
24406
|
+
suppressedVisibleIds: []
|
|
24407
|
+
}),
|
|
24193
24408
|
runGitCommits ? Promise.resolve(searchGitCommits({
|
|
24194
24409
|
db,
|
|
24195
24410
|
projectPath,
|
|
@@ -24215,8 +24430,11 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24215
24430
|
probes: messageProbes
|
|
24216
24431
|
})) : Promise.resolve([])
|
|
24217
24432
|
]);
|
|
24433
|
+
if (options.diagnostics) {
|
|
24434
|
+
options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
|
|
24435
|
+
}
|
|
24218
24436
|
const results = [
|
|
24219
|
-
...
|
|
24437
|
+
...memoryOutcome.results,
|
|
24220
24438
|
...primerResults,
|
|
24221
24439
|
...messageLikeResults,
|
|
24222
24440
|
...gitCommitResults,
|
|
@@ -24254,6 +24472,123 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
24254
24472
|
}
|
|
24255
24473
|
return results;
|
|
24256
24474
|
}
|
|
24475
|
+
var SEARCH_NOTE_EXPAND_HINT = "Use ctx_expand(start=N-10, end=N) around any note @msg anchor above to read the surrounding conversation context.";
|
|
24476
|
+
function formatSearchAge(timestampMs) {
|
|
24477
|
+
const ageMs = Date.now() - timestampMs;
|
|
24478
|
+
if (ageMs < 0)
|
|
24479
|
+
return "future";
|
|
24480
|
+
const days = Math.floor(ageMs / (24 * 60 * 60 * 1000));
|
|
24481
|
+
if (days <= 0)
|
|
24482
|
+
return "today";
|
|
24483
|
+
if (days === 1)
|
|
24484
|
+
return "1d ago";
|
|
24485
|
+
if (days < 30)
|
|
24486
|
+
return `${days}d ago`;
|
|
24487
|
+
const months = Math.floor(days / 30);
|
|
24488
|
+
if (months === 1)
|
|
24489
|
+
return "1mo ago";
|
|
24490
|
+
if (months < 12)
|
|
24491
|
+
return `${months}mo ago`;
|
|
24492
|
+
const years = Math.floor(days / 365);
|
|
24493
|
+
return years === 1 ? "1y ago" : `${years}y ago`;
|
|
24494
|
+
}
|
|
24495
|
+
function formatUnifiedSearchResult(result, index, currentSessionId) {
|
|
24496
|
+
if (result.source === "memory") {
|
|
24497
|
+
const source = result.sourceName ? ` source=${result.sourceName}` : "";
|
|
24498
|
+
return [
|
|
24499
|
+
`[${index}] [memory] score=${result.score.toFixed(2)} id=${result.memoryId} category=${result.category}${source} match=${result.matchType}`,
|
|
24500
|
+
result.content
|
|
24501
|
+
].join(`
|
|
24502
|
+
`);
|
|
24503
|
+
}
|
|
24504
|
+
if (result.source === "git_commit") {
|
|
24505
|
+
return [
|
|
24506
|
+
`[${index}] [git_commit] score=${result.score.toFixed(2)} sha=${result.shortSha} ${formatSearchAge(result.committedAtMs)} match=${result.matchType}`,
|
|
24507
|
+
result.content
|
|
24508
|
+
].join(`
|
|
24509
|
+
`);
|
|
24510
|
+
}
|
|
24511
|
+
if (result.source === "primer") {
|
|
24512
|
+
return [
|
|
24513
|
+
`[${index}] [primer] score=${result.score.toFixed(2)} id=${result.primerId} support=${result.support} match=${result.matchType}`,
|
|
24514
|
+
result.content
|
|
24515
|
+
].join(`
|
|
24516
|
+
`);
|
|
24517
|
+
}
|
|
24518
|
+
if (result.source === "note") {
|
|
24519
|
+
const anchor = result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId ? ` @msg ${result.anchorOrdinal}` : "";
|
|
24520
|
+
return [
|
|
24521
|
+
`[${index}] [note] score=${result.score.toFixed(2)} id=#${result.noteId} status=${result.status} ${formatSearchAge(result.createdAt)}${anchor}`,
|
|
24522
|
+
result.content
|
|
24523
|
+
].join(`
|
|
24524
|
+
`);
|
|
24525
|
+
}
|
|
24526
|
+
if (result.source === "compartment") {
|
|
24527
|
+
return [
|
|
24528
|
+
`[${index}] [message] score=${result.score.toFixed(2)} compartment_id=${result.compartmentId} range=${result.startOrdinal}-${result.endOrdinal} match=${result.matchType} title=${result.title}`,
|
|
24529
|
+
result.snippet ? `Snippet: ${result.snippet}` : result.content
|
|
24530
|
+
].join(`
|
|
24531
|
+
`);
|
|
24532
|
+
}
|
|
24533
|
+
const expandStart = Math.max(1, result.messageOrdinal - 3);
|
|
24534
|
+
const expandEnd = result.messageOrdinal + 3;
|
|
24535
|
+
return [
|
|
24536
|
+
`[${index}] [message] score=${result.score.toFixed(2)} ordinal=${result.messageOrdinal} range=${expandStart}-${expandEnd} role=${result.role}`,
|
|
24537
|
+
result.content
|
|
24538
|
+
].join(`
|
|
24539
|
+
`);
|
|
24540
|
+
}
|
|
24541
|
+
function formatSearchDiagnosticLines(results, diagnostics) {
|
|
24542
|
+
if (!diagnostics)
|
|
24543
|
+
return [];
|
|
24544
|
+
const lines = [];
|
|
24545
|
+
const visibleIds = [...diagnostics.suppressedVisibleMemoryIds].sort((left, right) => left - right);
|
|
24546
|
+
if (visibleIds.length > 0) {
|
|
24547
|
+
const count = visibleIds.length;
|
|
24548
|
+
const noun = count === 1 ? "match" : "matches";
|
|
24549
|
+
const ids = visibleIds.join(", ");
|
|
24550
|
+
if (results.some((result) => result.source === "memory")) {
|
|
24551
|
+
lines.push(`Memories: ${count} additional ${noun} suppressed because ${count === 1 ? "it is" : "they are"} already visible in your project-memory block (ids ${ids}).`);
|
|
24552
|
+
} else {
|
|
24553
|
+
lines.push(`Memories: ${count} ${noun} found, all already visible in your project-memory block (ids ${ids}).`);
|
|
24554
|
+
}
|
|
24555
|
+
}
|
|
24556
|
+
if (diagnostics.suppressedLiveMessageMatches > 0) {
|
|
24557
|
+
const count = diagnostics.suppressedLiveMessageMatches;
|
|
24558
|
+
lines.push(`Message history: ${count} raw-message ${count === 1 ? "match is" : "matches are"} newer than the last compartment boundary (already in your context).`);
|
|
24559
|
+
}
|
|
24560
|
+
if (diagnostics.gitCommitUnavailable === "no_git_repository") {
|
|
24561
|
+
lines.push("Git commits: no git repository — commit search unavailable for this project.");
|
|
24562
|
+
}
|
|
24563
|
+
return lines;
|
|
24564
|
+
}
|
|
24565
|
+
function formatSearchResults(query, results, currentSessionId, diagnostics) {
|
|
24566
|
+
const diagnosticLines = formatSearchDiagnosticLines(results, diagnostics);
|
|
24567
|
+
if (results.length === 0) {
|
|
24568
|
+
if (diagnosticLines.length > 0) {
|
|
24569
|
+
return `No hidden results found for "${query}".
|
|
24570
|
+
|
|
24571
|
+
${diagnosticLines.join(`
|
|
24572
|
+
`)}`;
|
|
24573
|
+
}
|
|
24574
|
+
return `No results found for "${query}" across notes, memories, primers, git commits, or message history.`;
|
|
24575
|
+
}
|
|
24576
|
+
const bodyParts = results.map((result, index) => formatUnifiedSearchResult(result, index + 1, currentSessionId));
|
|
24577
|
+
if (diagnosticLines.length > 0)
|
|
24578
|
+
bodyParts.push(diagnosticLines.join(`
|
|
24579
|
+
`));
|
|
24580
|
+
if (results.some((result) => result.source === "message" || result.source === "compartment")) {
|
|
24581
|
+
bodyParts.push("Use ctx_expand(start, end) with the range from any message result above to read the full conversation context.");
|
|
24582
|
+
}
|
|
24583
|
+
if (results.some((result) => result.source === "note" && result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId)) {
|
|
24584
|
+
bodyParts.push(SEARCH_NOTE_EXPAND_HINT);
|
|
24585
|
+
}
|
|
24586
|
+
return `Found ${results.length} result${results.length === 1 ? "" : "s"} for "${query}":
|
|
24587
|
+
|
|
24588
|
+
${bodyParts.join(`
|
|
24589
|
+
|
|
24590
|
+
`)}`;
|
|
24591
|
+
}
|
|
24257
24592
|
|
|
24258
24593
|
// src/hooks/magic-context/caveman.ts
|
|
24259
24594
|
var PRESERVATION_PATTERNS = [
|
|
@@ -25180,16 +25515,14 @@ var WHOLE_MESSAGE_PLACEHOLDER_TEXT = "[dropped]";
|
|
|
25180
25515
|
function modelAcceptsEmptyContent(providerID) {
|
|
25181
25516
|
return providerID === "anthropic";
|
|
25182
25517
|
}
|
|
25183
|
-
function variantChangeBustsProviderCache(providerID) {
|
|
25184
|
-
if (providerID
|
|
25185
|
-
return
|
|
25186
|
-
|
|
25187
|
-
|
|
25188
|
-
if (
|
|
25189
|
-
return
|
|
25190
|
-
|
|
25191
|
-
return true;
|
|
25192
|
-
return false;
|
|
25518
|
+
function variantChangeBustsProviderCache(providerID, modelID) {
|
|
25519
|
+
if (!providerID || !modelID)
|
|
25520
|
+
return false;
|
|
25521
|
+
const normalizedProviderID = providerID.toLowerCase();
|
|
25522
|
+
const isAnthropicFamily = normalizedProviderID === "anthropic" || normalizedProviderID === "google-vertex-anthropic" || normalizedProviderID.includes("bedrock");
|
|
25523
|
+
if (!isAnthropicFamily)
|
|
25524
|
+
return false;
|
|
25525
|
+
return !isFable51ThinkingBindingModel("anthropic", modelID);
|
|
25193
25526
|
}
|
|
25194
25527
|
function makeSentinel(originalPart) {
|
|
25195
25528
|
const sentinel = {
|
|
@@ -25602,7 +25935,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
25602
25935
|
const forceMaterializationPercentage = escalationBands(executeThresholdPercentage).forceMaterializationPercentage;
|
|
25603
25936
|
if (usage.percentage >= forceMaterializationPercentage) {
|
|
25604
25937
|
if (projectedPostDropPercentage !== null && projectedPostDropPercentage <= relativePostDropTarget) {
|
|
25605
|
-
sessionLog(sessionId, `
|
|
25938
|
+
sessionLog(sessionId, `historian redundancy skip: summarizer not needed this pass — force band is ${forceMaterializationPercentage}%; queued/automatic drops are projected to reclaim to ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%) on the next eligible execute pass`);
|
|
25606
25939
|
return { shouldFire: false };
|
|
25607
25940
|
}
|
|
25608
25941
|
sessionLog(sessionId, `compartment trigger: force-firing at ${usage.percentage.toFixed(1)}% (projected post-drop ${formatProjectedPostDropPercentage(projectedPostDropPercentage)})`);
|
|
@@ -25663,7 +25996,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
25663
25996
|
return { shouldFire: false };
|
|
25664
25997
|
}
|
|
25665
25998
|
if (projectedPostDropPercentage !== null && projectedPostDropPercentage <= relativePostDropTarget) {
|
|
25666
|
-
sessionLog(sessionId, `
|
|
25999
|
+
sessionLog(sessionId, `historian redundancy skip: summarizer not needed this pass — usage is ${usage.percentage.toFixed(1)}%; queued/automatic drops are projected to reclaim to ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%) on the next eligible execute pass`);
|
|
25667
26000
|
return { shouldFire: false };
|
|
25668
26001
|
}
|
|
25669
26002
|
if (!tailInfo.hasProtectedEligibleHead || !tailInfo.isMeaningful) {
|
|
@@ -26541,20 +26874,23 @@ function createChatMessageHook(args) {
|
|
|
26541
26874
|
args.agentBySession.set(sessionId, input.agent);
|
|
26542
26875
|
}
|
|
26543
26876
|
if (previousVariant !== undefined && input.variant !== undefined && previousVariant !== input.variant) {
|
|
26544
|
-
const
|
|
26545
|
-
|
|
26877
|
+
const liveModel = args.liveModelBySession.get(sessionId);
|
|
26878
|
+
const providerID = input.model?.providerID ?? liveModel?.providerID;
|
|
26879
|
+
const modelID = input.model?.modelID ?? liveModel?.modelID;
|
|
26880
|
+
if (variantChangeBustsProviderCache(providerID, modelID)) {
|
|
26546
26881
|
sessionLog(sessionId, `variant changed (${previousVariant} -> ${input.variant}), triggering flush`);
|
|
26547
26882
|
args.historyRefreshSessions.add(sessionId);
|
|
26548
26883
|
args.systemPromptRefreshSessions.add(sessionId);
|
|
26549
26884
|
args.pendingMaterializationSessions.add(sessionId);
|
|
26550
26885
|
args.lastHeuristicsTurnId.delete(sessionId);
|
|
26551
26886
|
} else {
|
|
26552
|
-
sessionLog(sessionId, `variant changed (${previousVariant} -> ${input.variant}) on
|
|
26887
|
+
sessionLog(sessionId, `variant changed (${previousVariant} -> ${input.variant}) on ${providerID ?? "unknown"}/${modelID ?? "unknown"} without a proven natural cache bust; deferring flush to next natural bust`);
|
|
26553
26888
|
}
|
|
26554
26889
|
}
|
|
26555
26890
|
};
|
|
26556
26891
|
}
|
|
26557
26892
|
function createEventHook(args) {
|
|
26893
|
+
const latestAssistantMessageIdBySession = args.latestAssistantMessageIdBySession ?? new Map;
|
|
26558
26894
|
return async (input) => {
|
|
26559
26895
|
await args.eventHandler(input);
|
|
26560
26896
|
if (input.event.type === "message.updated") {
|
|
@@ -26568,24 +26904,31 @@ function createEventHook(args) {
|
|
|
26568
26904
|
}
|
|
26569
26905
|
const assistantInfo = getMessageUpdatedAssistantInfo(input.event.properties);
|
|
26570
26906
|
if (assistantInfo?.providerID && assistantInfo?.modelID) {
|
|
26571
|
-
const
|
|
26572
|
-
|
|
26573
|
-
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
26578
|
-
|
|
26579
|
-
|
|
26580
|
-
|
|
26581
|
-
clearDetectedContextLimit(args.db, assistantInfo.sessionID);
|
|
26582
|
-
clearEmergencyRecovery(args.db, assistantInfo.sessionID);
|
|
26583
|
-
clearEmergencyDropSample(args.db, assistantInfo.sessionID);
|
|
26584
|
-
updateSessionMeta(args.db, assistantInfo.sessionID, {
|
|
26585
|
-
clearedReasoningThroughTag: 0,
|
|
26586
|
-
observedSafeInputTokens: 0,
|
|
26587
|
-
cacheAlertSent: false
|
|
26907
|
+
const latestMessageID = latestAssistantMessageIdBySession.get(assistantInfo.sessionID);
|
|
26908
|
+
const acceptsModelUpdate = latestMessageID === undefined || assistantInfo.messageID !== undefined && assistantInfo.messageID >= latestMessageID;
|
|
26909
|
+
if (acceptsModelUpdate) {
|
|
26910
|
+
if (assistantInfo.messageID !== undefined) {
|
|
26911
|
+
latestAssistantMessageIdBySession.set(assistantInfo.sessionID, assistantInfo.messageID);
|
|
26912
|
+
}
|
|
26913
|
+
const previous = args.liveModelBySession.get(assistantInfo.sessionID);
|
|
26914
|
+
args.liveModelBySession.set(assistantInfo.sessionID, {
|
|
26915
|
+
providerID: assistantInfo.providerID,
|
|
26916
|
+
modelID: assistantInfo.modelID
|
|
26588
26917
|
});
|
|
26918
|
+
if (previous && (previous.providerID !== assistantInfo.providerID || previous.modelID !== assistantInfo.modelID)) {
|
|
26919
|
+
dropSlot(assistantInfo.sessionID, "model-change");
|
|
26920
|
+
sessionLog(assistantInfo.sessionID, `model changed (${previous.providerID}/${previous.modelID} -> ${assistantInfo.providerID}/${assistantInfo.modelID}), clearing historian failure state and reasoning watermark`);
|
|
26921
|
+
clearHistorianFailureState(args.db, assistantInfo.sessionID);
|
|
26922
|
+
clearPersistedReasoningWatermark(args.db, assistantInfo.sessionID);
|
|
26923
|
+
clearDetectedContextLimit(args.db, assistantInfo.sessionID);
|
|
26924
|
+
clearEmergencyRecovery(args.db, assistantInfo.sessionID);
|
|
26925
|
+
clearEmergencyDropSample(args.db, assistantInfo.sessionID);
|
|
26926
|
+
updateSessionMeta(args.db, assistantInfo.sessionID, {
|
|
26927
|
+
clearedReasoningThroughTag: 0,
|
|
26928
|
+
observedSafeInputTokens: 0,
|
|
26929
|
+
cacheAlertSent: false
|
|
26930
|
+
});
|
|
26931
|
+
}
|
|
26589
26932
|
}
|
|
26590
26933
|
}
|
|
26591
26934
|
}
|
|
@@ -26598,6 +26941,7 @@ function createEventHook(args) {
|
|
|
26598
26941
|
}
|
|
26599
26942
|
if (input.event.type === "session.deleted") {
|
|
26600
26943
|
args.liveModelBySession.delete(sessionId);
|
|
26944
|
+
latestAssistantMessageIdBySession.delete(sessionId);
|
|
26601
26945
|
args.variantBySession.delete(sessionId);
|
|
26602
26946
|
args.agentBySession.delete(sessionId);
|
|
26603
26947
|
args.sessionDirectoryBySession.delete(sessionId);
|
|
@@ -27565,9 +27909,9 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
27565
27909
|
return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
|
|
27566
27910
|
});
|
|
27567
27911
|
const buildManagedCtx = async (db) => {
|
|
27568
|
-
const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-
|
|
27569
|
-
const { resolveHistorianModel: resolveHistorianModel2 } = await import("./model-resolution-
|
|
27570
|
-
const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-
|
|
27912
|
+
const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-9q2d3r93.js");
|
|
27913
|
+
const { resolveHistorianModel: resolveHistorianModel2 } = await import("./model-resolution-6w6wzw18.js");
|
|
27914
|
+
const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-gv6s04fp.js");
|
|
27571
27915
|
const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
|
|
27572
27916
|
const historianModel = resolveHistorianModel2(config, "opencode");
|
|
27573
27917
|
return {
|
|
@@ -27598,8 +27942,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
27598
27942
|
const db = getDb();
|
|
27599
27943
|
if (!db)
|
|
27600
27944
|
return { ok: false, error: "db unavailable" };
|
|
27601
|
-
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-
|
|
27602
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
27945
|
+
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-m37p3fq6.js");
|
|
27946
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
|
|
27603
27947
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
27604
27948
|
const ctx = await buildManagedCtx(db);
|
|
27605
27949
|
runManagedRecomp2(ctx, sessionId).then((message) => {
|
|
@@ -27617,8 +27961,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
27617
27961
|
const db = getDb();
|
|
27618
27962
|
if (!db)
|
|
27619
27963
|
return { ok: false, error: "db unavailable" };
|
|
27620
|
-
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-
|
|
27621
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
27964
|
+
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-m37p3fq6.js");
|
|
27965
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
|
|
27622
27966
|
log(`[rpc] session-upgrade requested for session ${sessionId}`);
|
|
27623
27967
|
const ctx = await buildManagedCtx(db);
|
|
27624
27968
|
runManagedUpgrade2(ctx, sessionId).then((message) => {
|
|
@@ -27634,7 +27978,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
27634
27978
|
if (!db)
|
|
27635
27979
|
return { ok: false, error: "db unavailable" };
|
|
27636
27980
|
try {
|
|
27637
|
-
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-
|
|
27981
|
+
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-dse3qv6s.js");
|
|
27638
27982
|
updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
|
|
27639
27983
|
return { ok: true };
|
|
27640
27984
|
} catch (error) {
|
|
@@ -28261,15 +28605,31 @@ function detectMidTurnBypassReason(input) {
|
|
|
28261
28605
|
}
|
|
28262
28606
|
function applyMidTurnDeferral(input) {
|
|
28263
28607
|
if (input.base === "defer") {
|
|
28264
|
-
return {
|
|
28608
|
+
return {
|
|
28609
|
+
midTurnAdjustedSchedulerDecision: "defer",
|
|
28610
|
+
sideEffect: "none",
|
|
28611
|
+
deferReason: "scheduler_defer"
|
|
28612
|
+
};
|
|
28265
28613
|
}
|
|
28266
28614
|
if (input.bypassReason !== "none") {
|
|
28267
|
-
return {
|
|
28615
|
+
return {
|
|
28616
|
+
midTurnAdjustedSchedulerDecision: "execute",
|
|
28617
|
+
sideEffect: "none",
|
|
28618
|
+
deferReason: null
|
|
28619
|
+
};
|
|
28268
28620
|
}
|
|
28269
28621
|
if (input.midTurn) {
|
|
28270
|
-
return {
|
|
28622
|
+
return {
|
|
28623
|
+
midTurnAdjustedSchedulerDecision: "defer",
|
|
28624
|
+
sideEffect: "set-flag",
|
|
28625
|
+
deferReason: "mid_turn_boundary"
|
|
28626
|
+
};
|
|
28271
28627
|
}
|
|
28272
|
-
return {
|
|
28628
|
+
return {
|
|
28629
|
+
midTurnAdjustedSchedulerDecision: "execute",
|
|
28630
|
+
sideEffect: "none",
|
|
28631
|
+
deferReason: null
|
|
28632
|
+
};
|
|
28273
28633
|
}
|
|
28274
28634
|
|
|
28275
28635
|
// src/hooks/magic-context/cache-busting-signals.ts
|
|
@@ -30819,118 +31179,706 @@ class RawFallbackContextLimitError extends Error {
|
|
|
30819
31179
|
}
|
|
30820
31180
|
}
|
|
30821
31181
|
|
|
30822
|
-
// src/hooks/magic-context/
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30828
|
-
|
|
31182
|
+
// src/hooks/magic-context/strip-content.ts
|
|
31183
|
+
var DROPPED_PLACEHOLDER_PATTERN = /^\[dropped §\d+§\]$/;
|
|
31184
|
+
var TAG_PREFIX_PATTERN = /^§\d+§\s*/;
|
|
31185
|
+
var SYSTEM_INJECTION_PATTERNS = [
|
|
31186
|
+
/^<!-- OMO_INTERNAL_INITIATOR -->$/,
|
|
31187
|
+
/^<system-reminder>[\s\S]*<\/system-reminder>$/,
|
|
31188
|
+
/^\[SYSTEM DIRECTIVE:/,
|
|
31189
|
+
/^\[Category\+Skill Reminder\]/,
|
|
31190
|
+
/^\[EDIT ERROR - IMMEDIATE ACTION REQUIRED\]/,
|
|
31191
|
+
/^\[task CALL FAILED/,
|
|
31192
|
+
/^\[EMERGENCY CONTEXT WINDOW WARNING\]/
|
|
31193
|
+
];
|
|
31194
|
+
function isSystemInjectedText(text) {
|
|
31195
|
+
const stripped = text.trim().replace(TAG_PREFIX_PATTERN, "").trim();
|
|
31196
|
+
if (stripped.length === 0)
|
|
31197
|
+
return false;
|
|
31198
|
+
return SYSTEM_INJECTION_PATTERNS.some((pattern) => pattern.test(stripped));
|
|
30829
31199
|
}
|
|
30830
|
-
function
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
31200
|
+
function stripSystemInjectedMessages(messages, protectedTailStart, providerID) {
|
|
31201
|
+
let stripped = 0;
|
|
31202
|
+
const sentineledIds = [];
|
|
31203
|
+
for (let i = 0;i < messages.length; i++) {
|
|
31204
|
+
if (i >= protectedTailStart)
|
|
31205
|
+
continue;
|
|
31206
|
+
const msg = messages[i];
|
|
31207
|
+
if (msg.parts.length === 0)
|
|
31208
|
+
continue;
|
|
31209
|
+
if (msg.info.role === "user")
|
|
31210
|
+
continue;
|
|
31211
|
+
if (msg.parts.length === 1 && isSentinel(msg.parts[0]))
|
|
31212
|
+
continue;
|
|
31213
|
+
let hasContentPart = false;
|
|
31214
|
+
let allContentIsSystemInjection = true;
|
|
31215
|
+
for (const part of msg.parts) {
|
|
31216
|
+
if (!isRecord(part))
|
|
31217
|
+
continue;
|
|
31218
|
+
const partType = part.type;
|
|
31219
|
+
if (METADATA_PART_TYPES.has(partType))
|
|
31220
|
+
continue;
|
|
31221
|
+
if (part.ignored === true)
|
|
31222
|
+
continue;
|
|
31223
|
+
if (partType === "tool") {
|
|
31224
|
+
allContentIsSystemInjection = false;
|
|
31225
|
+
break;
|
|
31226
|
+
}
|
|
31227
|
+
if (partType === "text" && typeof part.text === "string") {
|
|
31228
|
+
hasContentPart = true;
|
|
31229
|
+
if (!isSystemInjectedText(part.text)) {
|
|
31230
|
+
allContentIsSystemInjection = false;
|
|
31231
|
+
break;
|
|
31232
|
+
}
|
|
31233
|
+
continue;
|
|
31234
|
+
}
|
|
31235
|
+
allContentIsSystemInjection = false;
|
|
31236
|
+
break;
|
|
30840
31237
|
}
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
});
|
|
30848
|
-
return persisted.usage;
|
|
31238
|
+
if (hasContentPart && allContentIsSystemInjection) {
|
|
31239
|
+
msg.parts.length = 0;
|
|
31240
|
+
msg.parts.push(makeWholeMessageSentinel(providerID));
|
|
31241
|
+
stripped++;
|
|
31242
|
+
if (typeof msg.info.id === "string")
|
|
31243
|
+
sentineledIds.push(msg.info.id);
|
|
30849
31244
|
}
|
|
30850
|
-
contextUsageMap.delete(sessionId);
|
|
30851
|
-
} catch (error) {
|
|
30852
|
-
sessionLog(sessionId, "transform failed loading persisted usage:", error);
|
|
30853
|
-
return contextUsageEntry?.usage ?? { percentage: 0, inputTokens: 0 };
|
|
30854
|
-
}
|
|
30855
|
-
return { percentage: 0, inputTokens: 0 };
|
|
30856
|
-
}
|
|
30857
|
-
function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey, contextLimit) {
|
|
30858
|
-
try {
|
|
30859
|
-
const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey, contextLimit);
|
|
30860
|
-
sessionLog(sessionId, `transform scheduler: percentage=${contextUsage.percentage.toFixed(1)}% inputTokens=${contextUsage.inputTokens} cacheTtl=${sessionMeta.cacheTtl} lastResponseTime=${sessionMeta.lastResponseTime} decision=${schedulerDecision}`);
|
|
30861
|
-
return schedulerDecision;
|
|
30862
|
-
} catch (error) {
|
|
30863
|
-
sessionLog(sessionId, "transform scheduler failed; defaulting to defer:", error);
|
|
30864
|
-
return "defer";
|
|
30865
|
-
}
|
|
30866
|
-
}
|
|
30867
|
-
|
|
30868
|
-
// src/hooks/magic-context/channel2-cycle.ts
|
|
30869
|
-
function rearmChannel2AfterCoverageAdvancingHardFold(input) {
|
|
30870
|
-
if (input.compactionOff || !input.foldExecuted || input.previousCoverage === null || input.currentCoverage === null || input.currentCoverage <= input.previousCoverage) {
|
|
30871
|
-
return false;
|
|
30872
31245
|
}
|
|
30873
|
-
return
|
|
30874
|
-
}
|
|
30875
|
-
function rearmChannel2AfterMeasuredCollapse(input) {
|
|
30876
|
-
if (!input.baseline.evaluable || input.baseline.generationInvalidated)
|
|
30877
|
-
return false;
|
|
30878
|
-
if (effectiveTailHygiene(input.baseline).u >= CHANNEL1_FLOOR_TOKENS)
|
|
30879
|
-
return false;
|
|
30880
|
-
return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
|
|
30881
|
-
}
|
|
30882
|
-
|
|
30883
|
-
// src/hooks/magic-context/drop-stale-reduce-calls.ts
|
|
30884
|
-
var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
|
|
30885
|
-
function isReduceToolPart(part) {
|
|
30886
|
-
if (!isRecord(part))
|
|
30887
|
-
return false;
|
|
30888
|
-
if (part.type === "tool" && typeof part.tool === "string" && STALE_TOOL_NAMES.has(part.tool))
|
|
30889
|
-
return true;
|
|
30890
|
-
if (part.type === "tool-invocation" && typeof part.toolName === "string" && STALE_TOOL_NAMES.has(part.toolName))
|
|
30891
|
-
return true;
|
|
30892
|
-
if (part.type === "tool_use" && typeof part.name === "string" && STALE_TOOL_NAMES.has(part.name))
|
|
30893
|
-
return true;
|
|
30894
|
-
return false;
|
|
31246
|
+
return { stripped, sentineledIds };
|
|
30895
31247
|
}
|
|
30896
|
-
|
|
30897
|
-
|
|
30898
|
-
|
|
31248
|
+
var METADATA_PART_TYPES = new Set([
|
|
31249
|
+
"step-start",
|
|
31250
|
+
"step-finish",
|
|
31251
|
+
"snapshot",
|
|
31252
|
+
"patch",
|
|
31253
|
+
"agent",
|
|
31254
|
+
"retry",
|
|
31255
|
+
"subtask",
|
|
31256
|
+
"compaction"
|
|
31257
|
+
]);
|
|
31258
|
+
function stripDroppedPlaceholderMessages(messages, providerID) {
|
|
31259
|
+
let stripped = 0;
|
|
31260
|
+
const sentineledIds = [];
|
|
31261
|
+
for (let i = 0;i < messages.length; i++) {
|
|
31262
|
+
const msg = messages[i];
|
|
31263
|
+
if (msg.parts.length === 0)
|
|
30899
31264
|
continue;
|
|
30900
|
-
if (
|
|
30901
|
-
return true;
|
|
30902
|
-
if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking")
|
|
31265
|
+
if (msg.info.role === "user")
|
|
30903
31266
|
continue;
|
|
30904
|
-
if (
|
|
31267
|
+
if (msg.parts.length === 1 && isSentinel(msg.parts[0]))
|
|
30905
31268
|
continue;
|
|
30906
|
-
|
|
30907
|
-
|
|
31269
|
+
let hasContentPart = false;
|
|
31270
|
+
let hasNonDroppedContent = false;
|
|
31271
|
+
for (const part of msg.parts) {
|
|
31272
|
+
if (!isRecord(part))
|
|
31273
|
+
continue;
|
|
31274
|
+
const partType = part.type;
|
|
31275
|
+
if (METADATA_PART_TYPES.has(partType))
|
|
31276
|
+
continue;
|
|
31277
|
+
if (partType === "tool") {
|
|
31278
|
+
hasNonDroppedContent = true;
|
|
31279
|
+
break;
|
|
31280
|
+
}
|
|
31281
|
+
if (partType === "text" && typeof part.text === "string") {
|
|
31282
|
+
hasContentPart = true;
|
|
31283
|
+
const trimmed = part.text.trim();
|
|
31284
|
+
if (trimmed.length === 0)
|
|
31285
|
+
continue;
|
|
31286
|
+
if (!trimmed.includes("[dropped §")) {
|
|
31287
|
+
hasNonDroppedContent = true;
|
|
31288
|
+
break;
|
|
31289
|
+
}
|
|
31290
|
+
const allSegmentsDropped = trimmed.split(/(?=\[dropped §)/).filter((s) => s.trim().length > 0).every((segment) => DROPPED_PLACEHOLDER_PATTERN.test(segment.trim()));
|
|
31291
|
+
if (!allSegmentsDropped) {
|
|
31292
|
+
hasNonDroppedContent = true;
|
|
31293
|
+
break;
|
|
31294
|
+
}
|
|
31295
|
+
continue;
|
|
31296
|
+
}
|
|
31297
|
+
if (partType === "reasoning" && typeof part.text === "string") {
|
|
31298
|
+
hasContentPart = true;
|
|
31299
|
+
const trimmed = part.text.trim();
|
|
31300
|
+
if (trimmed.length === 0)
|
|
31301
|
+
continue;
|
|
31302
|
+
if (!trimmed.includes("[dropped §")) {
|
|
31303
|
+
hasNonDroppedContent = true;
|
|
31304
|
+
break;
|
|
31305
|
+
}
|
|
31306
|
+
const allSegmentsDropped = trimmed.split(/(?=\[dropped §)/).filter((s) => s.trim().length > 0).every((segment) => DROPPED_PLACEHOLDER_PATTERN.test(segment.trim()));
|
|
31307
|
+
if (!allSegmentsDropped) {
|
|
31308
|
+
hasNonDroppedContent = true;
|
|
31309
|
+
break;
|
|
31310
|
+
}
|
|
31311
|
+
continue;
|
|
31312
|
+
}
|
|
31313
|
+
hasNonDroppedContent = true;
|
|
31314
|
+
break;
|
|
31315
|
+
}
|
|
31316
|
+
if (hasContentPart && !hasNonDroppedContent) {
|
|
31317
|
+
msg.parts.length = 0;
|
|
31318
|
+
msg.parts.push(makeWholeMessageSentinel(providerID));
|
|
31319
|
+
stripped++;
|
|
31320
|
+
if (typeof msg.info.id === "string")
|
|
31321
|
+
sentineledIds.push(msg.info.id);
|
|
31322
|
+
}
|
|
30908
31323
|
}
|
|
30909
|
-
return
|
|
31324
|
+
return { stripped, sentineledIds };
|
|
30910
31325
|
}
|
|
30911
|
-
function
|
|
30912
|
-
|
|
30913
|
-
|
|
31326
|
+
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark) {
|
|
31327
|
+
if (persistedWatermark <= 0)
|
|
31328
|
+
return 0;
|
|
31329
|
+
let cleared = 0;
|
|
31330
|
+
for (const message of messages) {
|
|
31331
|
+
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31332
|
+
if (msgTag === 0 || msgTag > persistedWatermark)
|
|
30914
31333
|
continue;
|
|
30915
|
-
|
|
30916
|
-
|
|
31334
|
+
const parts = reasoningByMessage.get(message);
|
|
31335
|
+
if (!parts)
|
|
31336
|
+
continue;
|
|
31337
|
+
for (const tp of parts) {
|
|
31338
|
+
if (tp.thinking !== undefined && tp.thinking !== "[cleared]") {
|
|
31339
|
+
tp.thinking = "[cleared]";
|
|
31340
|
+
cleared++;
|
|
31341
|
+
}
|
|
31342
|
+
if (tp.text !== undefined && tp.text !== "[cleared]") {
|
|
31343
|
+
tp.text = "[cleared]";
|
|
31344
|
+
cleared++;
|
|
31345
|
+
}
|
|
31346
|
+
}
|
|
30917
31347
|
}
|
|
30918
|
-
return
|
|
31348
|
+
return cleared;
|
|
30919
31349
|
}
|
|
30920
|
-
function
|
|
30921
|
-
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
|
|
31350
|
+
function replayStrippedInlineThinking(messages, messageTagNumbers, persistedWatermark) {
|
|
31351
|
+
if (persistedWatermark <= 0)
|
|
31352
|
+
return 0;
|
|
31353
|
+
let stripped = 0;
|
|
31354
|
+
for (const message of messages) {
|
|
31355
|
+
if (message.info.role !== "assistant")
|
|
30925
31356
|
continue;
|
|
30926
|
-
|
|
30927
|
-
|
|
30928
|
-
|
|
31357
|
+
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31358
|
+
if (msgTag === 0 || msgTag > persistedWatermark)
|
|
31359
|
+
continue;
|
|
31360
|
+
for (const part of message.parts) {
|
|
31361
|
+
if (!isRecord(part) || part.type !== "text" || typeof part.text !== "string")
|
|
31362
|
+
continue;
|
|
31363
|
+
if (!part.text.includes("<think"))
|
|
31364
|
+
continue;
|
|
31365
|
+
const cleaned = part.text.replace(INLINE_THINKING_PATTERN, "");
|
|
31366
|
+
if (cleaned !== part.text) {
|
|
31367
|
+
part.text = cleaned;
|
|
31368
|
+
stripped++;
|
|
31369
|
+
}
|
|
30929
31370
|
}
|
|
30930
31371
|
}
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
|
|
31372
|
+
return stripped;
|
|
31373
|
+
}
|
|
31374
|
+
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge) {
|
|
31375
|
+
const maxTag = findMaxTag(messageTagNumbers);
|
|
31376
|
+
if (maxTag === 0)
|
|
31377
|
+
return 0;
|
|
31378
|
+
const ageCutoff = maxTag - clearReasoningAge;
|
|
31379
|
+
let cleared = 0;
|
|
31380
|
+
for (const message of messages) {
|
|
31381
|
+
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31382
|
+
if (msgTag === 0 || msgTag > ageCutoff)
|
|
31383
|
+
continue;
|
|
31384
|
+
const parts = reasoningByMessage.get(message);
|
|
31385
|
+
if (!parts)
|
|
31386
|
+
continue;
|
|
31387
|
+
for (const tp of parts) {
|
|
31388
|
+
if (tp.thinking !== undefined && tp.thinking !== "[cleared]") {
|
|
31389
|
+
tp.thinking = "[cleared]";
|
|
31390
|
+
cleared++;
|
|
31391
|
+
}
|
|
31392
|
+
if (tp.text !== undefined && tp.text !== "[cleared]") {
|
|
31393
|
+
tp.text = "[cleared]";
|
|
31394
|
+
cleared++;
|
|
31395
|
+
}
|
|
31396
|
+
}
|
|
31397
|
+
}
|
|
31398
|
+
return cleared;
|
|
31399
|
+
}
|
|
31400
|
+
function findMaxTag(messageTagNumbers) {
|
|
31401
|
+
let max = 0;
|
|
31402
|
+
for (const tag of messageTagNumbers.values()) {
|
|
31403
|
+
if (tag > max)
|
|
31404
|
+
max = tag;
|
|
31405
|
+
}
|
|
31406
|
+
return max;
|
|
31407
|
+
}
|
|
31408
|
+
var CLEARED_REASONING_TYPES = new Set(["thinking", "reasoning"]);
|
|
31409
|
+
function stripClearedReasoning(messages) {
|
|
31410
|
+
let stripped = 0;
|
|
31411
|
+
for (const message of messages) {
|
|
31412
|
+
if (message.info.role !== "assistant")
|
|
31413
|
+
continue;
|
|
31414
|
+
for (let i = 0;i < message.parts.length; i++) {
|
|
31415
|
+
const part = message.parts[i];
|
|
31416
|
+
if (!isRecord(part))
|
|
31417
|
+
continue;
|
|
31418
|
+
const partType = part.type;
|
|
31419
|
+
if (!CLEARED_REASONING_TYPES.has(partType))
|
|
31420
|
+
continue;
|
|
31421
|
+
if (!("thinking" in part) && !("text" in part))
|
|
31422
|
+
continue;
|
|
31423
|
+
const thinking = "thinking" in part ? part.thinking : undefined;
|
|
31424
|
+
const text = "text" in part ? part.text : undefined;
|
|
31425
|
+
const isCleared = (thinking === undefined || thinking === "[cleared]") && (text === undefined || text === "[cleared]");
|
|
31426
|
+
if (!isCleared)
|
|
31427
|
+
continue;
|
|
31428
|
+
message.parts[i] = makeSentinel(part);
|
|
31429
|
+
stripped++;
|
|
31430
|
+
}
|
|
31431
|
+
}
|
|
31432
|
+
return stripped;
|
|
31433
|
+
}
|
|
31434
|
+
var INLINE_THINKING_PATTERN = /<(?:thinking|think)>[\s\S]*?<\/(?:thinking|think)>\s*/g;
|
|
31435
|
+
function stripInlineThinking(messages, messageTagNumbers, clearReasoningAge) {
|
|
31436
|
+
const maxTag = findMaxTag(messageTagNumbers);
|
|
31437
|
+
if (maxTag === 0)
|
|
31438
|
+
return 0;
|
|
31439
|
+
const ageCutoff = maxTag - clearReasoningAge;
|
|
31440
|
+
let stripped = 0;
|
|
31441
|
+
for (const message of messages) {
|
|
31442
|
+
if (message.info.role !== "assistant")
|
|
31443
|
+
continue;
|
|
31444
|
+
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31445
|
+
if (msgTag === 0 || msgTag > ageCutoff)
|
|
31446
|
+
continue;
|
|
31447
|
+
for (const part of message.parts) {
|
|
31448
|
+
if (!isRecord(part) || part.type !== "text" || typeof part.text !== "string")
|
|
31449
|
+
continue;
|
|
31450
|
+
const cleaned = part.text.replace(INLINE_THINKING_PATTERN, "");
|
|
31451
|
+
if (cleaned !== part.text) {
|
|
31452
|
+
part.text = cleaned;
|
|
31453
|
+
stripped++;
|
|
31454
|
+
}
|
|
31455
|
+
}
|
|
31456
|
+
}
|
|
31457
|
+
return stripped;
|
|
31458
|
+
}
|
|
31459
|
+
var REASONING_IGNORED_PART_TYPES = new Set([
|
|
31460
|
+
"step-start",
|
|
31461
|
+
"step-finish",
|
|
31462
|
+
"snapshot",
|
|
31463
|
+
"patch",
|
|
31464
|
+
"agent",
|
|
31465
|
+
"retry",
|
|
31466
|
+
"subtask",
|
|
31467
|
+
"compaction"
|
|
31468
|
+
]);
|
|
31469
|
+
var REASONING_PART_TYPES = new Set(["reasoning", "thinking", "redacted_thinking"]);
|
|
31470
|
+
function hasReasoningReplayContent(message) {
|
|
31471
|
+
return message.parts.some((part) => {
|
|
31472
|
+
if (!isRecord(part) || part.ignored === true)
|
|
31473
|
+
return false;
|
|
31474
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
31475
|
+
if (REASONING_IGNORED_PART_TYPES.has(type))
|
|
31476
|
+
return false;
|
|
31477
|
+
return type !== "text" || typeof part.text !== "string" || part.text.trim().length > 0;
|
|
31478
|
+
});
|
|
31479
|
+
}
|
|
31480
|
+
function findNewestReasoningBearingAssistantId(messages) {
|
|
31481
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
31482
|
+
const message = messages[index];
|
|
31483
|
+
if (message.info.role !== "assistant")
|
|
31484
|
+
continue;
|
|
31485
|
+
if (!message.parts.some((part) => isRecord(part) && REASONING_PART_TYPES.has(String(part.type)))) {
|
|
31486
|
+
continue;
|
|
31487
|
+
}
|
|
31488
|
+
const id = message.info.id;
|
|
31489
|
+
if (typeof id === "string" && id.length > 0)
|
|
31490
|
+
return id;
|
|
31491
|
+
}
|
|
31492
|
+
return;
|
|
31493
|
+
}
|
|
31494
|
+
function assistantHasReasoningPart(messages, messageId2) {
|
|
31495
|
+
return messages.some((message) => message.info.role === "assistant" && message.info.id === messageId2 && message.parts.some((part) => isRecord(part) && REASONING_PART_TYPES.has(String(part.type))));
|
|
31496
|
+
}
|
|
31497
|
+
function findLatestAssistantReasoningMutationExemptMessage(messages) {
|
|
31498
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
31499
|
+
const message = messages[index];
|
|
31500
|
+
if (message.info.role === "assistant" && hasReasoningReplayContent(message))
|
|
31501
|
+
return message;
|
|
31502
|
+
}
|
|
31503
|
+
return;
|
|
31504
|
+
}
|
|
31505
|
+
function planMergedAssistantReasoningStrip(messages, mutationExemptMessage) {
|
|
31506
|
+
const plan = [];
|
|
31507
|
+
let prevRole;
|
|
31508
|
+
let keptReasoningInRun = false;
|
|
31509
|
+
for (const message of messages) {
|
|
31510
|
+
const role = message.info.role;
|
|
31511
|
+
if (role !== "assistant") {
|
|
31512
|
+
prevRole = role;
|
|
31513
|
+
keptReasoningInRun = false;
|
|
31514
|
+
continue;
|
|
31515
|
+
}
|
|
31516
|
+
const firstInRun = prevRole !== "assistant";
|
|
31517
|
+
if (firstInRun)
|
|
31518
|
+
keptReasoningInRun = false;
|
|
31519
|
+
if (message === mutationExemptMessage) {
|
|
31520
|
+
prevRole = role;
|
|
31521
|
+
continue;
|
|
31522
|
+
}
|
|
31523
|
+
let keepIndex = -1;
|
|
31524
|
+
if (firstInRun && !keptReasoningInRun) {
|
|
31525
|
+
for (let i = 0;i < message.parts.length; i++) {
|
|
31526
|
+
const part = message.parts[i];
|
|
31527
|
+
if (!isRecord(part))
|
|
31528
|
+
continue;
|
|
31529
|
+
const partType = part.type;
|
|
31530
|
+
if (REASONING_IGNORED_PART_TYPES.has(partType))
|
|
31531
|
+
continue;
|
|
31532
|
+
if (part.ignored === true)
|
|
31533
|
+
continue;
|
|
31534
|
+
if (isSentinel(part))
|
|
31535
|
+
continue;
|
|
31536
|
+
if (partType === "text" && typeof part.text === "string" && part.text.trim() === "") {
|
|
31537
|
+
continue;
|
|
31538
|
+
}
|
|
31539
|
+
if (REASONING_PART_TYPES.has(partType)) {
|
|
31540
|
+
keepIndex = i;
|
|
31541
|
+
}
|
|
31542
|
+
break;
|
|
31543
|
+
}
|
|
31544
|
+
}
|
|
31545
|
+
const stripIndices = [];
|
|
31546
|
+
for (let i = 0;i < message.parts.length; i++) {
|
|
31547
|
+
const part = message.parts[i];
|
|
31548
|
+
if (!isRecord(part))
|
|
31549
|
+
continue;
|
|
31550
|
+
if (!REASONING_PART_TYPES.has(part.type))
|
|
31551
|
+
continue;
|
|
31552
|
+
if (part.cache_control !== undefined)
|
|
31553
|
+
continue;
|
|
31554
|
+
if (i === keepIndex) {
|
|
31555
|
+
keptReasoningInRun = true;
|
|
31556
|
+
continue;
|
|
31557
|
+
}
|
|
31558
|
+
stripIndices.push(i);
|
|
31559
|
+
}
|
|
31560
|
+
if (stripIndices.length > 0)
|
|
31561
|
+
plan.push({ message, stripIndices });
|
|
31562
|
+
prevRole = role;
|
|
31563
|
+
}
|
|
31564
|
+
return plan;
|
|
31565
|
+
}
|
|
31566
|
+
var MAX_FROZEN_TRAILING_BLANKS = 1e4;
|
|
31567
|
+
var CANONICAL_BLANK_PART = { type: "text", text: "" };
|
|
31568
|
+
function isSentinelInvisibleTextPart(part) {
|
|
31569
|
+
return isRecord(part) && part.type === "text" && typeof part.text === "string" && part.text.trim() === "";
|
|
31570
|
+
}
|
|
31571
|
+
function isCanonicalBlankPart(part) {
|
|
31572
|
+
return isRecord(part) && Object.keys(part).length === 2 && part.type === "text" && part.text === "";
|
|
31573
|
+
}
|
|
31574
|
+
function trailingBlankKeepCount(decision) {
|
|
31575
|
+
if (decision === "keep")
|
|
31576
|
+
return 1;
|
|
31577
|
+
if (!decision.startsWith("keep:"))
|
|
31578
|
+
return;
|
|
31579
|
+
const countText = decision.slice("keep:".length);
|
|
31580
|
+
if (!/^[1-9]\d*$/.test(countText))
|
|
31581
|
+
return;
|
|
31582
|
+
const count = Number(countText);
|
|
31583
|
+
return Number.isSafeInteger(count) && count > 0 && count <= MAX_FROZEN_TRAILING_BLANKS ? count : undefined;
|
|
31584
|
+
}
|
|
31585
|
+
function trailingBlankDecisionForMessage(message) {
|
|
31586
|
+
const id = message.info.id;
|
|
31587
|
+
if (message.info.role !== "assistant" || typeof id !== "string" || id.length === 0) {
|
|
31588
|
+
return;
|
|
31589
|
+
}
|
|
31590
|
+
let trailingCount = 0;
|
|
31591
|
+
while (trailingCount < message.parts.length && isSentinelInvisibleTextPart(message.parts[message.parts.length - trailingCount - 1])) {
|
|
31592
|
+
trailingCount += 1;
|
|
31593
|
+
}
|
|
31594
|
+
if (trailingCount > MAX_FROZEN_TRAILING_BLANKS && trailingCount < message.parts.length) {
|
|
31595
|
+
return;
|
|
31596
|
+
}
|
|
31597
|
+
const decision = message.parts.length === 0 || trailingCount === message.parts.length ? "keep" : trailingCount === 0 ? "strip" : trailingCount === 1 ? "keep" : `keep:${trailingCount}`;
|
|
31598
|
+
return [id, decision];
|
|
31599
|
+
}
|
|
31600
|
+
function snapshotTrailingBlankSourceDecisions(messages) {
|
|
31601
|
+
const decisions = new Map;
|
|
31602
|
+
for (const message of messages) {
|
|
31603
|
+
const observed = trailingBlankDecisionForMessage(message);
|
|
31604
|
+
if (observed)
|
|
31605
|
+
decisions.set(...observed);
|
|
31606
|
+
}
|
|
31607
|
+
return decisions;
|
|
31608
|
+
}
|
|
31609
|
+
function findTrailingBlankDecisionCandidates(messages, frozenDecisions, options) {
|
|
31610
|
+
const observedDecisions = options?.sourceDecisions ?? snapshotTrailingBlankSourceDecisions(messages);
|
|
31611
|
+
const visibleIds = new Set(messages.flatMap((message) => typeof message.info.id === "string" ? [message.info.id] : []));
|
|
31612
|
+
const decisions = [];
|
|
31613
|
+
for (const [id, decision] of observedDecisions) {
|
|
31614
|
+
if (!visibleIds.has(id))
|
|
31615
|
+
continue;
|
|
31616
|
+
const frozen = frozenDecisions.get(id);
|
|
31617
|
+
if (frozen !== undefined && (id !== options?.refreshMessageId || frozen === decision || frozen === "strip")) {
|
|
31618
|
+
continue;
|
|
31619
|
+
}
|
|
31620
|
+
decisions.push([id, decision]);
|
|
31621
|
+
}
|
|
31622
|
+
return decisions;
|
|
31623
|
+
}
|
|
31624
|
+
function applyFrozenTrailingBlankDecisions(messages, frozenDecisions) {
|
|
31625
|
+
let mutations = 0;
|
|
31626
|
+
for (let messageIndex = 0;messageIndex < messages.length; messageIndex += 1) {
|
|
31627
|
+
let message = messages[messageIndex];
|
|
31628
|
+
const id = message.info.id;
|
|
31629
|
+
if (message.info.role !== "assistant" || typeof id !== "string")
|
|
31630
|
+
continue;
|
|
31631
|
+
const decision = frozenDecisions.get(id);
|
|
31632
|
+
if (!decision)
|
|
31633
|
+
continue;
|
|
31634
|
+
let lastMeaningfulIndex = message.parts.length - 1;
|
|
31635
|
+
while (lastMeaningfulIndex >= 0 && isSentinelInvisibleTextPart(message.parts[lastMeaningfulIndex])) {
|
|
31636
|
+
lastMeaningfulIndex -= 1;
|
|
31637
|
+
}
|
|
31638
|
+
const replaceParts = (start, deleteCount, insertBlankCount) => {
|
|
31639
|
+
message = { ...message, parts: [...message.parts] };
|
|
31640
|
+
messages[messageIndex] = message;
|
|
31641
|
+
message.parts.splice(start, deleteCount, ...Array.from({ length: insertBlankCount }, () => ({ ...CANONICAL_BLANK_PART })));
|
|
31642
|
+
};
|
|
31643
|
+
if (lastMeaningfulIndex < 0) {
|
|
31644
|
+
if (message.parts.length === 0)
|
|
31645
|
+
continue;
|
|
31646
|
+
if (message.parts.length !== 1 || !isCanonicalBlankPart(message.parts[0])) {
|
|
31647
|
+
mutations += Math.max(1, message.parts.length);
|
|
31648
|
+
replaceParts(0, message.parts.length, 1);
|
|
31649
|
+
}
|
|
31650
|
+
continue;
|
|
31651
|
+
}
|
|
31652
|
+
const trailingCount = message.parts.length - lastMeaningfulIndex - 1;
|
|
31653
|
+
const keepCount = trailingBlankKeepCount(decision);
|
|
31654
|
+
if (keepCount !== undefined) {
|
|
31655
|
+
if (trailingCount === 0)
|
|
31656
|
+
continue;
|
|
31657
|
+
const blankIndex = lastMeaningfulIndex + 1;
|
|
31658
|
+
const suffixIsCanonical = trailingCount === keepCount && message.parts.slice(blankIndex).every(isCanonicalBlankPart);
|
|
31659
|
+
if (!suffixIsCanonical) {
|
|
31660
|
+
mutations += Math.max(1, trailingCount, keepCount);
|
|
31661
|
+
replaceParts(blankIndex, trailingCount, keepCount);
|
|
31662
|
+
}
|
|
31663
|
+
continue;
|
|
31664
|
+
}
|
|
31665
|
+
if (trailingCount === 0)
|
|
31666
|
+
continue;
|
|
31667
|
+
const lastMeaningfulPart = message.parts[lastMeaningfulIndex];
|
|
31668
|
+
if (isRecord(lastMeaningfulPart) && REASONING_PART_TYPES.has(lastMeaningfulPart.type)) {
|
|
31669
|
+
const blankIndex = lastMeaningfulIndex + 1;
|
|
31670
|
+
if (trailingCount !== 1 || !isCanonicalBlankPart(message.parts[blankIndex])) {
|
|
31671
|
+
mutations += Math.max(1, trailingCount);
|
|
31672
|
+
replaceParts(blankIndex, trailingCount, 1);
|
|
31673
|
+
}
|
|
31674
|
+
continue;
|
|
31675
|
+
}
|
|
31676
|
+
mutations += trailingCount;
|
|
31677
|
+
replaceParts(lastMeaningfulIndex + 1, trailingCount, 0);
|
|
31678
|
+
}
|
|
31679
|
+
return mutations;
|
|
31680
|
+
}
|
|
31681
|
+
function findMergedReasoningStripCandidateIds(messages, providerID, options) {
|
|
31682
|
+
if (providerID !== "anthropic")
|
|
31683
|
+
return [];
|
|
31684
|
+
const ids = new Set;
|
|
31685
|
+
for (const entry of planMergedAssistantReasoningStrip(messages, options?.mutationExemptMessage)) {
|
|
31686
|
+
const id = entry.message.info.id;
|
|
31687
|
+
if (typeof id === "string" && id.length > 0)
|
|
31688
|
+
ids.add(id);
|
|
31689
|
+
}
|
|
31690
|
+
return [...ids];
|
|
31691
|
+
}
|
|
31692
|
+
function stripReasoningFromAssistantIds(messages, providerID, messageIds) {
|
|
31693
|
+
if (providerID !== "anthropic" || messageIds.size === 0)
|
|
31694
|
+
return 0;
|
|
31695
|
+
let stripped = 0;
|
|
31696
|
+
for (const message of messages) {
|
|
31697
|
+
const id = message.info.id;
|
|
31698
|
+
if (typeof id !== "string" || !messageIds.has(id))
|
|
31699
|
+
continue;
|
|
31700
|
+
for (let index = 0;index < message.parts.length; index += 1) {
|
|
31701
|
+
const part = message.parts[index];
|
|
31702
|
+
if (!isRecord(part) || !REASONING_PART_TYPES.has(String(part.type)))
|
|
31703
|
+
continue;
|
|
31704
|
+
message.parts[index] = makeSentinel(part);
|
|
31705
|
+
stripped += 1;
|
|
31706
|
+
}
|
|
31707
|
+
}
|
|
31708
|
+
return stripped;
|
|
31709
|
+
}
|
|
31710
|
+
function stripReasoningFromMergedAssistants(messages, providerID, options) {
|
|
31711
|
+
if (providerID !== "anthropic")
|
|
31712
|
+
return 0;
|
|
31713
|
+
let stripped = 0;
|
|
31714
|
+
for (const entry of planMergedAssistantReasoningStrip(messages, options?.mutationExemptMessage)) {
|
|
31715
|
+
if (options?.frozenMessageIds) {
|
|
31716
|
+
const id = entry.message.info.id;
|
|
31717
|
+
if (typeof id !== "string" || !options.frozenMessageIds.has(id))
|
|
31718
|
+
continue;
|
|
31719
|
+
}
|
|
31720
|
+
for (const index of entry.stripIndices) {
|
|
31721
|
+
entry.message.parts[index] = makeSentinel(entry.message.parts[index]);
|
|
31722
|
+
stripped++;
|
|
31723
|
+
}
|
|
31724
|
+
}
|
|
31725
|
+
return stripped;
|
|
31726
|
+
}
|
|
31727
|
+
function stripProcessedImages(messages, frozenIds, options) {
|
|
31728
|
+
const { detect, watermark, messageTagNumbers } = options;
|
|
31729
|
+
let stripped = 0;
|
|
31730
|
+
const newlyStrippedIds = [];
|
|
31731
|
+
let hasAssistantResponse = false;
|
|
31732
|
+
for (let i = messages.length - 1;i >= 0; i--) {
|
|
31733
|
+
const msg = messages[i];
|
|
31734
|
+
if (msg.info.role === "assistant") {
|
|
31735
|
+
hasAssistantResponse = true;
|
|
31736
|
+
continue;
|
|
31737
|
+
}
|
|
31738
|
+
if (msg.info.role !== "user") {
|
|
31739
|
+
continue;
|
|
31740
|
+
}
|
|
31741
|
+
const id = typeof msg.info.id === "string" ? msg.info.id : undefined;
|
|
31742
|
+
const inFrozen = id !== undefined && frozenIds.has(id);
|
|
31743
|
+
const maxTag = messageTagNumbers.get(msg) ?? 0;
|
|
31744
|
+
const isNewDetection = !inFrozen && detect && hasAssistantResponse && id !== undefined && maxTag <= watermark;
|
|
31745
|
+
if (!inFrozen && !isNewDetection) {
|
|
31746
|
+
continue;
|
|
31747
|
+
}
|
|
31748
|
+
let touchedThisMsg = false;
|
|
31749
|
+
for (let j = 0;j < msg.parts.length; j++) {
|
|
31750
|
+
const part = msg.parts[j];
|
|
31751
|
+
if (!isRecord(part) || part.type !== "file") {
|
|
31752
|
+
continue;
|
|
31753
|
+
}
|
|
31754
|
+
if (typeof part.mime !== "string" || !part.mime.startsWith("image/")) {
|
|
31755
|
+
continue;
|
|
31756
|
+
}
|
|
31757
|
+
if (typeof part.url === "string" && part.url.startsWith("data:") && part.url.length > 200) {
|
|
31758
|
+
msg.parts[j] = makeSentinel(part);
|
|
31759
|
+
stripped++;
|
|
31760
|
+
touchedThisMsg = true;
|
|
31761
|
+
}
|
|
31762
|
+
}
|
|
31763
|
+
if (touchedThisMsg && isNewDetection && id !== undefined) {
|
|
31764
|
+
newlyStrippedIds.push(id);
|
|
31765
|
+
}
|
|
31766
|
+
}
|
|
31767
|
+
return { stripped, newlyStrippedIds };
|
|
31768
|
+
}
|
|
31769
|
+
|
|
31770
|
+
// src/hooks/magic-context/transform-context-state.ts
|
|
31771
|
+
function loadPersistedUsageWatermark(db, sessionId) {
|
|
31772
|
+
const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
31773
|
+
if (result === null || typeof result !== "object")
|
|
31774
|
+
return null;
|
|
31775
|
+
const lastResponseTime = result.last_response_time;
|
|
31776
|
+
return typeof lastResponseTime === "number" ? lastResponseTime : null;
|
|
31777
|
+
}
|
|
31778
|
+
function loadContextUsage(contextUsageMap, db, sessionId) {
|
|
31779
|
+
const contextUsageEntry = contextUsageMap.get(sessionId);
|
|
31780
|
+
try {
|
|
31781
|
+
const persistedLastResponseTime = loadPersistedUsageWatermark(db, sessionId);
|
|
31782
|
+
const cachedLastResponseTime = contextUsageEntry?.lastResponseTime ?? contextUsageEntry?.updatedAt;
|
|
31783
|
+
if (contextUsageEntry && contextUsageEntry.lastResponseTime === undefined && (persistedLastResponseTime === null || persistedLastResponseTime === 0)) {
|
|
31784
|
+
return contextUsageEntry.usage;
|
|
31785
|
+
}
|
|
31786
|
+
if (contextUsageEntry && cachedLastResponseTime === persistedLastResponseTime) {
|
|
31787
|
+
return contextUsageEntry.usage;
|
|
31788
|
+
}
|
|
31789
|
+
const persisted = loadPersistedUsage(db, sessionId);
|
|
31790
|
+
if (persisted) {
|
|
31791
|
+
contextUsageMap.set(sessionId, {
|
|
31792
|
+
...persisted,
|
|
31793
|
+
lastResponseTime: persistedLastResponseTime ?? persisted.updatedAt,
|
|
31794
|
+
hasUsageTokens: false
|
|
31795
|
+
});
|
|
31796
|
+
return persisted.usage;
|
|
31797
|
+
}
|
|
31798
|
+
contextUsageMap.delete(sessionId);
|
|
31799
|
+
} catch (error) {
|
|
31800
|
+
sessionLog(sessionId, "transform failed loading persisted usage:", error);
|
|
31801
|
+
return contextUsageEntry?.usage ?? { percentage: 0, inputTokens: 0 };
|
|
31802
|
+
}
|
|
31803
|
+
return { percentage: 0, inputTokens: 0 };
|
|
31804
|
+
}
|
|
31805
|
+
function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey, contextLimit) {
|
|
31806
|
+
try {
|
|
31807
|
+
const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey, contextLimit);
|
|
31808
|
+
sessionLog(sessionId, `transform scheduler: percentage=${contextUsage.percentage.toFixed(1)}% inputTokens=${contextUsage.inputTokens} cacheTtl=${sessionMeta.cacheTtl} lastResponseTime=${sessionMeta.lastResponseTime} decision=${schedulerDecision}`);
|
|
31809
|
+
return schedulerDecision;
|
|
31810
|
+
} catch (error) {
|
|
31811
|
+
sessionLog(sessionId, "transform scheduler failed; defaulting to defer:", error);
|
|
31812
|
+
return "defer";
|
|
31813
|
+
}
|
|
31814
|
+
}
|
|
31815
|
+
|
|
31816
|
+
// src/hooks/magic-context/channel2-cycle.ts
|
|
31817
|
+
function rearmChannel2AfterCoverageAdvancingHardFold(input) {
|
|
31818
|
+
if (input.compactionOff || !input.foldExecuted || input.previousCoverage === null || input.currentCoverage === null || input.currentCoverage <= input.previousCoverage) {
|
|
31819
|
+
return false;
|
|
31820
|
+
}
|
|
31821
|
+
return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
|
|
31822
|
+
}
|
|
31823
|
+
function rearmChannel2AfterMeasuredCollapse(input) {
|
|
31824
|
+
if (!input.baseline.evaluable || input.baseline.generationInvalidated)
|
|
31825
|
+
return false;
|
|
31826
|
+
if (effectiveTailHygiene(input.baseline).u >= CHANNEL1_FLOOR_TOKENS)
|
|
31827
|
+
return false;
|
|
31828
|
+
return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
|
|
31829
|
+
}
|
|
31830
|
+
|
|
31831
|
+
// src/hooks/magic-context/drop-stale-reduce-calls.ts
|
|
31832
|
+
var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
|
|
31833
|
+
function isReduceToolPart(part) {
|
|
31834
|
+
if (!isRecord(part))
|
|
31835
|
+
return false;
|
|
31836
|
+
if (part.type === "tool" && typeof part.tool === "string" && STALE_TOOL_NAMES.has(part.tool))
|
|
31837
|
+
return true;
|
|
31838
|
+
if (part.type === "tool-invocation" && typeof part.toolName === "string" && STALE_TOOL_NAMES.has(part.toolName))
|
|
31839
|
+
return true;
|
|
31840
|
+
if (part.type === "tool_use" && typeof part.name === "string" && STALE_TOOL_NAMES.has(part.name))
|
|
31841
|
+
return true;
|
|
31842
|
+
return false;
|
|
31843
|
+
}
|
|
31844
|
+
function hasAnyMeaningfulPart(parts) {
|
|
31845
|
+
for (const part of parts) {
|
|
31846
|
+
if (!isRecord(part))
|
|
31847
|
+
continue;
|
|
31848
|
+
if (part.type === "text" && typeof part.text === "string" && part.text.trim().length > 0)
|
|
31849
|
+
return true;
|
|
31850
|
+
if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking")
|
|
31851
|
+
continue;
|
|
31852
|
+
if (part.type === "meta" || part.type === "step-start" || part.type === "step-finish")
|
|
31853
|
+
continue;
|
|
31854
|
+
if (part.type !== "tool" || !isReduceToolPart(part))
|
|
31855
|
+
return true;
|
|
31856
|
+
}
|
|
31857
|
+
return false;
|
|
31858
|
+
}
|
|
31859
|
+
function messageHasReducePart(message) {
|
|
31860
|
+
for (const part of message.parts) {
|
|
31861
|
+
if (isSentinel(part))
|
|
31862
|
+
continue;
|
|
31863
|
+
if (isReduceToolPart(part))
|
|
31864
|
+
return true;
|
|
31865
|
+
}
|
|
31866
|
+
return false;
|
|
31867
|
+
}
|
|
31868
|
+
function sentinelizeReduceParts(message) {
|
|
31869
|
+
let touched = false;
|
|
31870
|
+
for (let j = 0;j < message.parts.length; j++) {
|
|
31871
|
+
const part = message.parts[j];
|
|
31872
|
+
if (isSentinel(part))
|
|
31873
|
+
continue;
|
|
31874
|
+
if (isReduceToolPart(part)) {
|
|
31875
|
+
message.parts[j] = makeSentinel(part);
|
|
31876
|
+
touched = true;
|
|
31877
|
+
}
|
|
31878
|
+
}
|
|
31879
|
+
if (touched && !hasAnyMeaningfulPart(message.parts)) {
|
|
31880
|
+
message.parts.length = 0;
|
|
31881
|
+
message.parts.push(makeSentinel(undefined));
|
|
30934
31882
|
}
|
|
30935
31883
|
return touched;
|
|
30936
31884
|
}
|
|
@@ -31121,699 +32069,146 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
31121
32069
|
}
|
|
31122
32070
|
const fingerprintGroups = new Map;
|
|
31123
32071
|
for (const [compositeKey, fingerprint] of toolFingerprints) {
|
|
31124
|
-
const tag = tagsByCompositeKey.get(compositeKey);
|
|
31125
|
-
if (!tag || tag.tagNumber > protectedCutoff)
|
|
31126
|
-
continue;
|
|
31127
|
-
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
31128
|
-
group.push(tag);
|
|
31129
|
-
fingerprintGroups.set(fingerprint, group);
|
|
31130
|
-
}
|
|
31131
|
-
db.transaction(() => {
|
|
31132
|
-
for (const [, group] of fingerprintGroups) {
|
|
31133
|
-
if (group.length <= 1)
|
|
31134
|
-
continue;
|
|
31135
|
-
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
31136
|
-
for (let i = 0;i < group.length - 1; i++) {
|
|
31137
|
-
const tag = group[i];
|
|
31138
|
-
const target = targets.get(tag.tagNumber);
|
|
31139
|
-
const result = target?.drop?.() ?? "absent";
|
|
31140
|
-
if (result === "incomplete")
|
|
31141
|
-
continue;
|
|
31142
|
-
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
31143
|
-
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
31144
|
-
if (result === "removed" || result === "truncated") {
|
|
31145
|
-
deduplicatedTools++;
|
|
31146
|
-
}
|
|
31147
|
-
}
|
|
31148
|
-
}
|
|
31149
|
-
})();
|
|
31150
|
-
}
|
|
31151
|
-
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
|
|
31152
|
-
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
31153
|
-
}
|
|
31154
|
-
let compressedTextTags = 0;
|
|
31155
|
-
let mutatedTextTags = 0;
|
|
31156
|
-
if (config.routine !== false && config.caveman?.enabled) {
|
|
31157
|
-
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
|
|
31158
|
-
enabled: true,
|
|
31159
|
-
minChars: config.caveman.minChars,
|
|
31160
|
-
protectedTags: config.protectedTags
|
|
31161
|
-
});
|
|
31162
|
-
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
31163
|
-
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
31164
|
-
}
|
|
31165
|
-
return {
|
|
31166
|
-
droppedTools,
|
|
31167
|
-
deduplicatedTools,
|
|
31168
|
-
droppedInjections,
|
|
31169
|
-
emergencyDroppedTools,
|
|
31170
|
-
emergencyReclaimedTokens,
|
|
31171
|
-
compressedTextTags,
|
|
31172
|
-
mutatedTextTags
|
|
31173
|
-
};
|
|
31174
|
-
}
|
|
31175
|
-
function extractToolInfo(part) {
|
|
31176
|
-
if (part.type === "tool" && typeof part.tool === "string" && DEDUP_SAFE_TOOLS.has(part.tool)) {
|
|
31177
|
-
const state = typeof part.state === "object" && part.state !== null ? part.state : {};
|
|
31178
|
-
return { toolName: part.tool, args: state.input ?? {} };
|
|
31179
|
-
}
|
|
31180
|
-
if (part.type === "tool-invocation" && typeof part.toolName === "string" && DEDUP_SAFE_TOOLS.has(part.toolName)) {
|
|
31181
|
-
return { toolName: part.toolName, args: part.args ?? {} };
|
|
31182
|
-
}
|
|
31183
|
-
if (part.type === "tool_use" && typeof part.name === "string" && DEDUP_SAFE_TOOLS.has(part.name)) {
|
|
31184
|
-
return { toolName: part.name, args: part.input ?? {} };
|
|
31185
|
-
}
|
|
31186
|
-
return null;
|
|
31187
|
-
}
|
|
31188
|
-
function buildToolFingerprints(messages) {
|
|
31189
|
-
const fingerprints = new Map;
|
|
31190
|
-
for (const message of messages) {
|
|
31191
|
-
if (message.info.role !== "assistant")
|
|
31192
|
-
continue;
|
|
31193
|
-
const ownerMsgId = typeof message.info.id === "string" ? message.info.id : null;
|
|
31194
|
-
if (!ownerMsgId)
|
|
31195
|
-
continue;
|
|
31196
|
-
for (const part of message.parts) {
|
|
31197
|
-
const record = part;
|
|
31198
|
-
const info = extractToolInfo(record);
|
|
31199
|
-
if (!info)
|
|
31200
|
-
continue;
|
|
31201
|
-
const callId = extractCallId(record);
|
|
31202
|
-
if (!callId)
|
|
31203
|
-
continue;
|
|
31204
|
-
try {
|
|
31205
|
-
const fingerprint = `${ownerMsgId}:${info.toolName}:${JSON.stringify(info.args)}`;
|
|
31206
|
-
const compositeKey = `${ownerMsgId}\x00${callId}`;
|
|
31207
|
-
fingerprints.set(compositeKey, fingerprint);
|
|
31208
|
-
} catch {}
|
|
31209
|
-
}
|
|
31210
|
-
}
|
|
31211
|
-
return fingerprints;
|
|
31212
|
-
}
|
|
31213
|
-
function extractCallId(part) {
|
|
31214
|
-
if (part.type === "tool" && typeof part.callID === "string")
|
|
31215
|
-
return part.callID;
|
|
31216
|
-
if (part.type === "tool-invocation" && typeof part.callID === "string")
|
|
31217
|
-
return part.callID;
|
|
31218
|
-
if (part.type === "tool_use" && typeof part.id === "string")
|
|
31219
|
-
return part.id;
|
|
31220
|
-
return null;
|
|
31221
|
-
}
|
|
31222
|
-
|
|
31223
|
-
// src/hooks/magic-context/note-visibility.ts
|
|
31224
|
-
var NOTE_TOOL_NAMES = new Set(["ctx_note"]);
|
|
31225
|
-
var READ_ACTION = "read";
|
|
31226
|
-
function hasVisibleNoteReadCall(messages) {
|
|
31227
|
-
for (let i = messages.length - 1;i >= 0; i -= 1) {
|
|
31228
|
-
const parts = messages[i]?.parts;
|
|
31229
|
-
if (!Array.isArray(parts))
|
|
31230
|
-
continue;
|
|
31231
|
-
for (const part of parts) {
|
|
31232
|
-
if (isSentinel(part))
|
|
31233
|
-
continue;
|
|
31234
|
-
if (isVisibleNoteReadPart(part))
|
|
31235
|
-
return true;
|
|
31236
|
-
}
|
|
31237
|
-
}
|
|
31238
|
-
return false;
|
|
31239
|
-
}
|
|
31240
|
-
function isVisibleNoteReadPart(part) {
|
|
31241
|
-
if (!isRecord(part))
|
|
31242
|
-
return false;
|
|
31243
|
-
if (part.type === "tool" && typeof part.tool === "string" && NOTE_TOOL_NAMES.has(part.tool)) {
|
|
31244
|
-
const state = part.state;
|
|
31245
|
-
if (isRecord(state) && isRecord(state.input)) {
|
|
31246
|
-
return state.input.action === READ_ACTION;
|
|
31247
|
-
}
|
|
31248
|
-
return false;
|
|
31249
|
-
}
|
|
31250
|
-
if (part.type === "tool_use" && typeof part.name === "string" && NOTE_TOOL_NAMES.has(part.name)) {
|
|
31251
|
-
if (isRecord(part.input)) {
|
|
31252
|
-
return part.input.action === READ_ACTION;
|
|
31253
|
-
}
|
|
31254
|
-
return false;
|
|
31255
|
-
}
|
|
31256
|
-
if (part.type === "tool-invocation" && typeof part.toolName === "string" && NOTE_TOOL_NAMES.has(part.toolName)) {
|
|
31257
|
-
const argsCandidate = part.args ?? part.input;
|
|
31258
|
-
if (isRecord(argsCandidate)) {
|
|
31259
|
-
return argsCandidate.action === READ_ACTION;
|
|
31260
|
-
}
|
|
31261
|
-
return false;
|
|
31262
|
-
}
|
|
31263
|
-
return false;
|
|
31264
|
-
}
|
|
31265
|
-
|
|
31266
|
-
// src/hooks/magic-context/strip-content.ts
|
|
31267
|
-
var DROPPED_PLACEHOLDER_PATTERN = /^\[dropped §\d+§\]$/;
|
|
31268
|
-
var TAG_PREFIX_PATTERN = /^§\d+§\s*/;
|
|
31269
|
-
var SYSTEM_INJECTION_PATTERNS = [
|
|
31270
|
-
/^<!-- OMO_INTERNAL_INITIATOR -->$/,
|
|
31271
|
-
/^<system-reminder>[\s\S]*<\/system-reminder>$/,
|
|
31272
|
-
/^\[SYSTEM DIRECTIVE:/,
|
|
31273
|
-
/^\[Category\+Skill Reminder\]/,
|
|
31274
|
-
/^\[EDIT ERROR - IMMEDIATE ACTION REQUIRED\]/,
|
|
31275
|
-
/^\[task CALL FAILED/,
|
|
31276
|
-
/^\[EMERGENCY CONTEXT WINDOW WARNING\]/
|
|
31277
|
-
];
|
|
31278
|
-
function isSystemInjectedText(text) {
|
|
31279
|
-
const stripped = text.trim().replace(TAG_PREFIX_PATTERN, "").trim();
|
|
31280
|
-
if (stripped.length === 0)
|
|
31281
|
-
return false;
|
|
31282
|
-
return SYSTEM_INJECTION_PATTERNS.some((pattern) => pattern.test(stripped));
|
|
31283
|
-
}
|
|
31284
|
-
function stripSystemInjectedMessages(messages, protectedTailStart, providerID) {
|
|
31285
|
-
let stripped = 0;
|
|
31286
|
-
const sentineledIds = [];
|
|
31287
|
-
for (let i = 0;i < messages.length; i++) {
|
|
31288
|
-
if (i >= protectedTailStart)
|
|
31289
|
-
continue;
|
|
31290
|
-
const msg = messages[i];
|
|
31291
|
-
if (msg.parts.length === 0)
|
|
31292
|
-
continue;
|
|
31293
|
-
if (msg.info.role === "user")
|
|
31294
|
-
continue;
|
|
31295
|
-
if (msg.parts.length === 1 && isSentinel(msg.parts[0]))
|
|
31296
|
-
continue;
|
|
31297
|
-
let hasContentPart = false;
|
|
31298
|
-
let allContentIsSystemInjection = true;
|
|
31299
|
-
for (const part of msg.parts) {
|
|
31300
|
-
if (!isRecord(part))
|
|
31301
|
-
continue;
|
|
31302
|
-
const partType = part.type;
|
|
31303
|
-
if (METADATA_PART_TYPES.has(partType))
|
|
31304
|
-
continue;
|
|
31305
|
-
if (part.ignored === true)
|
|
31306
|
-
continue;
|
|
31307
|
-
if (partType === "tool") {
|
|
31308
|
-
allContentIsSystemInjection = false;
|
|
31309
|
-
break;
|
|
31310
|
-
}
|
|
31311
|
-
if (partType === "text" && typeof part.text === "string") {
|
|
31312
|
-
hasContentPart = true;
|
|
31313
|
-
if (!isSystemInjectedText(part.text)) {
|
|
31314
|
-
allContentIsSystemInjection = false;
|
|
31315
|
-
break;
|
|
31316
|
-
}
|
|
31317
|
-
continue;
|
|
31318
|
-
}
|
|
31319
|
-
allContentIsSystemInjection = false;
|
|
31320
|
-
break;
|
|
31321
|
-
}
|
|
31322
|
-
if (hasContentPart && allContentIsSystemInjection) {
|
|
31323
|
-
msg.parts.length = 0;
|
|
31324
|
-
msg.parts.push(makeWholeMessageSentinel(providerID));
|
|
31325
|
-
stripped++;
|
|
31326
|
-
if (typeof msg.info.id === "string")
|
|
31327
|
-
sentineledIds.push(msg.info.id);
|
|
31328
|
-
}
|
|
31329
|
-
}
|
|
31330
|
-
return { stripped, sentineledIds };
|
|
31331
|
-
}
|
|
31332
|
-
var METADATA_PART_TYPES = new Set([
|
|
31333
|
-
"step-start",
|
|
31334
|
-
"step-finish",
|
|
31335
|
-
"snapshot",
|
|
31336
|
-
"patch",
|
|
31337
|
-
"agent",
|
|
31338
|
-
"retry",
|
|
31339
|
-
"subtask",
|
|
31340
|
-
"compaction"
|
|
31341
|
-
]);
|
|
31342
|
-
function stripDroppedPlaceholderMessages(messages, providerID) {
|
|
31343
|
-
let stripped = 0;
|
|
31344
|
-
const sentineledIds = [];
|
|
31345
|
-
for (let i = 0;i < messages.length; i++) {
|
|
31346
|
-
const msg = messages[i];
|
|
31347
|
-
if (msg.parts.length === 0)
|
|
31348
|
-
continue;
|
|
31349
|
-
if (msg.info.role === "user")
|
|
31350
|
-
continue;
|
|
31351
|
-
if (msg.parts.length === 1 && isSentinel(msg.parts[0]))
|
|
31352
|
-
continue;
|
|
31353
|
-
let hasContentPart = false;
|
|
31354
|
-
let hasNonDroppedContent = false;
|
|
31355
|
-
for (const part of msg.parts) {
|
|
31356
|
-
if (!isRecord(part))
|
|
31357
|
-
continue;
|
|
31358
|
-
const partType = part.type;
|
|
31359
|
-
if (METADATA_PART_TYPES.has(partType))
|
|
31360
|
-
continue;
|
|
31361
|
-
if (partType === "tool") {
|
|
31362
|
-
hasNonDroppedContent = true;
|
|
31363
|
-
break;
|
|
31364
|
-
}
|
|
31365
|
-
if (partType === "text" && typeof part.text === "string") {
|
|
31366
|
-
hasContentPart = true;
|
|
31367
|
-
const trimmed = part.text.trim();
|
|
31368
|
-
if (trimmed.length === 0)
|
|
31369
|
-
continue;
|
|
31370
|
-
if (!trimmed.includes("[dropped §")) {
|
|
31371
|
-
hasNonDroppedContent = true;
|
|
31372
|
-
break;
|
|
31373
|
-
}
|
|
31374
|
-
const allSegmentsDropped = trimmed.split(/(?=\[dropped §)/).filter((s) => s.trim().length > 0).every((segment) => DROPPED_PLACEHOLDER_PATTERN.test(segment.trim()));
|
|
31375
|
-
if (!allSegmentsDropped) {
|
|
31376
|
-
hasNonDroppedContent = true;
|
|
31377
|
-
break;
|
|
31378
|
-
}
|
|
31379
|
-
continue;
|
|
31380
|
-
}
|
|
31381
|
-
if (partType === "reasoning" && typeof part.text === "string") {
|
|
31382
|
-
hasContentPart = true;
|
|
31383
|
-
const trimmed = part.text.trim();
|
|
31384
|
-
if (trimmed.length === 0)
|
|
31385
|
-
continue;
|
|
31386
|
-
if (!trimmed.includes("[dropped §")) {
|
|
31387
|
-
hasNonDroppedContent = true;
|
|
31388
|
-
break;
|
|
31389
|
-
}
|
|
31390
|
-
const allSegmentsDropped = trimmed.split(/(?=\[dropped §)/).filter((s) => s.trim().length > 0).every((segment) => DROPPED_PLACEHOLDER_PATTERN.test(segment.trim()));
|
|
31391
|
-
if (!allSegmentsDropped) {
|
|
31392
|
-
hasNonDroppedContent = true;
|
|
31393
|
-
break;
|
|
31394
|
-
}
|
|
31395
|
-
continue;
|
|
31396
|
-
}
|
|
31397
|
-
hasNonDroppedContent = true;
|
|
31398
|
-
break;
|
|
31399
|
-
}
|
|
31400
|
-
if (hasContentPart && !hasNonDroppedContent) {
|
|
31401
|
-
msg.parts.length = 0;
|
|
31402
|
-
msg.parts.push(makeWholeMessageSentinel(providerID));
|
|
31403
|
-
stripped++;
|
|
31404
|
-
if (typeof msg.info.id === "string")
|
|
31405
|
-
sentineledIds.push(msg.info.id);
|
|
31406
|
-
}
|
|
31407
|
-
}
|
|
31408
|
-
return { stripped, sentineledIds };
|
|
31409
|
-
}
|
|
31410
|
-
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark) {
|
|
31411
|
-
if (persistedWatermark <= 0)
|
|
31412
|
-
return 0;
|
|
31413
|
-
let cleared = 0;
|
|
31414
|
-
for (const message of messages) {
|
|
31415
|
-
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31416
|
-
if (msgTag === 0 || msgTag > persistedWatermark)
|
|
31417
|
-
continue;
|
|
31418
|
-
const parts = reasoningByMessage.get(message);
|
|
31419
|
-
if (!parts)
|
|
31420
|
-
continue;
|
|
31421
|
-
for (const tp of parts) {
|
|
31422
|
-
if (tp.thinking !== undefined && tp.thinking !== "[cleared]") {
|
|
31423
|
-
tp.thinking = "[cleared]";
|
|
31424
|
-
cleared++;
|
|
31425
|
-
}
|
|
31426
|
-
if (tp.text !== undefined && tp.text !== "[cleared]") {
|
|
31427
|
-
tp.text = "[cleared]";
|
|
31428
|
-
cleared++;
|
|
31429
|
-
}
|
|
31430
|
-
}
|
|
31431
|
-
}
|
|
31432
|
-
return cleared;
|
|
31433
|
-
}
|
|
31434
|
-
function replayStrippedInlineThinking(messages, messageTagNumbers, persistedWatermark) {
|
|
31435
|
-
if (persistedWatermark <= 0)
|
|
31436
|
-
return 0;
|
|
31437
|
-
let stripped = 0;
|
|
31438
|
-
for (const message of messages) {
|
|
31439
|
-
if (message.info.role !== "assistant")
|
|
31440
|
-
continue;
|
|
31441
|
-
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31442
|
-
if (msgTag === 0 || msgTag > persistedWatermark)
|
|
31443
|
-
continue;
|
|
31444
|
-
for (const part of message.parts) {
|
|
31445
|
-
if (!isRecord(part) || part.type !== "text" || typeof part.text !== "string")
|
|
31446
|
-
continue;
|
|
31447
|
-
if (!part.text.includes("<think"))
|
|
31448
|
-
continue;
|
|
31449
|
-
const cleaned = part.text.replace(INLINE_THINKING_PATTERN, "");
|
|
31450
|
-
if (cleaned !== part.text) {
|
|
31451
|
-
part.text = cleaned;
|
|
31452
|
-
stripped++;
|
|
31453
|
-
}
|
|
31454
|
-
}
|
|
31455
|
-
}
|
|
31456
|
-
return stripped;
|
|
31457
|
-
}
|
|
31458
|
-
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge) {
|
|
31459
|
-
const maxTag = findMaxTag(messageTagNumbers);
|
|
31460
|
-
if (maxTag === 0)
|
|
31461
|
-
return 0;
|
|
31462
|
-
const ageCutoff = maxTag - clearReasoningAge;
|
|
31463
|
-
let cleared = 0;
|
|
31464
|
-
for (const message of messages) {
|
|
31465
|
-
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31466
|
-
if (msgTag === 0 || msgTag > ageCutoff)
|
|
31467
|
-
continue;
|
|
31468
|
-
const parts = reasoningByMessage.get(message);
|
|
31469
|
-
if (!parts)
|
|
31470
|
-
continue;
|
|
31471
|
-
for (const tp of parts) {
|
|
31472
|
-
if (tp.thinking !== undefined && tp.thinking !== "[cleared]") {
|
|
31473
|
-
tp.thinking = "[cleared]";
|
|
31474
|
-
cleared++;
|
|
31475
|
-
}
|
|
31476
|
-
if (tp.text !== undefined && tp.text !== "[cleared]") {
|
|
31477
|
-
tp.text = "[cleared]";
|
|
31478
|
-
cleared++;
|
|
31479
|
-
}
|
|
31480
|
-
}
|
|
31481
|
-
}
|
|
31482
|
-
return cleared;
|
|
31483
|
-
}
|
|
31484
|
-
function findMaxTag(messageTagNumbers) {
|
|
31485
|
-
let max = 0;
|
|
31486
|
-
for (const tag of messageTagNumbers.values()) {
|
|
31487
|
-
if (tag > max)
|
|
31488
|
-
max = tag;
|
|
31489
|
-
}
|
|
31490
|
-
return max;
|
|
31491
|
-
}
|
|
31492
|
-
var CLEARED_REASONING_TYPES = new Set(["thinking", "reasoning"]);
|
|
31493
|
-
function stripClearedReasoning(messages) {
|
|
31494
|
-
let stripped = 0;
|
|
31495
|
-
for (const message of messages) {
|
|
31496
|
-
if (message.info.role !== "assistant")
|
|
31497
|
-
continue;
|
|
31498
|
-
for (let i = 0;i < message.parts.length; i++) {
|
|
31499
|
-
const part = message.parts[i];
|
|
31500
|
-
if (!isRecord(part))
|
|
31501
|
-
continue;
|
|
31502
|
-
const partType = part.type;
|
|
31503
|
-
if (!CLEARED_REASONING_TYPES.has(partType))
|
|
31504
|
-
continue;
|
|
31505
|
-
if (!("thinking" in part) && !("text" in part))
|
|
31506
|
-
continue;
|
|
31507
|
-
const thinking = "thinking" in part ? part.thinking : undefined;
|
|
31508
|
-
const text = "text" in part ? part.text : undefined;
|
|
31509
|
-
const isCleared = (thinking === undefined || thinking === "[cleared]") && (text === undefined || text === "[cleared]");
|
|
31510
|
-
if (!isCleared)
|
|
31511
|
-
continue;
|
|
31512
|
-
message.parts[i] = makeSentinel(part);
|
|
31513
|
-
stripped++;
|
|
31514
|
-
}
|
|
31515
|
-
}
|
|
31516
|
-
return stripped;
|
|
31517
|
-
}
|
|
31518
|
-
var INLINE_THINKING_PATTERN = /<(?:thinking|think)>[\s\S]*?<\/(?:thinking|think)>\s*/g;
|
|
31519
|
-
function stripInlineThinking(messages, messageTagNumbers, clearReasoningAge) {
|
|
31520
|
-
const maxTag = findMaxTag(messageTagNumbers);
|
|
31521
|
-
if (maxTag === 0)
|
|
31522
|
-
return 0;
|
|
31523
|
-
const ageCutoff = maxTag - clearReasoningAge;
|
|
31524
|
-
let stripped = 0;
|
|
31525
|
-
for (const message of messages) {
|
|
31526
|
-
if (message.info.role !== "assistant")
|
|
31527
|
-
continue;
|
|
31528
|
-
const msgTag = messageTagNumbers.get(message) ?? 0;
|
|
31529
|
-
if (msgTag === 0 || msgTag > ageCutoff)
|
|
31530
|
-
continue;
|
|
31531
|
-
for (const part of message.parts) {
|
|
31532
|
-
if (!isRecord(part) || part.type !== "text" || typeof part.text !== "string")
|
|
31533
|
-
continue;
|
|
31534
|
-
const cleaned = part.text.replace(INLINE_THINKING_PATTERN, "");
|
|
31535
|
-
if (cleaned !== part.text) {
|
|
31536
|
-
part.text = cleaned;
|
|
31537
|
-
stripped++;
|
|
31538
|
-
}
|
|
31539
|
-
}
|
|
31540
|
-
}
|
|
31541
|
-
return stripped;
|
|
31542
|
-
}
|
|
31543
|
-
var REASONING_IGNORED_PART_TYPES = new Set([
|
|
31544
|
-
"step-start",
|
|
31545
|
-
"step-finish",
|
|
31546
|
-
"snapshot",
|
|
31547
|
-
"patch",
|
|
31548
|
-
"agent",
|
|
31549
|
-
"retry",
|
|
31550
|
-
"subtask",
|
|
31551
|
-
"compaction"
|
|
31552
|
-
]);
|
|
31553
|
-
var REASONING_PART_TYPES = new Set(["reasoning", "thinking", "redacted_thinking"]);
|
|
31554
|
-
function hasReasoningReplayContent(message) {
|
|
31555
|
-
return message.parts.some((part) => {
|
|
31556
|
-
if (!isRecord(part) || part.ignored === true)
|
|
31557
|
-
return false;
|
|
31558
|
-
const type = typeof part.type === "string" ? part.type : "";
|
|
31559
|
-
if (REASONING_IGNORED_PART_TYPES.has(type))
|
|
31560
|
-
return false;
|
|
31561
|
-
return type !== "text" || typeof part.text !== "string" || part.text.trim().length > 0;
|
|
31562
|
-
});
|
|
31563
|
-
}
|
|
31564
|
-
function findLatestAssistantReasoningMutationExemptMessage(messages) {
|
|
31565
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
31566
|
-
const message = messages[index];
|
|
31567
|
-
if (message.info.role === "assistant" && hasReasoningReplayContent(message))
|
|
31568
|
-
return message;
|
|
31569
|
-
}
|
|
31570
|
-
return;
|
|
31571
|
-
}
|
|
31572
|
-
function planMergedAssistantReasoningStrip(messages, mutationExemptMessage) {
|
|
31573
|
-
const plan = [];
|
|
31574
|
-
let prevRole;
|
|
31575
|
-
let keptReasoningInRun = false;
|
|
31576
|
-
for (const message of messages) {
|
|
31577
|
-
const role = message.info.role;
|
|
31578
|
-
if (role !== "assistant") {
|
|
31579
|
-
prevRole = role;
|
|
31580
|
-
keptReasoningInRun = false;
|
|
31581
|
-
continue;
|
|
31582
|
-
}
|
|
31583
|
-
const firstInRun = prevRole !== "assistant";
|
|
31584
|
-
if (firstInRun)
|
|
31585
|
-
keptReasoningInRun = false;
|
|
31586
|
-
if (message === mutationExemptMessage) {
|
|
31587
|
-
prevRole = role;
|
|
31588
|
-
continue;
|
|
31589
|
-
}
|
|
31590
|
-
let keepIndex = -1;
|
|
31591
|
-
if (firstInRun && !keptReasoningInRun) {
|
|
31592
|
-
for (let i = 0;i < message.parts.length; i++) {
|
|
31593
|
-
const part = message.parts[i];
|
|
31594
|
-
if (!isRecord(part))
|
|
31595
|
-
continue;
|
|
31596
|
-
const partType = part.type;
|
|
31597
|
-
if (REASONING_IGNORED_PART_TYPES.has(partType))
|
|
31598
|
-
continue;
|
|
31599
|
-
if (part.ignored === true)
|
|
31600
|
-
continue;
|
|
31601
|
-
if (isSentinel(part))
|
|
31602
|
-
continue;
|
|
31603
|
-
if (partType === "text" && typeof part.text === "string" && part.text.trim() === "") {
|
|
31604
|
-
continue;
|
|
31605
|
-
}
|
|
31606
|
-
if (REASONING_PART_TYPES.has(partType)) {
|
|
31607
|
-
keepIndex = i;
|
|
31608
|
-
}
|
|
31609
|
-
break;
|
|
31610
|
-
}
|
|
31611
|
-
}
|
|
31612
|
-
const stripIndices = [];
|
|
31613
|
-
for (let i = 0;i < message.parts.length; i++) {
|
|
31614
|
-
const part = message.parts[i];
|
|
31615
|
-
if (!isRecord(part))
|
|
31616
|
-
continue;
|
|
31617
|
-
if (!REASONING_PART_TYPES.has(part.type))
|
|
31618
|
-
continue;
|
|
31619
|
-
if (part.cache_control !== undefined)
|
|
31620
|
-
continue;
|
|
31621
|
-
if (i === keepIndex) {
|
|
31622
|
-
keptReasoningInRun = true;
|
|
32072
|
+
const tag = tagsByCompositeKey.get(compositeKey);
|
|
32073
|
+
if (!tag || tag.tagNumber > protectedCutoff)
|
|
31623
32074
|
continue;
|
|
31624
|
-
|
|
31625
|
-
|
|
32075
|
+
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
32076
|
+
group.push(tag);
|
|
32077
|
+
fingerprintGroups.set(fingerprint, group);
|
|
31626
32078
|
}
|
|
31627
|
-
|
|
31628
|
-
|
|
31629
|
-
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
31636
|
-
|
|
31637
|
-
|
|
31638
|
-
|
|
31639
|
-
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
const countText = decision.slice("keep:".length);
|
|
31647
|
-
if (!/^[1-9]\d*$/.test(countText))
|
|
31648
|
-
return;
|
|
31649
|
-
const count = Number(countText);
|
|
31650
|
-
return Number.isSafeInteger(count) && count > 0 && count <= MAX_FROZEN_TRAILING_BLANKS ? count : undefined;
|
|
31651
|
-
}
|
|
31652
|
-
function trailingBlankDecisionForMessage(message) {
|
|
31653
|
-
const id = message.info.id;
|
|
31654
|
-
if (message.info.role !== "assistant" || typeof id !== "string" || id.length === 0) {
|
|
31655
|
-
return;
|
|
32079
|
+
db.transaction(() => {
|
|
32080
|
+
for (const [, group] of fingerprintGroups) {
|
|
32081
|
+
if (group.length <= 1)
|
|
32082
|
+
continue;
|
|
32083
|
+
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
32084
|
+
for (let i = 0;i < group.length - 1; i++) {
|
|
32085
|
+
const tag = group[i];
|
|
32086
|
+
const target = targets.get(tag.tagNumber);
|
|
32087
|
+
const result = target?.drop?.() ?? "absent";
|
|
32088
|
+
if (result === "incomplete")
|
|
32089
|
+
continue;
|
|
32090
|
+
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
32091
|
+
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
32092
|
+
if (result === "removed" || result === "truncated") {
|
|
32093
|
+
deduplicatedTools++;
|
|
32094
|
+
}
|
|
32095
|
+
}
|
|
32096
|
+
}
|
|
32097
|
+
})();
|
|
31656
32098
|
}
|
|
31657
|
-
|
|
31658
|
-
|
|
31659
|
-
trailingCount += 1;
|
|
32099
|
+
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
|
|
32100
|
+
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
31660
32101
|
}
|
|
31661
|
-
|
|
31662
|
-
|
|
32102
|
+
let compressedTextTags = 0;
|
|
32103
|
+
let mutatedTextTags = 0;
|
|
32104
|
+
if (config.routine !== false && config.caveman?.enabled) {
|
|
32105
|
+
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
|
|
32106
|
+
enabled: true,
|
|
32107
|
+
minChars: config.caveman.minChars,
|
|
32108
|
+
protectedTags: config.protectedTags
|
|
32109
|
+
});
|
|
32110
|
+
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
32111
|
+
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
31663
32112
|
}
|
|
31664
|
-
|
|
31665
|
-
|
|
32113
|
+
return {
|
|
32114
|
+
droppedTools,
|
|
32115
|
+
deduplicatedTools,
|
|
32116
|
+
droppedInjections,
|
|
32117
|
+
emergencyDroppedTools,
|
|
32118
|
+
emergencyReclaimedTokens,
|
|
32119
|
+
compressedTextTags,
|
|
32120
|
+
mutatedTextTags
|
|
32121
|
+
};
|
|
31666
32122
|
}
|
|
31667
|
-
function
|
|
31668
|
-
|
|
31669
|
-
|
|
31670
|
-
|
|
31671
|
-
if (observed)
|
|
31672
|
-
decisions.set(...observed);
|
|
32123
|
+
function extractToolInfo(part) {
|
|
32124
|
+
if (part.type === "tool" && typeof part.tool === "string" && DEDUP_SAFE_TOOLS.has(part.tool)) {
|
|
32125
|
+
const state = typeof part.state === "object" && part.state !== null ? part.state : {};
|
|
32126
|
+
return { toolName: part.tool, args: state.input ?? {} };
|
|
31673
32127
|
}
|
|
31674
|
-
|
|
31675
|
-
}
|
|
31676
|
-
function findTrailingBlankDecisionCandidates(messages, frozenDecisions, options) {
|
|
31677
|
-
const observedDecisions = options?.sourceDecisions ?? snapshotTrailingBlankSourceDecisions(messages);
|
|
31678
|
-
const visibleIds = new Set(messages.flatMap((message) => typeof message.info.id === "string" ? [message.info.id] : []));
|
|
31679
|
-
const decisions = [];
|
|
31680
|
-
for (const [id, decision] of observedDecisions) {
|
|
31681
|
-
if (!visibleIds.has(id))
|
|
31682
|
-
continue;
|
|
31683
|
-
const frozen = frozenDecisions.get(id);
|
|
31684
|
-
if (frozen !== undefined && (id !== options?.refreshMessageId || frozen === decision)) {
|
|
31685
|
-
continue;
|
|
31686
|
-
}
|
|
31687
|
-
decisions.push([id, decision]);
|
|
32128
|
+
if (part.type === "tool-invocation" && typeof part.toolName === "string" && DEDUP_SAFE_TOOLS.has(part.toolName)) {
|
|
32129
|
+
return { toolName: part.toolName, args: part.args ?? {} };
|
|
31688
32130
|
}
|
|
31689
|
-
|
|
32131
|
+
if (part.type === "tool_use" && typeof part.name === "string" && DEDUP_SAFE_TOOLS.has(part.name)) {
|
|
32132
|
+
return { toolName: part.name, args: part.input ?? {} };
|
|
32133
|
+
}
|
|
32134
|
+
return null;
|
|
31690
32135
|
}
|
|
31691
|
-
function
|
|
31692
|
-
|
|
31693
|
-
for (
|
|
31694
|
-
|
|
31695
|
-
const id = message.info.id;
|
|
31696
|
-
if (message.info.role !== "assistant" || typeof id !== "string")
|
|
32136
|
+
function buildToolFingerprints(messages) {
|
|
32137
|
+
const fingerprints = new Map;
|
|
32138
|
+
for (const message of messages) {
|
|
32139
|
+
if (message.info.role !== "assistant")
|
|
31697
32140
|
continue;
|
|
31698
|
-
const
|
|
31699
|
-
if (!
|
|
32141
|
+
const ownerMsgId = typeof message.info.id === "string" ? message.info.id : null;
|
|
32142
|
+
if (!ownerMsgId)
|
|
31700
32143
|
continue;
|
|
31701
|
-
|
|
31702
|
-
|
|
31703
|
-
|
|
31704
|
-
|
|
31705
|
-
const replaceParts = (start, deleteCount, insertBlankCount) => {
|
|
31706
|
-
message = { ...message, parts: [...message.parts] };
|
|
31707
|
-
messages[messageIndex] = message;
|
|
31708
|
-
message.parts.splice(start, deleteCount, ...Array.from({ length: insertBlankCount }, () => ({ ...CANONICAL_BLANK_PART })));
|
|
31709
|
-
};
|
|
31710
|
-
if (lastMeaningfulIndex < 0) {
|
|
31711
|
-
if (message.parts.length === 0)
|
|
32144
|
+
for (const part of message.parts) {
|
|
32145
|
+
const record = part;
|
|
32146
|
+
const info = extractToolInfo(record);
|
|
32147
|
+
if (!info)
|
|
31712
32148
|
continue;
|
|
31713
|
-
|
|
31714
|
-
|
|
31715
|
-
replaceParts(0, message.parts.length, 1);
|
|
31716
|
-
}
|
|
31717
|
-
continue;
|
|
31718
|
-
}
|
|
31719
|
-
const trailingCount = message.parts.length - lastMeaningfulIndex - 1;
|
|
31720
|
-
const keepCount = trailingBlankKeepCount(decision);
|
|
31721
|
-
if (keepCount !== undefined) {
|
|
31722
|
-
if (trailingCount === 0)
|
|
32149
|
+
const callId = extractCallId(record);
|
|
32150
|
+
if (!callId)
|
|
31723
32151
|
continue;
|
|
31724
|
-
|
|
31725
|
-
|
|
31726
|
-
|
|
31727
|
-
|
|
31728
|
-
|
|
31729
|
-
}
|
|
31730
|
-
continue;
|
|
31731
|
-
}
|
|
31732
|
-
if (id === newestAssistantId || trailingCount === 0)
|
|
31733
|
-
continue;
|
|
31734
|
-
const lastMeaningfulPart = message.parts[lastMeaningfulIndex];
|
|
31735
|
-
if (isRecord(lastMeaningfulPart) && REASONING_PART_TYPES.has(lastMeaningfulPart.type)) {
|
|
31736
|
-
const blankIndex = lastMeaningfulIndex + 1;
|
|
31737
|
-
if (trailingCount !== 1 || !isCanonicalBlankPart(message.parts[blankIndex])) {
|
|
31738
|
-
mutations += Math.max(1, trailingCount);
|
|
31739
|
-
replaceParts(blankIndex, trailingCount, 1);
|
|
31740
|
-
}
|
|
31741
|
-
continue;
|
|
32152
|
+
try {
|
|
32153
|
+
const fingerprint = `${ownerMsgId}:${info.toolName}:${JSON.stringify(info.args)}`;
|
|
32154
|
+
const compositeKey = `${ownerMsgId}\x00${callId}`;
|
|
32155
|
+
fingerprints.set(compositeKey, fingerprint);
|
|
32156
|
+
} catch {}
|
|
31742
32157
|
}
|
|
31743
|
-
mutations += trailingCount;
|
|
31744
|
-
replaceParts(lastMeaningfulIndex + 1, trailingCount, 0);
|
|
31745
32158
|
}
|
|
31746
|
-
return
|
|
32159
|
+
return fingerprints;
|
|
31747
32160
|
}
|
|
31748
|
-
function
|
|
31749
|
-
if (
|
|
31750
|
-
return
|
|
31751
|
-
|
|
31752
|
-
|
|
31753
|
-
|
|
31754
|
-
|
|
31755
|
-
|
|
31756
|
-
}
|
|
31757
|
-
return [...ids];
|
|
32161
|
+
function extractCallId(part) {
|
|
32162
|
+
if (part.type === "tool" && typeof part.callID === "string")
|
|
32163
|
+
return part.callID;
|
|
32164
|
+
if (part.type === "tool-invocation" && typeof part.callID === "string")
|
|
32165
|
+
return part.callID;
|
|
32166
|
+
if (part.type === "tool_use" && typeof part.id === "string")
|
|
32167
|
+
return part.id;
|
|
32168
|
+
return null;
|
|
31758
32169
|
}
|
|
31759
|
-
|
|
31760
|
-
|
|
31761
|
-
|
|
31762
|
-
|
|
31763
|
-
|
|
31764
|
-
|
|
31765
|
-
|
|
31766
|
-
|
|
32170
|
+
|
|
32171
|
+
// src/hooks/magic-context/note-visibility.ts
|
|
32172
|
+
var NOTE_TOOL_NAMES = new Set(["ctx_note"]);
|
|
32173
|
+
var READ_ACTION = "read";
|
|
32174
|
+
function hasVisibleNoteReadCall(messages) {
|
|
32175
|
+
for (let i = messages.length - 1;i >= 0; i -= 1) {
|
|
32176
|
+
const parts = messages[i]?.parts;
|
|
32177
|
+
if (!Array.isArray(parts))
|
|
32178
|
+
continue;
|
|
32179
|
+
for (const part of parts) {
|
|
32180
|
+
if (isSentinel(part))
|
|
31767
32181
|
continue;
|
|
31768
|
-
|
|
31769
|
-
|
|
31770
|
-
entry.message.parts[index] = makeSentinel(entry.message.parts[index]);
|
|
31771
|
-
stripped++;
|
|
32182
|
+
if (isVisibleNoteReadPart(part))
|
|
32183
|
+
return true;
|
|
31772
32184
|
}
|
|
31773
32185
|
}
|
|
31774
|
-
return
|
|
32186
|
+
return false;
|
|
31775
32187
|
}
|
|
31776
|
-
function
|
|
31777
|
-
|
|
31778
|
-
|
|
31779
|
-
|
|
31780
|
-
|
|
31781
|
-
|
|
31782
|
-
|
|
31783
|
-
if (msg.info.role === "assistant") {
|
|
31784
|
-
hasAssistantResponse = true;
|
|
31785
|
-
continue;
|
|
31786
|
-
}
|
|
31787
|
-
if (msg.info.role !== "user") {
|
|
31788
|
-
continue;
|
|
31789
|
-
}
|
|
31790
|
-
const id = typeof msg.info.id === "string" ? msg.info.id : undefined;
|
|
31791
|
-
const inFrozen = id !== undefined && frozenIds.has(id);
|
|
31792
|
-
const maxTag = messageTagNumbers.get(msg) ?? 0;
|
|
31793
|
-
const isNewDetection = !inFrozen && detect && hasAssistantResponse && id !== undefined && maxTag <= watermark;
|
|
31794
|
-
if (!inFrozen && !isNewDetection) {
|
|
31795
|
-
continue;
|
|
32188
|
+
function isVisibleNoteReadPart(part) {
|
|
32189
|
+
if (!isRecord(part))
|
|
32190
|
+
return false;
|
|
32191
|
+
if (part.type === "tool" && typeof part.tool === "string" && NOTE_TOOL_NAMES.has(part.tool)) {
|
|
32192
|
+
const state = part.state;
|
|
32193
|
+
if (isRecord(state) && isRecord(state.input)) {
|
|
32194
|
+
return state.input.action === READ_ACTION;
|
|
31796
32195
|
}
|
|
31797
|
-
|
|
31798
|
-
|
|
31799
|
-
|
|
31800
|
-
|
|
31801
|
-
|
|
31802
|
-
}
|
|
31803
|
-
if (typeof part.mime !== "string" || !part.mime.startsWith("image/")) {
|
|
31804
|
-
continue;
|
|
31805
|
-
}
|
|
31806
|
-
if (typeof part.url === "string" && part.url.startsWith("data:") && part.url.length > 200) {
|
|
31807
|
-
msg.parts[j] = makeSentinel(part);
|
|
31808
|
-
stripped++;
|
|
31809
|
-
touchedThisMsg = true;
|
|
31810
|
-
}
|
|
32196
|
+
return false;
|
|
32197
|
+
}
|
|
32198
|
+
if (part.type === "tool_use" && typeof part.name === "string" && NOTE_TOOL_NAMES.has(part.name)) {
|
|
32199
|
+
if (isRecord(part.input)) {
|
|
32200
|
+
return part.input.action === READ_ACTION;
|
|
31811
32201
|
}
|
|
31812
|
-
|
|
31813
|
-
|
|
32202
|
+
return false;
|
|
32203
|
+
}
|
|
32204
|
+
if (part.type === "tool-invocation" && typeof part.toolName === "string" && NOTE_TOOL_NAMES.has(part.toolName)) {
|
|
32205
|
+
const argsCandidate = part.args ?? part.input;
|
|
32206
|
+
if (isRecord(argsCandidate)) {
|
|
32207
|
+
return argsCandidate.action === READ_ACTION;
|
|
31814
32208
|
}
|
|
32209
|
+
return false;
|
|
31815
32210
|
}
|
|
31816
|
-
return
|
|
32211
|
+
return false;
|
|
31817
32212
|
}
|
|
31818
32213
|
|
|
31819
32214
|
// src/hooks/magic-context/supersession-reclaim.ts
|
|
@@ -32137,14 +32532,15 @@ function createExistingTagResolver(sessionId, tagger, db) {
|
|
|
32137
32532
|
return cachedScopedAssignments;
|
|
32138
32533
|
}
|
|
32139
32534
|
return {
|
|
32140
|
-
resolve(messageId2, type, currentContentId, ordinal) {
|
|
32535
|
+
resolve(messageId2, type, currentContentId, ordinal, options) {
|
|
32536
|
+
const accept = options?.accept ?? (() => true);
|
|
32141
32537
|
const exactTagId = assignments.get(currentContentId);
|
|
32142
|
-
if (exactTagId !== undefined) {
|
|
32538
|
+
if (exactTagId !== undefined && accept(exactTagId)) {
|
|
32143
32539
|
usedTagNumbers.add(exactTagId);
|
|
32144
32540
|
return exactTagId;
|
|
32145
32541
|
}
|
|
32146
32542
|
const fallback = getScopedAssignments().get(messageId2)?.[type][ordinal];
|
|
32147
|
-
if (!fallback || usedTagNumbers.has(fallback.tagNumber)) {
|
|
32543
|
+
if (!fallback || usedTagNumbers.has(fallback.tagNumber) || !accept(fallback.tagNumber)) {
|
|
32148
32544
|
return;
|
|
32149
32545
|
}
|
|
32150
32546
|
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
@@ -32336,6 +32732,21 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
32336
32732
|
};
|
|
32337
32733
|
const ownerByPartKey = new Map;
|
|
32338
32734
|
const batch = new ToolMutationBatch(messages);
|
|
32735
|
+
const inertWhitespaceTagNumbers = new Set;
|
|
32736
|
+
const inertWhitespaceTagsByMessage = new Map;
|
|
32737
|
+
for (const tag of getInertWhitespaceAssistantTags(db, sessionId)) {
|
|
32738
|
+
inertWhitespaceTagNumbers.add(tag.tagNumber);
|
|
32739
|
+
tagger.bindTag(sessionId, tag.contentId, tag.tagNumber);
|
|
32740
|
+
const scoped = /^(.*):p(\d+)$/.exec(tag.contentId);
|
|
32741
|
+
if (!scoped)
|
|
32742
|
+
continue;
|
|
32743
|
+
const list = inertWhitespaceTagsByMessage.get(scoped[1]) ?? [];
|
|
32744
|
+
list.push({ partIndex: Number(scoped[2]), tagNumber: tag.tagNumber });
|
|
32745
|
+
inertWhitespaceTagsByMessage.set(scoped[1], list);
|
|
32746
|
+
}
|
|
32747
|
+
for (const list of inertWhitespaceTagsByMessage.values()) {
|
|
32748
|
+
list.sort((left, right) => left.partIndex - right.partIndex);
|
|
32749
|
+
}
|
|
32339
32750
|
const assignments = tagger.getAssignments(sessionId);
|
|
32340
32751
|
const resolver = createExistingTagResolver(sessionId, tagger, db);
|
|
32341
32752
|
const tGetSourceContents = performance.now();
|
|
@@ -32364,6 +32775,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
32364
32775
|
const messageHasTextPart = message.parts.some(isTextPart);
|
|
32365
32776
|
let textOrdinal = 0;
|
|
32366
32777
|
let fileOrdinal = 0;
|
|
32778
|
+
let whitespaceRank = 0;
|
|
32367
32779
|
for (let partIndex = 0;partIndex < message.parts.length; partIndex += 1) {
|
|
32368
32780
|
const part = message.parts[partIndex];
|
|
32369
32781
|
if (isReduceToolPart(part)) {
|
|
@@ -32419,7 +32831,47 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
32419
32831
|
const textPart = part;
|
|
32420
32832
|
const thinkingParts = messageThinkingParts;
|
|
32421
32833
|
const contentId = `${messageId2}:p${partIndex}`;
|
|
32422
|
-
|
|
32834
|
+
const whitespaceOnlyAssistant = message.info.role === "assistant" && stripTagPrefix(textPart.text).trim().length === 0;
|
|
32835
|
+
let existingTagId;
|
|
32836
|
+
if (whitespaceOnlyAssistant) {
|
|
32837
|
+
const persistedWhitespaceTag = getTagNumberByMessageId(db, sessionId, contentId);
|
|
32838
|
+
const rankedInertTag = inertWhitespaceTagsByMessage.get(messageId2)?.[whitespaceRank];
|
|
32839
|
+
const canReplayRankedTag = rankedInertTag?.partIndex === partIndex || isThinkingPart(message.parts[partIndex - 1]) || isThinkingPart(message.parts[partIndex + 1]);
|
|
32840
|
+
const inertForThisPart = canReplayRankedTag ? rankedInertTag?.tagNumber : undefined;
|
|
32841
|
+
whitespaceRank += 1;
|
|
32842
|
+
if (inertForThisPart !== undefined) {
|
|
32843
|
+
tagger.bindTag(sessionId, contentId, inertForThisPart);
|
|
32844
|
+
existingTagId = inertForThisPart;
|
|
32845
|
+
} else {
|
|
32846
|
+
existingTagId = resolver.resolve(messageId2, "message", contentId, textOrdinal, { accept: (tagNumber) => tagNumber === persistedWhitespaceTag });
|
|
32847
|
+
}
|
|
32848
|
+
if (existingTagId === undefined) {
|
|
32849
|
+
const persisted = getTagNumberByMessageId(db, sessionId, contentId);
|
|
32850
|
+
if (persisted !== null && !getSourceContents(db, sessionId, [persisted]).has(persisted)) {
|
|
32851
|
+
tagger.bindTag(sessionId, contentId, persisted);
|
|
32852
|
+
existingTagId = persisted;
|
|
32853
|
+
}
|
|
32854
|
+
}
|
|
32855
|
+
if (existingTagId === undefined) {
|
|
32856
|
+
textOrdinal += 1;
|
|
32857
|
+
continue;
|
|
32858
|
+
}
|
|
32859
|
+
const existingTag = getTagById(db, sessionId, existingTagId);
|
|
32860
|
+
if (!existingTag || existingTag.type !== "message") {
|
|
32861
|
+
tagger.unbindTag(sessionId, contentId);
|
|
32862
|
+
textOrdinal += 1;
|
|
32863
|
+
continue;
|
|
32864
|
+
}
|
|
32865
|
+
if (existingTag.status === "active") {
|
|
32866
|
+
markWhitespaceAssistantTagInert(db, sessionId, existingTagId, contentId);
|
|
32867
|
+
inertWhitespaceTagNumbers.add(existingTagId);
|
|
32868
|
+
}
|
|
32869
|
+
} else {
|
|
32870
|
+
const resolved = resolver.resolve(messageId2, "message", contentId, textOrdinal, { accept: (tagNumber) => !inertWhitespaceTagNumbers.has(tagNumber) });
|
|
32871
|
+
if (resolved === undefined && inertWhitespaceTagNumbers.has(tagger.getTag(sessionId, contentId, "message") ?? -1)) {
|
|
32872
|
+
tagger.unbindTag(sessionId, contentId);
|
|
32873
|
+
}
|
|
32874
|
+
}
|
|
32423
32875
|
const reasoningBytes = textOrdinal === 0 ? getReasoningByteSize(thinkingParts) : 0;
|
|
32424
32876
|
const reasoningTokens = textOrdinal === 0 ? getReasoningTokenCount(thinkingParts) : 0;
|
|
32425
32877
|
const _tAssignText = performance.now();
|
|
@@ -32689,11 +33141,24 @@ async function applyTodoSynthesis(args) {
|
|
|
32689
33141
|
}
|
|
32690
33142
|
return 0;
|
|
32691
33143
|
}
|
|
33144
|
+
function replayRustModeBindingMismatchStrips(args) {
|
|
33145
|
+
if (!modelAcceptsEmptyContent(args.resolvedProviderID))
|
|
33146
|
+
return;
|
|
33147
|
+
const recoveryMessageIds = new Set;
|
|
33148
|
+
for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
|
|
33149
|
+
if (!id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX))
|
|
33150
|
+
continue;
|
|
33151
|
+
const messageId2 = id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length);
|
|
33152
|
+
if (messageId2.length > 0)
|
|
33153
|
+
recoveryMessageIds.add(messageId2);
|
|
33154
|
+
}
|
|
33155
|
+
stripReasoningFromAssistantIds(args.messages, args.resolvedProviderID, recoveryMessageIds);
|
|
33156
|
+
}
|
|
32692
33157
|
function runRustModePostprocess(args) {
|
|
32693
33158
|
if (!args.fullFeatureMode || args.compactionOff)
|
|
32694
|
-
return;
|
|
33159
|
+
return { thinkingBindingRecovery: null };
|
|
32695
33160
|
if (args.messages.some((message) => !message || typeof message !== "object" || !isRecord(message.info))) {
|
|
32696
|
-
return;
|
|
33161
|
+
return { thinkingBindingRecovery: null };
|
|
32697
33162
|
}
|
|
32698
33163
|
reconcileMarkerRepresentation(args.messages, getPersistedCompactionMarkerState(args.db, args.sessionId), {
|
|
32699
33164
|
db: args.db,
|
|
@@ -32709,21 +33174,80 @@ function runRustModePostprocess(args) {
|
|
|
32709
33174
|
appendReminderToUserMessageById(args.messages, decision.messageId, decision.text);
|
|
32710
33175
|
}
|
|
32711
33176
|
}
|
|
33177
|
+
const trailingBlankDecisions = new Map;
|
|
33178
|
+
if (modelAcceptsEmptyContent(args.resolvedProviderID)) {
|
|
33179
|
+
try {
|
|
33180
|
+
for (const [id, decision] of getTrailingBlankDecisions(args.db, args.sessionId)) {
|
|
33181
|
+
trailingBlankDecisions.set(id, decision);
|
|
33182
|
+
}
|
|
33183
|
+
const candidates = findTrailingBlankDecisionCandidates(args.messages, trailingBlankDecisions, { sourceDecisions: args.trailingBlankSourceDecisions }).filter(([id]) => id === args.trailingBlankNewestAssistantId);
|
|
33184
|
+
if (candidates.length > 0) {
|
|
33185
|
+
const persisted = addTrailingBlankDecisions(args.db, args.sessionId, candidates, {
|
|
33186
|
+
overwriteMessageId: args.trailingBlankNewestAssistantId
|
|
33187
|
+
});
|
|
33188
|
+
if (persisted) {
|
|
33189
|
+
const committed = getTrailingBlankDecisions(args.db, args.sessionId);
|
|
33190
|
+
for (const [id] of candidates) {
|
|
33191
|
+
const decision = committed.get(id);
|
|
33192
|
+
if (decision)
|
|
33193
|
+
trailingBlankDecisions.set(id, decision);
|
|
33194
|
+
}
|
|
33195
|
+
} else {
|
|
33196
|
+
sessionLog(args.sessionId, "rust trailing blank decision: persistence failed; serving only frozen decisions");
|
|
33197
|
+
}
|
|
33198
|
+
}
|
|
33199
|
+
} catch (error) {
|
|
33200
|
+
sessionLog(args.sessionId, "rust trailing blank decision failed:", error);
|
|
33201
|
+
}
|
|
33202
|
+
}
|
|
33203
|
+
const absorbingStripDecisions = new Map([...trailingBlankDecisions].filter(([, decision]) => decision === "strip"));
|
|
33204
|
+
applyFrozenTrailingBlankDecisions(args.messages, absorbingStripDecisions);
|
|
32712
33205
|
const currentUserMessageId = findLastUserMessageId(args.messages);
|
|
32713
33206
|
const noteReadStillVisible = hasVisibleNoteReadCall(args.messages);
|
|
32714
33207
|
const deferredNoteText = peekNoteNudgeText(args.db, args.sessionId, currentUserMessageId, args.projectPath, noteReadStillVisible);
|
|
32715
|
-
if (
|
|
32716
|
-
|
|
32717
|
-
const instruction = `
|
|
33208
|
+
if (deferredNoteText) {
|
|
33209
|
+
const instruction = `
|
|
32718
33210
|
|
|
32719
33211
|
<instruction name="deferred_notes">${deferredNoteText}</instruction>`;
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
|
|
32723
|
-
|
|
32724
|
-
|
|
32725
|
-
|
|
33212
|
+
const anchoredMessageId = findLastUserMessageId(args.messages);
|
|
33213
|
+
const outcome = markNoteNudgeDelivered(args.db, args.sessionId, instruction, anchoredMessageId);
|
|
33214
|
+
if (anchoredMessageId && outcome.ok) {
|
|
33215
|
+
appendReminderToUserMessageById(args.messages, anchoredMessageId, instruction);
|
|
33216
|
+
} else if (anchoredMessageId && !outcome.ok) {
|
|
33217
|
+
sessionLog(args.sessionId, `rust note-nudge delivery skipped wire append: ${outcome.kind}`);
|
|
33218
|
+
}
|
|
33219
|
+
}
|
|
33220
|
+
const recoveryMessageIds = new Set;
|
|
33221
|
+
let thinkingBindingRecovery = null;
|
|
33222
|
+
if (modelAcceptsEmptyContent(args.resolvedProviderID)) {
|
|
33223
|
+
try {
|
|
33224
|
+
for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
|
|
33225
|
+
if (!id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX))
|
|
33226
|
+
continue;
|
|
33227
|
+
const messageId2 = id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length);
|
|
33228
|
+
if (messageId2.length > 0)
|
|
33229
|
+
recoveryMessageIds.add(messageId2);
|
|
33230
|
+
}
|
|
33231
|
+
const flagTarget = args.thinkingBindingRecoveryEnabledForModel ? getThinkingBindingRecoveryTarget(args.db, args.sessionId) : null;
|
|
33232
|
+
if (flagTarget) {
|
|
33233
|
+
const messageId2 = flagTarget === NEWEST_REASONING_BEARING_ASSISTANT ? findNewestReasoningBearingAssistantId(args.messages) : flagTarget;
|
|
33234
|
+
if (messageId2 && assistantHasReasoningPart(args.messages, messageId2)) {
|
|
33235
|
+
const frozenId = thinkingBindingRecoveryFrozenId(messageId2);
|
|
33236
|
+
const persisted = recoveryMessageIds.has(messageId2) || addMergedReasoningStrippedIds(args.db, args.sessionId, [frozenId]);
|
|
33237
|
+
if (persisted) {
|
|
33238
|
+
recoveryMessageIds.add(messageId2);
|
|
33239
|
+
thinkingBindingRecovery = { flagTarget, messageId: messageId2 };
|
|
33240
|
+
} else {
|
|
33241
|
+
sessionLog(args.sessionId, "rust thinking binding recovery: persistence failed; leaving the bound block intact");
|
|
33242
|
+
}
|
|
33243
|
+
}
|
|
33244
|
+
}
|
|
33245
|
+
} catch (error) {
|
|
33246
|
+
sessionLog(args.sessionId, "rust thinking binding recovery failed:", error);
|
|
33247
|
+
}
|
|
33248
|
+
stripReasoningFromAssistantIds(args.messages, args.resolvedProviderID, recoveryMessageIds);
|
|
32726
33249
|
}
|
|
33250
|
+
return { thinkingBindingRecovery };
|
|
32727
33251
|
}
|
|
32728
33252
|
function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
|
|
32729
33253
|
const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
|
|
@@ -32847,22 +33371,13 @@ function finalizeMessageRepresentation(messages, resolvedProviderID, options) {
|
|
|
32847
33371
|
clearedParts = stripClearedReasoning(targetedMessages);
|
|
32848
33372
|
}
|
|
32849
33373
|
}
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
32853
|
-
const message = messages[index];
|
|
32854
|
-
if (message.info.role !== "assistant")
|
|
32855
|
-
continue;
|
|
32856
|
-
newestAssistant = message;
|
|
32857
|
-
break;
|
|
32858
|
-
}
|
|
32859
|
-
}
|
|
32860
|
-
const mergedReasoningParts = options?.skipMergedReasoningStrip ? 0 : stripReasoningFromMergedAssistants(messages, resolvedProviderID, {
|
|
33374
|
+
const bindingRecoveryParts = options?.skipMergedReasoningStrip ? 0 : stripReasoningFromAssistantIds(messages, resolvedProviderID, options?.thinkingBindingRecoveryMessageIds ?? new Set);
|
|
33375
|
+
const mergedReasoningParts = bindingRecoveryParts + (options?.skipMergedReasoningStrip ? 0 : stripReasoningFromMergedAssistants(messages, resolvedProviderID, {
|
|
32861
33376
|
mutationExemptMessage: options?.reasoningMutationExemptMessage,
|
|
32862
33377
|
frozenMessageIds: options?.mergedReasoningStrippedIds
|
|
32863
|
-
});
|
|
33378
|
+
}));
|
|
32864
33379
|
if (!options?.skipTrailingWhitespaceStrip && modelAcceptsEmptyContent(resolvedProviderID)) {
|
|
32865
|
-
applyFrozenTrailingBlankDecisions(messages,
|
|
33380
|
+
applyFrozenTrailingBlankDecisions(messages, options?.trailingBlankDecisions ?? new Map);
|
|
32866
33381
|
}
|
|
32867
33382
|
return { clearedParts, mergedReasoningParts };
|
|
32868
33383
|
}
|
|
@@ -32964,6 +33479,10 @@ async function runPostTransformPhase(args) {
|
|
|
32964
33479
|
const shouldReadPendingOps = !compactionOff && (materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || compartmentRunning);
|
|
32965
33480
|
const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
|
|
32966
33481
|
const hasPendingUserOps = pendingOps.length > 0;
|
|
33482
|
+
const formatPendingOpsDepth = () => {
|
|
33483
|
+
const depth = getPendingOpsCount(args.db, args.sessionId);
|
|
33484
|
+
return depth === null ? "not loaded (deferred pass)" : String(depth);
|
|
33485
|
+
};
|
|
32967
33486
|
const shouldApplyPendingOps = !compactionOff && (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || foldExecutedThisPass) && (!compartmentRunning || bypassCompartmentGate);
|
|
32968
33487
|
const shouldRunHeuristics = !compactionOff && (!compartmentRunning || bypassCompartmentGate) && (materializationRequested || forceMaterialization || foldExecutedThisPass || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
|
|
32969
33488
|
const isCacheBustingPass = shouldApplyPendingOps || shouldRunHeuristics;
|
|
@@ -32983,10 +33502,15 @@ async function runPostTransformPhase(args) {
|
|
|
32983
33502
|
const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
|
|
32984
33503
|
const reason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `scheduler_execute_subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
|
|
32985
33504
|
sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
|
|
33505
|
+
} else if (args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
33506
|
+
sessionLog(args.sessionId, `heuristics WILL NOT RUN — reason=${args.schedulerDeferReason}`);
|
|
32986
33507
|
}
|
|
32987
33508
|
if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
|
|
32988
33509
|
sessionLog(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
|
|
32989
33510
|
}
|
|
33511
|
+
if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
33512
|
+
sessionLog(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
33513
|
+
}
|
|
32990
33514
|
if (compartmentRunning && hasPendingUserOps) {
|
|
32991
33515
|
if (bypassCompartmentGate) {
|
|
32992
33516
|
const bypassReason = forceMaterialization ? `emergency >=${args.forceMaterializationPercentage}%` : "m0 hard fold";
|
|
@@ -33021,7 +33545,7 @@ async function runPostTransformPhase(args) {
|
|
|
33021
33545
|
try {
|
|
33022
33546
|
if (shouldApplyPendingOps) {
|
|
33023
33547
|
const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
33024
|
-
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${
|
|
33548
|
+
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${formatPendingOpsDepth()}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
33025
33549
|
const tApply = performance.now();
|
|
33026
33550
|
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
|
|
33027
33551
|
if (pendingOpsDidMutate) {
|
|
@@ -33511,10 +34035,34 @@ async function runPostTransformPhase(args) {
|
|
|
33511
34035
|
}
|
|
33512
34036
|
}
|
|
33513
34037
|
const mergedReasoningStrippedIds = new Set;
|
|
34038
|
+
const thinkingBindingRecoveryMessageIds = new Set;
|
|
34039
|
+
let thinkingBindingRecovery = null;
|
|
33514
34040
|
if (canUseEmptySentinels && !compactionOff) {
|
|
33515
34041
|
try {
|
|
33516
34042
|
for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
|
|
33517
34043
|
mergedReasoningStrippedIds.add(id);
|
|
34044
|
+
if (id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX)) {
|
|
34045
|
+
const messageId2 = id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length);
|
|
34046
|
+
if (messageId2.length > 0)
|
|
34047
|
+
thinkingBindingRecoveryMessageIds.add(messageId2);
|
|
34048
|
+
}
|
|
34049
|
+
}
|
|
34050
|
+
const flagTarget = args.thinkingBindingRecoveryEnabledForModel ? getThinkingBindingRecoveryTarget(args.db, args.sessionId) : null;
|
|
34051
|
+
if (flagTarget) {
|
|
34052
|
+
const messageId2 = flagTarget === NEWEST_REASONING_BEARING_ASSISTANT ? findNewestReasoningBearingAssistantId(args.messages) : flagTarget;
|
|
34053
|
+
if (messageId2 && assistantHasReasoningPart(args.messages, messageId2)) {
|
|
34054
|
+
const frozenId = thinkingBindingRecoveryFrozenId(messageId2);
|
|
34055
|
+
const persisted = mergedReasoningStrippedIds.has(frozenId) || addMergedReasoningStrippedIds(args.db, args.sessionId, [frozenId]);
|
|
34056
|
+
if (persisted) {
|
|
34057
|
+
mergedReasoningStrippedIds.add(frozenId);
|
|
34058
|
+
thinkingBindingRecoveryMessageIds.add(messageId2);
|
|
34059
|
+
thinkingBindingRecovery = { flagTarget, messageId: messageId2 };
|
|
34060
|
+
bustedThisPass = true;
|
|
34061
|
+
} else {
|
|
34062
|
+
args.passOutcome?.record("thinking-binding-recovery-persistence-failure");
|
|
34063
|
+
sessionLog(args.sessionId, "thinking binding recovery: persistence failed; leaving the bound block intact");
|
|
34064
|
+
}
|
|
34065
|
+
}
|
|
33518
34066
|
}
|
|
33519
34067
|
if (isCacheBustingPass) {
|
|
33520
34068
|
const candidates = findMergedReasoningStripCandidateIds(args.messages, args.resolvedProviderID, { mutationExemptMessage: reasoningMutationExemptMessage });
|
|
@@ -33578,17 +34126,6 @@ async function runPostTransformPhase(args) {
|
|
|
33578
34126
|
}
|
|
33579
34127
|
}
|
|
33580
34128
|
}
|
|
33581
|
-
const tFinalRepresentation = performance.now();
|
|
33582
|
-
const finalRepresentation = finalizeMessageRepresentation(args.messages, args.resolvedProviderID, {
|
|
33583
|
-
prependedMessageCount,
|
|
33584
|
-
reasoningMutatedMessages,
|
|
33585
|
-
reasoningMutationExemptMessage,
|
|
33586
|
-
trailingBlankNewestAssistant,
|
|
33587
|
-
mergedReasoningStrippedIds,
|
|
33588
|
-
trailingBlankDecisions,
|
|
33589
|
-
skipMergedReasoningStrip: compactionOff,
|
|
33590
|
-
skipTrailingWhitespaceStrip: compactionOff
|
|
33591
|
-
});
|
|
33592
34129
|
if (canUseEmptySentinels && !compactionOff) {
|
|
33593
34130
|
const detectedCandidates = findTrailingBlankDecisionCandidates(args.messages, trailingBlankDecisions, {
|
|
33594
34131
|
refreshMessageId: newestAssistantId,
|
|
@@ -33602,20 +34139,16 @@ async function runPostTransformPhase(args) {
|
|
|
33602
34139
|
});
|
|
33603
34140
|
if (persisted) {
|
|
33604
34141
|
const committed = getTrailingBlankDecisions(args.db, args.sessionId);
|
|
33605
|
-
const newlyFrozen = new Map;
|
|
33606
34142
|
for (const [id] of candidates) {
|
|
33607
34143
|
const decision = committed.get(id);
|
|
33608
|
-
if (
|
|
33609
|
-
|
|
33610
|
-
trailingBlankDecisions.set(id, decision);
|
|
33611
|
-
newlyFrozen.set(id, decision);
|
|
34144
|
+
if (decision)
|
|
34145
|
+
trailingBlankDecisions.set(id, decision);
|
|
33612
34146
|
}
|
|
33613
|
-
applyFrozenTrailingBlankDecisions(args.messages, newestAssistantId, newlyFrozen);
|
|
33614
34147
|
if (isCacheBustingPass)
|
|
33615
34148
|
bustedThisPass = true;
|
|
33616
34149
|
} else {
|
|
33617
34150
|
args.passOutcome?.record("trailing-blank-decision-persistence-failure");
|
|
33618
|
-
sessionLog(args.sessionId, "trailing blank decision: persistence failed;
|
|
34151
|
+
sessionLog(args.sessionId, "trailing blank decision: persistence failed; serving the frozen decisions");
|
|
33619
34152
|
}
|
|
33620
34153
|
} catch (error) {
|
|
33621
34154
|
args.passOutcome?.record("trailing-blank-decision-exception");
|
|
@@ -33623,6 +34156,17 @@ async function runPostTransformPhase(args) {
|
|
|
33623
34156
|
}
|
|
33624
34157
|
}
|
|
33625
34158
|
}
|
|
34159
|
+
const tFinalRepresentation = performance.now();
|
|
34160
|
+
const finalRepresentation = finalizeMessageRepresentation(args.messages, args.resolvedProviderID, {
|
|
34161
|
+
prependedMessageCount,
|
|
34162
|
+
reasoningMutatedMessages,
|
|
34163
|
+
reasoningMutationExemptMessage,
|
|
34164
|
+
mergedReasoningStrippedIds,
|
|
34165
|
+
thinkingBindingRecoveryMessageIds,
|
|
34166
|
+
trailingBlankDecisions,
|
|
34167
|
+
skipMergedReasoningStrip: compactionOff,
|
|
34168
|
+
skipTrailingWhitespaceStrip: compactionOff
|
|
34169
|
+
});
|
|
33626
34170
|
sessionLog(args.sessionId, `final representation: clearedParts=${finalRepresentation.clearedParts} mergedReasoningParts=${finalRepresentation.mergedReasoningParts}`);
|
|
33627
34171
|
logTransformTiming(args.sessionId, "finalizeMessageRepresentation", tFinalRepresentation, `clearedParts=${finalRepresentation.clearedParts} mergedReasoningParts=${finalRepresentation.mergedReasoningParts}`);
|
|
33628
34172
|
let assertedBaseline;
|
|
@@ -33717,7 +34261,8 @@ async function runPostTransformPhase(args) {
|
|
|
33717
34261
|
emergencyReclaimedTokens,
|
|
33718
34262
|
droppedCount,
|
|
33719
34263
|
emergency,
|
|
33720
|
-
bustedThisPass
|
|
34264
|
+
bustedThisPass,
|
|
34265
|
+
thinkingBindingRecovery
|
|
33721
34266
|
};
|
|
33722
34267
|
}
|
|
33723
34268
|
function checkM0MutationDriftAndSignal(args) {
|
|
@@ -34001,7 +34546,9 @@ function formatRustPassLog(args) {
|
|
|
34001
34546
|
const measured = timings.prefixGuard + timings.ordinalResolve + timings.stateSync + timings.clone + timings.wireBuild + timings.transport + timings.apply + timings.lkgSnapshot;
|
|
34002
34547
|
const unattributed = Math.max(0, args.elapsedMs - measured);
|
|
34003
34548
|
const rowVersion = Number.isSafeInteger(args.rowVersion) ? args.rowVersion : 0;
|
|
34004
|
-
|
|
34549
|
+
const schedulerFields = args.schedulerDecision ? ` scheduler=${args.schedulerDecision}${args.schedulerDeferReason ? ` defer_reason=${args.schedulerDeferReason}` : ""}` : "";
|
|
34550
|
+
const historianFields = args.historianCanonicalCause ? ` historian_no_fire=${args.historianNoFire ?? "unknown"} canonical_cause=${args.historianCanonicalCause}` : "";
|
|
34551
|
+
return `rust pass: decision=${args.decision} reason=${args.reason}${schedulerFields}${historianFields} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} row_version=${rowVersion} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} mirror_pull:${timings.mirrorPull.toFixed(1)} compartment_mirror:${timings.compartmentMirror.toFixed(1)} other:${unattributed.toFixed(1)}`;
|
|
34005
34552
|
}
|
|
34006
34553
|
function isSyntheticUserMessage(message) {
|
|
34007
34554
|
if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
|
|
@@ -34549,6 +35096,7 @@ function createRustModeTransform(deps, options) {
|
|
|
34549
35096
|
const states = new Map;
|
|
34550
35097
|
const wireCaches = new Map;
|
|
34551
35098
|
const scheduleLkgCapture = options.scheduleLkgCapture ?? ((capture) => setImmediate(capture));
|
|
35099
|
+
const installNativeMessages = options.installNativeMessagesForTests ?? replaceMessagesInPlace;
|
|
34552
35100
|
const rawFallbackEstimator = options.rawFallbackEstimatorForTests ?? estimateFinalWireInputTokens;
|
|
34553
35101
|
const timeoutMs = Math.max(1, options.moduleTimeoutMs ?? RUST_SEND_TIMEOUT_MS);
|
|
34554
35102
|
const logStage = (sessionId, stage, startedAt, timings, extra) => {
|
|
@@ -34636,6 +35184,12 @@ function createRustModeTransform(deps, options) {
|
|
|
34636
35184
|
return false;
|
|
34637
35185
|
}
|
|
34638
35186
|
const replayModel = modelFromMessages(currentMessages) ?? findLastAssistantModelFromOpenCodeDb(sessionId);
|
|
35187
|
+
replayRustModeBindingMismatchStrips({
|
|
35188
|
+
db: deps.db,
|
|
35189
|
+
sessionId,
|
|
35190
|
+
messages: replay.messages,
|
|
35191
|
+
resolvedProviderID: replayModel?.providerID
|
|
35192
|
+
});
|
|
34639
35193
|
const trustedReplayLimit = replayModel ? resolveTrustedContextLimit(replayModel.providerID, replayModel.modelID, {
|
|
34640
35194
|
db: deps.db,
|
|
34641
35195
|
sessionID: sessionId
|
|
@@ -34668,23 +35222,21 @@ function createRustModeTransform(deps, options) {
|
|
|
34668
35222
|
sessionLog(sessionId, "lkg_replay_served");
|
|
34669
35223
|
return true;
|
|
34670
35224
|
};
|
|
34671
|
-
const prepareRustCapture = (state, sessionId,
|
|
35225
|
+
const prepareRustCapture = (state, sessionId, inputIds, inputKeys, inputSnapshots, nativeMessages, responseRowVersion) => {
|
|
34672
35226
|
state.lkgCaptureSequence += 1;
|
|
34673
|
-
const inputIds = input.map((message) => message.info.id);
|
|
34674
35227
|
if (inputIds.some((id) => typeof id !== "string") || new Set(inputIds).size !== inputIds.length || inputIds.length === 0 || inputSnapshots.length !== inputIds.length) {
|
|
34675
35228
|
return null;
|
|
34676
35229
|
}
|
|
34677
35230
|
const jsonPrefix = JSON.stringify(nativeMessages);
|
|
34678
35231
|
if (typeof jsonPrefix !== "string")
|
|
34679
35232
|
return null;
|
|
34680
|
-
const keys = resolveLkgModelKeys(input);
|
|
34681
35233
|
return {
|
|
34682
35234
|
sessionId,
|
|
34683
35235
|
inputIds,
|
|
34684
35236
|
inputSnapshots,
|
|
34685
35237
|
jsonPrefix,
|
|
34686
|
-
modelKey:
|
|
34687
|
-
providerKey:
|
|
35238
|
+
modelKey: inputKeys.modelKey,
|
|
35239
|
+
providerKey: inputKeys.providerKey,
|
|
34688
35240
|
capturedAt: Date.now(),
|
|
34689
35241
|
rowVersion: responseRowVersion,
|
|
34690
35242
|
captureSequence: state.lkgCaptureSequence
|
|
@@ -34729,6 +35281,8 @@ function createRustModeTransform(deps, options) {
|
|
|
34729
35281
|
const passStartedAt = performance.now();
|
|
34730
35282
|
const passObservedAtMs = Date.now();
|
|
34731
35283
|
const state = ensureState(states, sessionId);
|
|
35284
|
+
const trailingBlankSourceDecisions = snapshotTrailingBlankSourceDecisions(messages);
|
|
35285
|
+
const trailingBlankNewestAssistantId = [...messages].reverse().find((message) => message.info.role === "assistant")?.info.id;
|
|
34732
35286
|
const timings = emptyRustPassTimings();
|
|
34733
35287
|
state.passCount += 1;
|
|
34734
35288
|
const syntheticTurn = observeSyntheticTurn(state, messages);
|
|
@@ -34741,6 +35295,10 @@ function createRustModeTransform(deps, options) {
|
|
|
34741
35295
|
let requestInputTokens = 0;
|
|
34742
35296
|
let decision = "error";
|
|
34743
35297
|
let materializeReason = "none";
|
|
35298
|
+
let schedulerDecision;
|
|
35299
|
+
let schedulerDeferReason;
|
|
35300
|
+
let historianNoFire;
|
|
35301
|
+
let historianCanonicalCause;
|
|
34744
35302
|
let servedFrom = "none";
|
|
34745
35303
|
let moduleElapsedMs = 0;
|
|
34746
35304
|
let rowVersion = 0;
|
|
@@ -34819,6 +35377,10 @@ function createRustModeTransform(deps, options) {
|
|
|
34819
35377
|
sessionLog(sessionId, formatRustPassLog({
|
|
34820
35378
|
decision,
|
|
34821
35379
|
reason: materializeReason,
|
|
35380
|
+
schedulerDecision,
|
|
35381
|
+
schedulerDeferReason,
|
|
35382
|
+
historianNoFire,
|
|
35383
|
+
historianCanonicalCause,
|
|
34822
35384
|
servedFrom,
|
|
34823
35385
|
inputCount,
|
|
34824
35386
|
outputCount: output.messages.length,
|
|
@@ -34841,6 +35403,11 @@ function createRustModeTransform(deps, options) {
|
|
|
34841
35403
|
const captureResponseTelemetry = (response) => {
|
|
34842
35404
|
decision = typeof response.decision === "string" ? response.decision : typeof response.action === "string" ? response.action : typeof response.status === "string" ? response.status : "unknown";
|
|
34843
35405
|
servedFrom = typeof response.served_from === "string" ? response.served_from : "unknown";
|
|
35406
|
+
schedulerDecision = typeof response.scheduler_decision === "string" ? response.scheduler_decision : undefined;
|
|
35407
|
+
schedulerDeferReason = typeof response.scheduler_defer_reason === "string" ? response.scheduler_defer_reason : undefined;
|
|
35408
|
+
const historian = isRecord4(response.historian) ? response.historian : undefined;
|
|
35409
|
+
historianNoFire = typeof historian?.no_fire === "string" ? historian.no_fire : undefined;
|
|
35410
|
+
historianCanonicalCause = typeof historian?.canonical_cause === "string" ? historian.canonical_cause : undefined;
|
|
34844
35411
|
materializeReason = typeof response.materialize_reason === "string" && response.materialize_reason.length > 0 ? response.materialize_reason : "none";
|
|
34845
35412
|
const timings2 = isRecord4(response.timings) ? response.timings : undefined;
|
|
34846
35413
|
const applyOnceTotal = timings2?.total;
|
|
@@ -35363,6 +35930,7 @@ function createRustModeTransform(deps, options) {
|
|
|
35363
35930
|
const decisionUpper = decision.toUpperCase();
|
|
35364
35931
|
const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
|
|
35365
35932
|
let appliedMessages;
|
|
35933
|
+
let thinkingBindingRecovery = null;
|
|
35366
35934
|
const applyStartedAt = performance.now();
|
|
35367
35935
|
try {
|
|
35368
35936
|
const moduleMessages = applyNativeMessagesVerbatim({ messages: [] }, response, previousWireCache?.nativeOutput ? {
|
|
@@ -35390,16 +35958,20 @@ function createRustModeTransform(deps, options) {
|
|
|
35390
35958
|
}
|
|
35391
35959
|
pendingWireCache.nativeOutput = appliedMessages;
|
|
35392
35960
|
if (!replayedFrozenRepresentation) {
|
|
35393
|
-
runRustModePostprocess({
|
|
35961
|
+
thinkingBindingRecovery = runRustModePostprocess({
|
|
35394
35962
|
db: deps.db,
|
|
35395
35963
|
sessionId,
|
|
35396
35964
|
messages: appliedMessages,
|
|
35397
35965
|
projectPath: memoryProjectPath,
|
|
35398
35966
|
fullFeatureMode: !sessionMeta.isSubagent,
|
|
35399
35967
|
compactionOff: deps.compactionOff,
|
|
35968
|
+
resolvedProviderID: model?.providerID,
|
|
35969
|
+
thinkingBindingRecoveryEnabledForModel: isFable51ThinkingBindingModel(model?.providerID, model?.modelID),
|
|
35970
|
+
trailingBlankSourceDecisions,
|
|
35971
|
+
trailingBlankNewestAssistantId: typeof trailingBlankNewestAssistantId === "string" ? trailingBlankNewestAssistantId : undefined,
|
|
35400
35972
|
tagger: deps.tagger,
|
|
35401
35973
|
ctxReduceAvailability: reduceAvailability
|
|
35402
|
-
});
|
|
35974
|
+
}).thinkingBindingRecovery;
|
|
35403
35975
|
}
|
|
35404
35976
|
const boundaryId = response.boundary_id;
|
|
35405
35977
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
@@ -35423,11 +35995,20 @@ function createRustModeTransform(deps, options) {
|
|
|
35423
35995
|
});
|
|
35424
35996
|
}
|
|
35425
35997
|
logStage(sessionId, "apply", applyStartedAt, timings);
|
|
35998
|
+
const lkgInputIds = messages.map((message) => message.info.id);
|
|
35999
|
+
const lkgInputKeys = resolveLkgModelKeys(messages);
|
|
36000
|
+
const applyReplaceStartedAt = performance.now();
|
|
36001
|
+
installNativeMessages(output, appliedMessages);
|
|
36002
|
+
logStage(sessionId, "apply", applyReplaceStartedAt, timings);
|
|
36003
|
+
if (thinkingBindingRecovery) {
|
|
36004
|
+
const cleared = clearThinkingBindingRecoveryIf(deps.db, sessionId, thinkingBindingRecovery.flagTarget);
|
|
36005
|
+
sessionLog(sessionId, `rust thinking binding recovery: stripped bound reasoning from assistant ${thinkingBindingRecovery.messageId}; flag=${cleared ? "cleared" : "rearmed"}`);
|
|
36006
|
+
}
|
|
35426
36007
|
const lkgSnapshotStartedAt = performance.now();
|
|
35427
36008
|
if (cacheBustingPass) {
|
|
35428
36009
|
dropSlot(sessionId, "lkg_cache_bust_pending_capture");
|
|
35429
36010
|
}
|
|
35430
|
-
const capturePlan = prepareRustCapture(state, sessionId,
|
|
36011
|
+
const capturePlan = prepareRustCapture(state, sessionId, lkgInputIds, lkgInputKeys, pendingWireCache.rawContentSnapshots, output.messages, rowVersion);
|
|
35431
36012
|
let captureMode = "async";
|
|
35432
36013
|
const captureFailed = (mode, error) => {
|
|
35433
36014
|
if (states.get(sessionId) !== state || capturePlan && capturePlan.captureSequence !== state.lkgCaptureSequence) {
|
|
@@ -35464,9 +36045,6 @@ function createRustModeTransform(deps, options) {
|
|
|
35464
36045
|
}
|
|
35465
36046
|
}
|
|
35466
36047
|
logStage(sessionId, "lkgSnapshot", lkgSnapshotStartedAt, timings, `mode=${captureMode} row_version=${rowVersion}`);
|
|
35467
|
-
const applyReplaceStartedAt = performance.now();
|
|
35468
|
-
replaceMessagesInPlace(output, appliedMessages);
|
|
35469
|
-
logStage(sessionId, "apply", applyReplaceStartedAt, timings);
|
|
35470
36048
|
} catch (error) {
|
|
35471
36049
|
logStage(sessionId, "apply", applyStartedAt, timings, "failed=true");
|
|
35472
36050
|
try {
|
|
@@ -35612,17 +36190,24 @@ function createRustModeTransform(deps, options) {
|
|
|
35612
36190
|
};
|
|
35613
36191
|
return {
|
|
35614
36192
|
run,
|
|
35615
|
-
clearSession(sessionId) {
|
|
36193
|
+
async clearSession(sessionId) {
|
|
35616
36194
|
const projectRoot = states.get(sessionId)?.memoryAuthorityRoot ?? options.projectRoot ?? null;
|
|
35617
|
-
|
|
35618
|
-
|
|
35619
|
-
|
|
35620
|
-
|
|
35621
|
-
|
|
35622
|
-
|
|
35623
|
-
|
|
35624
|
-
|
|
35625
|
-
|
|
36195
|
+
const clearLocalState = () => {
|
|
36196
|
+
dropSlot(sessionId, "session-deleted");
|
|
36197
|
+
states.delete(sessionId);
|
|
36198
|
+
wireCaches.delete(sessionId);
|
|
36199
|
+
clearCompartmentMirrorCursor(sessionId);
|
|
36200
|
+
};
|
|
36201
|
+
clearLocalState();
|
|
36202
|
+
try {
|
|
36203
|
+
if (projectRoot && options.moduleClient.deleteSession) {
|
|
36204
|
+
await options.moduleClient.deleteSession(sessionId, projectRoot);
|
|
36205
|
+
}
|
|
36206
|
+
} catch (error) {
|
|
36207
|
+
sessionLog(sessionId, "rust module session deletion failed:", error);
|
|
36208
|
+
throw error;
|
|
36209
|
+
} finally {
|
|
36210
|
+
clearLocalState();
|
|
35626
36211
|
options.moduleClient.closeSession?.(sessionId);
|
|
35627
36212
|
}
|
|
35628
36213
|
},
|
|
@@ -36295,7 +36880,11 @@ function createTransform(deps) {
|
|
|
36295
36880
|
sessionId,
|
|
36296
36881
|
effectiveExecuteThresholdPercentage
|
|
36297
36882
|
});
|
|
36298
|
-
const {
|
|
36883
|
+
const {
|
|
36884
|
+
midTurnAdjustedSchedulerDecision,
|
|
36885
|
+
sideEffect,
|
|
36886
|
+
deferReason: schedulerDeferReason
|
|
36887
|
+
} = applyMidTurnDeferral({
|
|
36299
36888
|
base: schedulerDecisionEarly,
|
|
36300
36889
|
bypassReason,
|
|
36301
36890
|
midTurn
|
|
@@ -36664,6 +37253,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
36664
37253
|
contextUsage,
|
|
36665
37254
|
usableWindow: resolvedContextLimit ?? 0,
|
|
36666
37255
|
schedulerDecision,
|
|
37256
|
+
schedulerDeferReason,
|
|
36667
37257
|
fullFeatureMode,
|
|
36668
37258
|
compactionOff,
|
|
36669
37259
|
canRunCompartments,
|
|
@@ -36696,6 +37286,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
36696
37286
|
cavemanTextCompression: !reducedMode ? deps.cavemanTextCompression : undefined,
|
|
36697
37287
|
smartDrops: deps.smartDrops === true,
|
|
36698
37288
|
resolvedProviderID,
|
|
37289
|
+
thinkingBindingRecoveryEnabledForModel: isFable51ThinkingBindingModel(modelForBudget?.providerID, modelForBudget?.modelID),
|
|
36699
37290
|
trailingBlankSourceDecisions,
|
|
36700
37291
|
passOutcome,
|
|
36701
37292
|
historyRefreshSessions: deps.historyRefreshSessions,
|
|
@@ -36882,13 +37473,18 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
36882
37473
|
const elapsed = (performance.now() - startTime).toFixed(1);
|
|
36883
37474
|
sessionLog(sessionId, `transform completed in ${elapsed}ms (${messages.length} messages, ${targets.size} targets, watermark: ${watermark})`);
|
|
36884
37475
|
deps.maybeAutoEmbedSession?.(sessionId);
|
|
37476
|
+
const bindingRecovery = postTransformResult.thinkingBindingRecovery;
|
|
37477
|
+
if (bindingRecovery) {
|
|
37478
|
+
const cleared = clearThinkingBindingRecoveryIf(db, sessionId, bindingRecovery.flagTarget);
|
|
37479
|
+
sessionLog(sessionId, `thinking binding recovery: stripped bound reasoning from assistant ${bindingRecovery.messageId}; flag=${cleared ? "cleared" : "rearmed"}`);
|
|
37480
|
+
}
|
|
36885
37481
|
};
|
|
36886
37482
|
return Object.assign(transform, {
|
|
36887
37483
|
invalidateRustWireState(sessionId) {
|
|
36888
37484
|
rustModeTransform?.invalidateWireState(sessionId);
|
|
36889
37485
|
},
|
|
36890
|
-
clearRustSession(sessionId) {
|
|
36891
|
-
rustModeTransform?.clearSession(sessionId);
|
|
37486
|
+
async clearRustSession(sessionId) {
|
|
37487
|
+
await rustModeTransform?.clearSession(sessionId);
|
|
36892
37488
|
}
|
|
36893
37489
|
});
|
|
36894
37490
|
}
|
|
@@ -37006,6 +37602,16 @@ function createEventHandler2(deps) {
|
|
|
37006
37602
|
return;
|
|
37007
37603
|
}
|
|
37008
37604
|
try {
|
|
37605
|
+
const bindingMismatch = detectThinkingBindingMismatch(errInfo.error);
|
|
37606
|
+
if (bindingMismatch.isBindingMismatch) {
|
|
37607
|
+
const model = findLastAssistantModelFromOpenCodeDb(errInfo.sessionID);
|
|
37608
|
+
if (deps.thinkingBindingRecoveryEnabled !== false && !deps.compactionOff && isFable51ThinkingBindingModel(model?.providerID, model?.modelID)) {
|
|
37609
|
+
armThinkingBindingRecovery(deps.db, errInfo.sessionID, bindingMismatch.messageId);
|
|
37610
|
+
dropSlot(errInfo.sessionID, "thinking-binding-recovery-arm");
|
|
37611
|
+
deps.onSessionCacheInvalidated?.(errInfo.sessionID);
|
|
37612
|
+
}
|
|
37613
|
+
return;
|
|
37614
|
+
}
|
|
37009
37615
|
const detection = detectOverflow(errInfo.error);
|
|
37010
37616
|
if (!detection.isOverflow) {
|
|
37011
37617
|
return;
|
|
@@ -37069,6 +37675,18 @@ function createEventHandler2(deps) {
|
|
|
37069
37675
|
});
|
|
37070
37676
|
}
|
|
37071
37677
|
let messageHadOverflowError = false;
|
|
37678
|
+
if (info.error !== undefined && info.error !== null) {
|
|
37679
|
+
const bindingMismatch = detectThinkingBindingMismatch(info.error);
|
|
37680
|
+
if (bindingMismatch.isBindingMismatch && deps.thinkingBindingRecoveryEnabled !== false && !deps.compactionOff && isFable51ThinkingBindingModel(info.providerID, info.modelID)) {
|
|
37681
|
+
try {
|
|
37682
|
+
armThinkingBindingRecovery(deps.db, info.sessionID, bindingMismatch.messageId);
|
|
37683
|
+
dropSlot(info.sessionID, "thinking-binding-recovery-arm");
|
|
37684
|
+
deps.onSessionCacheInvalidated?.(info.sessionID);
|
|
37685
|
+
} catch (error) {
|
|
37686
|
+
sessionLog(info.sessionID, "event message.updated thinking binding recovery persistence failed:", error);
|
|
37687
|
+
}
|
|
37688
|
+
}
|
|
37689
|
+
}
|
|
37072
37690
|
if (info.error !== undefined && info.error !== null) {
|
|
37073
37691
|
const detection = detectOverflow(info.error);
|
|
37074
37692
|
if (detection.isOverflow) {
|
|
@@ -37279,15 +37897,17 @@ function createEventHandler2(deps) {
|
|
|
37279
37897
|
}
|
|
37280
37898
|
dropSlot(sessionId, "session.deleted");
|
|
37281
37899
|
try {
|
|
37282
|
-
markSessionCleanupPending(deps.db, sessionId);
|
|
37283
|
-
|
|
37284
|
-
|
|
37900
|
+
const rustCleanupPending = markSessionCleanupPending(deps.db, sessionId, deps.rustSessionCleanup === true);
|
|
37901
|
+
await deps.onSessionDeleted?.(sessionId);
|
|
37902
|
+
if (!rustCleanupPending || deps.rustSessionCleanup === true) {
|
|
37903
|
+
removeCompactionMarkerForSession(deps.db, sessionId);
|
|
37904
|
+
clearSession(deps.db, sessionId, deps.rustSessionCleanup === true);
|
|
37905
|
+
}
|
|
37285
37906
|
} catch (error) {
|
|
37286
37907
|
sessionLog(sessionId, "event session.deleted persistence failed:", error);
|
|
37287
37908
|
}
|
|
37288
37909
|
resetDegradedCacheCount(sessionId);
|
|
37289
37910
|
deps.onSessionCacheInvalidated?.(sessionId);
|
|
37290
|
-
deps.onSessionDeleted?.(sessionId);
|
|
37291
37911
|
deps.contextUsageMap.delete(sessionId);
|
|
37292
37912
|
deps.tagger.cleanup(sessionId);
|
|
37293
37913
|
clearTransformDecisionSession(sessionId);
|
|
@@ -37298,6 +37918,40 @@ function createEventHandler2(deps) {
|
|
|
37298
37918
|
};
|
|
37299
37919
|
}
|
|
37300
37920
|
|
|
37921
|
+
// src/hooks/magic-context/format-embed-failure.ts
|
|
37922
|
+
function formatEmbedFailureSummary(embedded, remaining, failure) {
|
|
37923
|
+
const compartment = `compartment${embedded === 1 ? "" : "s"}`;
|
|
37924
|
+
if (!failure) {
|
|
37925
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`;
|
|
37926
|
+
}
|
|
37927
|
+
const retry = " Run /ctx-embed start again to retry them.";
|
|
37928
|
+
switch (failure.class) {
|
|
37929
|
+
case "substitution_rejected":
|
|
37930
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: set embedding.model to the served spelling.`;
|
|
37931
|
+
case "http_error": {
|
|
37932
|
+
const fix = failure.reason.startsWith("HTTP 401") || failure.reason.startsWith("HTTP 403") ? " Fix: check embedding.api_key." : failure.reason.startsWith("HTTP 402") ? " Fix: check provider quota or billing." : failure.reason.startsWith("HTTP 404") ? " Fix: check embedding.endpoint and embedding.model." : failure.retryable ? retry : " Fix: check embedding.endpoint, embedding.model, and credentials.";
|
|
37933
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${fix}`;
|
|
37934
|
+
}
|
|
37935
|
+
case "invalid_envelope":
|
|
37936
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: configure an OpenAI-compatible embedding endpoint that returns data[].embedding.`;
|
|
37937
|
+
case "certification_refusal":
|
|
37938
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: recertify SYNAPSE or configure embedding.fallback_provider, then run /ctx-embed start again.`;
|
|
37939
|
+
case "credential_required":
|
|
37940
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: reauthenticate SYNAPSE, then run /ctx-embed start again.`;
|
|
37941
|
+
case "local_binding_missing":
|
|
37942
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` to verify the WASM fallback. On Intel macOS, onnxruntime-node@1.23.0 may be pinned manually for optional native speed.`;
|
|
37943
|
+
case "local_fs_unavailable":
|
|
37944
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: update or reinstall Magic Context so its Node WASM bundle can persist the model, then run /ctx-embed start again.`;
|
|
37945
|
+
case "local_download_failure":
|
|
37946
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: check network/proxy access to the model host.${retry}`;
|
|
37947
|
+
case "local_runtime_error":
|
|
37948
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` for local runtime diagnostics.`;
|
|
37949
|
+
case "empty_result":
|
|
37950
|
+
case "transport_error":
|
|
37951
|
+
return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${failure.retryable ? retry : ""}`;
|
|
37952
|
+
}
|
|
37953
|
+
}
|
|
37954
|
+
|
|
37301
37955
|
// src/hooks/magic-context/text-complete.ts
|
|
37302
37956
|
function createTextCompleteHandler() {
|
|
37303
37957
|
return async (_input, output) => {
|
|
@@ -38221,6 +38875,7 @@ function createMagicContextHook(deps) {
|
|
|
38221
38875
|
const commitSeenLastPass = new Map;
|
|
38222
38876
|
const variantBySession = deps.liveSessionState?.variantBySession ?? new Map;
|
|
38223
38877
|
const liveModelBySession = deps.liveSessionState?.liveModelBySession ?? new Map;
|
|
38878
|
+
const latestAssistantMessageIdBySession = deps.liveSessionState?.latestAssistantMessageIdBySession ?? new Map;
|
|
38224
38879
|
const agentBySession = deps.liveSessionState?.agentBySession ?? new Map;
|
|
38225
38880
|
const sessionDirectoryBySession = deps.liveSessionState?.sessionDirectoryBySession ?? new Map;
|
|
38226
38881
|
const internalChildSessions = deps.liveSessionState?.internalChildSessions ?? new Set;
|
|
@@ -38257,6 +38912,7 @@ function createMagicContextHook(deps) {
|
|
|
38257
38912
|
db,
|
|
38258
38913
|
liveSessionState: {
|
|
38259
38914
|
liveModelBySession,
|
|
38915
|
+
latestAssistantMessageIdBySession,
|
|
38260
38916
|
channel1StateBySession,
|
|
38261
38917
|
variantBySession,
|
|
38262
38918
|
agentBySession,
|
|
@@ -38372,7 +39028,7 @@ function createMagicContextHook(deps) {
|
|
|
38372
39028
|
return terminal("skipped", msg);
|
|
38373
39029
|
}
|
|
38374
39030
|
case "stalled":
|
|
38375
|
-
return terminal("skipped",
|
|
39031
|
+
return terminal("skipped", formatEmbedFailureSummary(outcome.embedded, outcome.remaining, outcome.failure));
|
|
38376
39032
|
default:
|
|
38377
39033
|
return terminal("done", `Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search${runFailed > 0 ? ` (${runFailed} failed)` : ""}.`);
|
|
38378
39034
|
}
|
|
@@ -38415,7 +39071,7 @@ function createMagicContextHook(deps) {
|
|
|
38415
39071
|
autoEmbedAttemptedBySession.add(sessionId);
|
|
38416
39072
|
const directory = sessionDirectoryBySession.get(sessionId) ?? deps.directory;
|
|
38417
39073
|
(async () => {
|
|
38418
|
-
let
|
|
39074
|
+
let drainReachedTerminal = false;
|
|
38419
39075
|
try {
|
|
38420
39076
|
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
38421
39077
|
await ensureProjectRegisteredFromOpenCodeDirectory(directory, db);
|
|
@@ -38429,25 +39085,19 @@ function createMagicContextHook(deps) {
|
|
|
38429
39085
|
const remaining = coverage.session.total - coverage.session.embedded;
|
|
38430
39086
|
if (remaining <= 0)
|
|
38431
39087
|
return;
|
|
38432
|
-
const
|
|
38433
|
-
|
|
38434
|
-
|
|
38435
|
-
await sendIgnoredMessage(deps.client, sessionId, startMsg, {
|
|
38436
|
-
...notifyParams
|
|
38437
|
-
});
|
|
38438
|
-
}
|
|
38439
|
-
const summary = await executeEmbedHistory(sessionId);
|
|
39088
|
+
const embeddedBefore = coverage.session.embedded;
|
|
39089
|
+
await executeEmbedHistory(sessionId, { silent: true });
|
|
39090
|
+
drainReachedTerminal = true;
|
|
38440
39091
|
const completedCoverage = getEmbeddingCoverageStatus(db, sessionProjectIdentity, sessionId);
|
|
38441
|
-
|
|
38442
|
-
if (!isTuiConnected(sessionId)) {
|
|
38443
|
-
|
|
38444
|
-
|
|
38445
|
-
});
|
|
39092
|
+
const embeddedNow = completedCoverage.session.embedded - embeddedBefore;
|
|
39093
|
+
if (embeddedNow > 0 && !isTuiConnected(sessionId)) {
|
|
39094
|
+
const notifyParams = getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession);
|
|
39095
|
+
await sendIgnoredMessage(deps.client, sessionId, `Embedded ${embeddedNow} compartment${embeddedNow === 1 ? "" : "s"} of history for semantic search.`, { ...notifyParams });
|
|
38446
39096
|
}
|
|
38447
39097
|
} catch (error) {
|
|
38448
39098
|
log("[magic-context] auto-embed drain failed:", error);
|
|
38449
39099
|
} finally {
|
|
38450
|
-
if (!
|
|
39100
|
+
if (!drainReachedTerminal)
|
|
38451
39101
|
autoEmbedAttemptedBySession.delete(sessionId);
|
|
38452
39102
|
}
|
|
38453
39103
|
})();
|
|
@@ -38777,6 +39427,7 @@ function createMagicContextHook(deps) {
|
|
|
38777
39427
|
compactionHandler: deps.compactionHandler,
|
|
38778
39428
|
config: deps.config,
|
|
38779
39429
|
compactionOff,
|
|
39430
|
+
thinkingBindingRecoveryEnabled: deps.config.transform_mode !== "rust",
|
|
38780
39431
|
tagger: deps.tagger,
|
|
38781
39432
|
db,
|
|
38782
39433
|
client: deps.client,
|
|
@@ -38792,23 +39443,27 @@ function createMagicContextHook(deps) {
|
|
|
38792
39443
|
onRustWireInvalidated: (sessionId) => {
|
|
38793
39444
|
transform.invalidateRustWireState(sessionId);
|
|
38794
39445
|
},
|
|
38795
|
-
|
|
39446
|
+
rustSessionCleanup: rustModeModuleClient !== undefined,
|
|
39447
|
+
onSessionDeleted: async (sessionId) => {
|
|
38796
39448
|
dropSlot(sessionId, "session-deleted");
|
|
38797
|
-
|
|
38798
|
-
|
|
38799
|
-
|
|
38800
|
-
|
|
38801
|
-
|
|
38802
|
-
|
|
38803
|
-
|
|
38804
|
-
|
|
38805
|
-
|
|
38806
|
-
|
|
38807
|
-
|
|
38808
|
-
|
|
38809
|
-
|
|
38810
|
-
|
|
38811
|
-
|
|
39449
|
+
try {
|
|
39450
|
+
await transform.clearRustSession(sessionId);
|
|
39451
|
+
} finally {
|
|
39452
|
+
systemPromptHash.clearSession(sessionId);
|
|
39453
|
+
lastHeuristicsTurnId.delete(sessionId);
|
|
39454
|
+
clearToolPermissionDenied(sessionId);
|
|
39455
|
+
commitSeenLastPass.delete(sessionId);
|
|
39456
|
+
variantBySession.delete(sessionId);
|
|
39457
|
+
liveModelBySession.delete(sessionId);
|
|
39458
|
+
agentBySession.delete(sessionId);
|
|
39459
|
+
sessionDirectoryBySession.delete(sessionId);
|
|
39460
|
+
recompProgressBySession.delete(sessionId);
|
|
39461
|
+
internalChildSessions.delete(sessionId);
|
|
39462
|
+
rustMemorySyncRequestedSessions.delete(sessionId);
|
|
39463
|
+
channel1StateBySession.delete(sessionId);
|
|
39464
|
+
channel2DirectiveTextBySession.delete(sessionId);
|
|
39465
|
+
clearEmbedSessionState(sessionId);
|
|
39466
|
+
}
|
|
38812
39467
|
}
|
|
38813
39468
|
});
|
|
38814
39469
|
const runDreamQueueInBackground = () => {
|
|
@@ -38976,6 +39631,7 @@ function createMagicContextHook(deps) {
|
|
|
38976
39631
|
contextUsageMap,
|
|
38977
39632
|
db,
|
|
38978
39633
|
liveModelBySession,
|
|
39634
|
+
latestAssistantMessageIdBySession,
|
|
38979
39635
|
variantBySession,
|
|
38980
39636
|
agentBySession,
|
|
38981
39637
|
sessionDirectoryBySession,
|
|
@@ -39875,6 +40531,48 @@ function projectIdentityForStoredPath(rawProjectPath) {
|
|
|
39875
40531
|
function memoryBelongsToProject(memory, projectPath) {
|
|
39876
40532
|
return storedPathBelongsToIdentity(memory.projectPath, projectPath);
|
|
39877
40533
|
}
|
|
40534
|
+
function preflightCurateMutation(args) {
|
|
40535
|
+
const { params } = args;
|
|
40536
|
+
if (params.action !== "archive" && params.action !== "update") {
|
|
40537
|
+
return { skip: null, successor: null };
|
|
40538
|
+
}
|
|
40539
|
+
const ids = params.ids;
|
|
40540
|
+
const content = params.content?.trim();
|
|
40541
|
+
if (!ids || ids.length === 0 || !ids.every(Number.isInteger) || params.action === "update" && (ids.length !== 1 || !content)) {
|
|
40542
|
+
return { skip: null, successor: null };
|
|
40543
|
+
}
|
|
40544
|
+
const uniqueIds = [...new Set(ids)];
|
|
40545
|
+
const memories = uniqueIds.map((id) => getMemoryById(args.db, id));
|
|
40546
|
+
if (memories.some((memory) => !memory)) {
|
|
40547
|
+
return { skip: null, successor: null };
|
|
40548
|
+
}
|
|
40549
|
+
const successor = Number.isInteger(params.superseded_by) ? getMemoryById(args.db, params.superseded_by) : null;
|
|
40550
|
+
const refusals = memories.flatMap((memory) => {
|
|
40551
|
+
if (!memory)
|
|
40552
|
+
return [];
|
|
40553
|
+
const refusal = assessCurateMutationSafety({
|
|
40554
|
+
memory,
|
|
40555
|
+
verdict: params.action,
|
|
40556
|
+
reason: params.reason,
|
|
40557
|
+
replacementContent: content,
|
|
40558
|
+
successor,
|
|
40559
|
+
projectIdentity: (candidate) => projectIdentityForStoredPath(candidate.projectPath)
|
|
40560
|
+
});
|
|
40561
|
+
return refusal ? [refusal] : [];
|
|
40562
|
+
});
|
|
40563
|
+
if (refusals.length === 0)
|
|
40564
|
+
return { skip: null, successor };
|
|
40565
|
+
let refused = 0;
|
|
40566
|
+
for (const refusal of refusals) {
|
|
40567
|
+
refused = recordCurateSafetyRefusal(args.sessionId, refusal);
|
|
40568
|
+
}
|
|
40569
|
+
const memoryIds = refusals.map((refusal) => refusal.memoryId).join(", ");
|
|
40570
|
+
const reasons = [...new Set(refusals.map((refusal) => refusal.reason))].join(",");
|
|
40571
|
+
return {
|
|
40572
|
+
skip: `Skipped ${params.action} for memory [ID: ${memoryIds}]: curate safety refusal (${reasons}); refused=${refused}.`,
|
|
40573
|
+
successor
|
|
40574
|
+
};
|
|
40575
|
+
}
|
|
39878
40576
|
function isPrimaryMutableMemory(memory) {
|
|
39879
40577
|
return (memory.status === "active" || memory.status === "permanent") && memory.supersededByMemoryId === null;
|
|
39880
40578
|
}
|
|
@@ -39901,7 +40599,10 @@ var ctxMemoryArgsShape = {
|
|
|
39901
40599
|
limit: tool2.schema.number().optional().describe("Max results for list (default: 10)"),
|
|
39902
40600
|
reason: tool2.schema.string().optional().describe("Why the memory is being archived (optional, recommended)")
|
|
39903
40601
|
};
|
|
39904
|
-
var ctxMemoryArgsSchema = tool2.schema.object(
|
|
40602
|
+
var ctxMemoryArgsSchema = tool2.schema.object({
|
|
40603
|
+
...ctxMemoryArgsShape,
|
|
40604
|
+
superseded_by: tool2.schema.number().optional()
|
|
40605
|
+
}).passthrough();
|
|
39905
40606
|
function createCtxMemoryTool(deps) {
|
|
39906
40607
|
const allowedActions = getAllowedActions(deps);
|
|
39907
40608
|
return tool2({
|
|
@@ -39916,7 +40617,8 @@ function createCtxMemoryTool(deps) {
|
|
|
39916
40617
|
category: { type: "enum", values: V2_MEMORY_CATEGORIES },
|
|
39917
40618
|
ids: { type: "array", items: "number", maxItems: 100 },
|
|
39918
40619
|
limit: "number",
|
|
39919
|
-
reason: "string"
|
|
40620
|
+
reason: "string",
|
|
40621
|
+
superseded_by: "number"
|
|
39920
40622
|
});
|
|
39921
40623
|
if (toolContext.agent === SIDEKICK_AGENT) {
|
|
39922
40624
|
return "Error: ctx_memory is not available to the sidekick agent.";
|
|
@@ -39929,6 +40631,13 @@ function createCtxMemoryTool(deps) {
|
|
|
39929
40631
|
return "Error: Could not resolve project identity for memory action.";
|
|
39930
40632
|
}
|
|
39931
40633
|
await deps.ensureProjectRegistered?.(toolContext.directory, deps.db);
|
|
40634
|
+
const curatePreflight = toolContext.agent === DREAMER_AGENT ? preflightCurateMutation({
|
|
40635
|
+
db: deps.db,
|
|
40636
|
+
params: args,
|
|
40637
|
+
sessionId: toolContext.sessionID
|
|
40638
|
+
}) : { skip: null, successor: null };
|
|
40639
|
+
if (curatePreflight.skip)
|
|
40640
|
+
return curatePreflight.skip;
|
|
39932
40641
|
if (args.action !== "list") {
|
|
39933
40642
|
const marker = getAuthorityManagedMarker(deps.db, projectPath);
|
|
39934
40643
|
let authorityState = null;
|
|
@@ -39951,18 +40660,29 @@ function createCtxMemoryTool(deps) {
|
|
|
39951
40660
|
}
|
|
39952
40661
|
try {
|
|
39953
40662
|
const commandId = toolCallIdFromContext(toolContext);
|
|
40663
|
+
const moduleArgs = args.action === "archive" && curatePreflight.successor ? {
|
|
40664
|
+
action: "merge",
|
|
40665
|
+
ids: [
|
|
40666
|
+
...new Set([
|
|
40667
|
+
...args.ids ?? [],
|
|
40668
|
+
curatePreflight.successor.id
|
|
40669
|
+
])
|
|
40670
|
+
],
|
|
40671
|
+
content: curatePreflight.successor.content,
|
|
40672
|
+
category: curatePreflight.successor.category
|
|
40673
|
+
} : args;
|
|
39954
40674
|
const text = moduleMemoryText(await memoryBackend({
|
|
39955
40675
|
...commandId ? { commandId } : {},
|
|
39956
40676
|
sessionId: toolContext.sessionID,
|
|
39957
40677
|
projectRoot: toolContext.directory,
|
|
39958
40678
|
projectPath,
|
|
39959
40679
|
memoryProject: projectPath,
|
|
39960
|
-
action:
|
|
39961
|
-
content:
|
|
39962
|
-
category:
|
|
39963
|
-
ids:
|
|
39964
|
-
reason:
|
|
39965
|
-
}),
|
|
40680
|
+
action: moduleArgs.action,
|
|
40681
|
+
content: moduleArgs.content,
|
|
40682
|
+
category: moduleArgs.category,
|
|
40683
|
+
ids: moduleArgs.ids,
|
|
40684
|
+
reason: moduleArgs.reason
|
|
40685
|
+
}), moduleArgs);
|
|
39966
40686
|
return text ?? "Error: Rust module returned an invalid ctx_memory response.";
|
|
39967
40687
|
} catch (error) {
|
|
39968
40688
|
if (isRustAuthorityDrainingError(error)) {
|
|
@@ -40241,11 +40961,21 @@ function createCtxMemoryTool(deps) {
|
|
|
40241
40961
|
runImmediateTransaction(deps.db, () => {
|
|
40242
40962
|
for (const target of targets) {
|
|
40243
40963
|
archiveMemory(deps.db, target.memoryId, args.reason);
|
|
40244
|
-
|
|
40245
|
-
|
|
40246
|
-
|
|
40247
|
-
|
|
40248
|
-
|
|
40964
|
+
if (toolContext.agent === DREAMER_AGENT && curatePreflight.successor) {
|
|
40965
|
+
supersededMemory(deps.db, target.memoryId, curatePreflight.successor.id);
|
|
40966
|
+
queueMemoryMutation(deps.db, {
|
|
40967
|
+
projectPath: target.projectIdentity,
|
|
40968
|
+
mutationType: "superseded",
|
|
40969
|
+
targetMemoryId: target.memoryId,
|
|
40970
|
+
supersededById: curatePreflight.successor.id
|
|
40971
|
+
});
|
|
40972
|
+
} else {
|
|
40973
|
+
queueMemoryMutation(deps.db, {
|
|
40974
|
+
projectPath: target.projectIdentity,
|
|
40975
|
+
mutationType: "archive",
|
|
40976
|
+
targetMemoryId: target.memoryId
|
|
40977
|
+
});
|
|
40978
|
+
}
|
|
40249
40979
|
}
|
|
40250
40980
|
});
|
|
40251
40981
|
requestRustMemorySync(deps, toolContext.sessionID);
|
|
@@ -41280,11 +42010,16 @@ function createCtxReduceTool(deps) {
|
|
|
41280
42010
|
const protectedTagIds = activeTags.map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, deps.protectedTags);
|
|
41281
42011
|
const protectedSet = new Set(protectedTagIds);
|
|
41282
42012
|
const tagStatusMap = new Map(allTags.map((tag) => [tag.tagNumber, tag.status]));
|
|
42013
|
+
const inertWhitespaceTagNumbers = new Set(getInertWhitespaceAssistantTags(deps.db, sessionId).map((tag) => tag.tagNumber));
|
|
42014
|
+
const inertDropIds = [
|
|
42015
|
+
...new Set(dropIds.filter((id) => inertWhitespaceTagNumbers.has(id)))
|
|
42016
|
+
];
|
|
42017
|
+
const inertNote = inertDropIds.length > 0 ? `Skipped: ${inertDropIds.map((id) => `§${id}§ is provider framing, nothing to reclaim`).join("; ")}.` : "";
|
|
41283
42018
|
const pendingOps = getPendingOps(deps.db, sessionId);
|
|
41284
42019
|
const pendingMap = new Map(pendingOps.map((op) => [op.tagId, op.operation]));
|
|
41285
42020
|
const conflicts = [];
|
|
41286
42021
|
for (const id of dropIds) {
|
|
41287
|
-
if (tagStatusMap.get(id) === "compacted") {
|
|
42022
|
+
if (tagStatusMap.get(id) === "compacted" && !inertWhitespaceTagNumbers.has(id)) {
|
|
41288
42023
|
conflicts.push(`§${id}§ is from before compaction`);
|
|
41289
42024
|
}
|
|
41290
42025
|
}
|
|
@@ -41292,10 +42027,13 @@ function createCtxReduceTool(deps) {
|
|
|
41292
42027
|
return `Error: Conflicting operations — ${conflicts.join("; ")}.`;
|
|
41293
42028
|
}
|
|
41294
42029
|
const preFilterDropCount = dropIds.length;
|
|
41295
|
-
dropIds = dropIds.filter((id) => tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
|
|
42030
|
+
dropIds = dropIds.filter((id) => !inertWhitespaceTagNumbers.has(id) && tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
|
|
41296
42031
|
const skippedCount = preFilterDropCount - dropIds.length;
|
|
41297
42032
|
if (dropIds.length === 0) {
|
|
41298
|
-
return
|
|
42033
|
+
return [
|
|
42034
|
+
inertNote,
|
|
42035
|
+
"All requested tags were already queued or processed. No new action is needed."
|
|
42036
|
+
].filter(Boolean).join(" ");
|
|
41299
42037
|
}
|
|
41300
42038
|
try {
|
|
41301
42039
|
deps.db.transaction(() => {
|
|
@@ -41318,7 +42056,7 @@ function createCtxReduceTool(deps) {
|
|
|
41318
42056
|
parts.push(`drop ${formatIds(immediateDropIds)}`);
|
|
41319
42057
|
if (deferredDropIds.length > 0)
|
|
41320
42058
|
parts.push(`deferred drop ${formatIds(deferredDropIds)}`);
|
|
41321
|
-
return `Queued: ${parts.join(", ")}.${skippedNote}`;
|
|
42059
|
+
return `Queued: ${parts.join(", ")}.${skippedNote}${inertNote ? ` ${inertNote}` : ""}`;
|
|
41322
42060
|
}
|
|
41323
42061
|
});
|
|
41324
42062
|
}
|
|
@@ -41379,90 +42117,6 @@ function normalizeSources(sources) {
|
|
|
41379
42117
|
}
|
|
41380
42118
|
return result;
|
|
41381
42119
|
}
|
|
41382
|
-
function formatAge2(committedAtMs) {
|
|
41383
|
-
const ageMs = Date.now() - committedAtMs;
|
|
41384
|
-
if (ageMs < 0)
|
|
41385
|
-
return "future";
|
|
41386
|
-
const days = Math.floor(ageMs / (24 * 60 * 60 * 1000));
|
|
41387
|
-
if (days <= 0)
|
|
41388
|
-
return "today";
|
|
41389
|
-
if (days === 1)
|
|
41390
|
-
return "1d ago";
|
|
41391
|
-
if (days < 30)
|
|
41392
|
-
return `${days}d ago`;
|
|
41393
|
-
const months = Math.floor(days / 30);
|
|
41394
|
-
if (months === 1)
|
|
41395
|
-
return "1mo ago";
|
|
41396
|
-
if (months < 12)
|
|
41397
|
-
return `${months}mo ago`;
|
|
41398
|
-
const years = Math.floor(days / 365);
|
|
41399
|
-
return years === 1 ? "1y ago" : `${years}y ago`;
|
|
41400
|
-
}
|
|
41401
|
-
var NOTE_EXPAND_HINT = "Use ctx_expand(start=N-10, end=N) around any note @msg anchor above to read the surrounding conversation context.";
|
|
41402
|
-
function formatResult(result, index, currentSessionId) {
|
|
41403
|
-
if (result.source === "memory") {
|
|
41404
|
-
const source = result.sourceName ? ` source=${result.sourceName}` : "";
|
|
41405
|
-
return [
|
|
41406
|
-
`[${index}] [memory] score=${result.score.toFixed(2)} id=${result.memoryId} category=${result.category}${source} match=${result.matchType}`,
|
|
41407
|
-
result.content
|
|
41408
|
-
].join(`
|
|
41409
|
-
`);
|
|
41410
|
-
}
|
|
41411
|
-
if (result.source === "git_commit") {
|
|
41412
|
-
return [
|
|
41413
|
-
`[${index}] [git_commit] score=${result.score.toFixed(2)} sha=${result.shortSha} ${formatAge2(result.committedAtMs)} match=${result.matchType}`,
|
|
41414
|
-
result.content
|
|
41415
|
-
].join(`
|
|
41416
|
-
`);
|
|
41417
|
-
}
|
|
41418
|
-
if (result.source === "primer") {
|
|
41419
|
-
return [
|
|
41420
|
-
`[${index}] [primer] score=${result.score.toFixed(2)} id=${result.primerId} support=${result.support} match=${result.matchType}`,
|
|
41421
|
-
result.content
|
|
41422
|
-
].join(`
|
|
41423
|
-
`);
|
|
41424
|
-
}
|
|
41425
|
-
if (result.source === "note") {
|
|
41426
|
-
const anchor = result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId ? ` @msg ${result.anchorOrdinal}` : "";
|
|
41427
|
-
return [
|
|
41428
|
-
`[${index}] [note] score=${result.score.toFixed(2)} id=#${result.noteId} status=${result.status} ${formatAge2(result.createdAt)}${anchor}`,
|
|
41429
|
-
result.content
|
|
41430
|
-
].join(`
|
|
41431
|
-
`);
|
|
41432
|
-
}
|
|
41433
|
-
if (result.source === "compartment") {
|
|
41434
|
-
return [
|
|
41435
|
-
`[${index}] [message] score=${result.score.toFixed(2)} compartment_id=${result.compartmentId} range=${result.startOrdinal}-${result.endOrdinal} match=${result.matchType} title=${result.title}`,
|
|
41436
|
-
result.snippet ? `Snippet: ${result.snippet}` : result.content
|
|
41437
|
-
].join(`
|
|
41438
|
-
`);
|
|
41439
|
-
}
|
|
41440
|
-
const expandStart = Math.max(1, result.messageOrdinal - 3);
|
|
41441
|
-
const expandEnd = result.messageOrdinal + 3;
|
|
41442
|
-
return [
|
|
41443
|
-
`[${index}] [message] score=${result.score.toFixed(2)} ordinal=${result.messageOrdinal} range=${expandStart}-${expandEnd} role=${result.role}`,
|
|
41444
|
-
result.content
|
|
41445
|
-
].join(`
|
|
41446
|
-
`);
|
|
41447
|
-
}
|
|
41448
|
-
function formatSearchResults(query, results, currentSessionId) {
|
|
41449
|
-
if (results.length === 0) {
|
|
41450
|
-
return `No results found for "${query}" across notes, memories, primers, git commits, or message history.`;
|
|
41451
|
-
}
|
|
41452
|
-
const bodyParts = results.map((result, index) => formatResult(result, index + 1, currentSessionId));
|
|
41453
|
-
if (results.some((result) => result.source === "message" || result.source === "compartment")) {
|
|
41454
|
-
bodyParts.push("Use ctx_expand(start, end) with the range from any message result above to read the full conversation context.");
|
|
41455
|
-
}
|
|
41456
|
-
if (results.some((result) => result.source === "note" && result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId)) {
|
|
41457
|
-
bodyParts.push(NOTE_EXPAND_HINT);
|
|
41458
|
-
}
|
|
41459
|
-
const body = bodyParts.join(`
|
|
41460
|
-
|
|
41461
|
-
`);
|
|
41462
|
-
return `Found ${results.length} result${results.length === 1 ? "" : "s"} for "${query}":
|
|
41463
|
-
|
|
41464
|
-
${body}`;
|
|
41465
|
-
}
|
|
41466
42120
|
var ctxSearchArgsShape = {
|
|
41467
42121
|
query: tool5.schema.string().optional().describe("Search query. Matches against memory content, Primers, git commit messages, and raw user/assistant message text."),
|
|
41468
42122
|
limit: tool5.schema.number().optional().describe("Maximum results to return (default: 10)"),
|
|
@@ -41493,6 +42147,7 @@ function createCtxSearchTool(deps) {
|
|
|
41493
42147
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, toolContext.sessionID);
|
|
41494
42148
|
const messageOrdinalCutoff = lastCompartmentEnd >= 0 ? lastCompartmentEnd : 0;
|
|
41495
42149
|
const visibleMemoryIds = getVisibleMemoryIds(deps.db, toolContext.sessionID);
|
|
42150
|
+
const diagnostics = createUnifiedSearchDiagnostics();
|
|
41496
42151
|
const projectPath = deps.resolveProjectPath(toolContext.directory);
|
|
41497
42152
|
if (!projectPath) {
|
|
41498
42153
|
return "Error: Could not resolve project identity for search.";
|
|
@@ -41509,10 +42164,11 @@ function createCtxSearchTool(deps) {
|
|
|
41509
42164
|
projectPath,
|
|
41510
42165
|
ids: idShape,
|
|
41511
42166
|
limit: Math.max(normalizeLimit3(args.limit), idShape.length),
|
|
41512
|
-
visibleMemoryIds
|
|
42167
|
+
visibleMemoryIds,
|
|
42168
|
+
diagnostics
|
|
41513
42169
|
});
|
|
41514
|
-
if (idResults !== null) {
|
|
41515
|
-
return formatSearchResults(query, idResults, toolContext.sessionID);
|
|
42170
|
+
if (idResults !== null || diagnostics.suppressedVisibleMemoryIds.length > 0) {
|
|
42171
|
+
return formatSearchResults(query, idResults ?? [], toolContext.sessionID, diagnostics);
|
|
41516
42172
|
}
|
|
41517
42173
|
}
|
|
41518
42174
|
const results = await unifiedSearch(deps.db, toolContext.sessionID, projectPath, query, {
|
|
@@ -41529,9 +42185,11 @@ function createCtxSearchTool(deps) {
|
|
|
41529
42185
|
gitCommitsEnabled,
|
|
41530
42186
|
sources: normalizeSources(args.sources),
|
|
41531
42187
|
visibleMemoryIds,
|
|
42188
|
+
diagnostics,
|
|
42189
|
+
gitRepositoryAvailable: typeof toolContext.directory === "string" ? directoryHasGitMetadata(toolContext.directory) : undefined,
|
|
41532
42190
|
explicitSearch: true
|
|
41533
42191
|
});
|
|
41534
|
-
return formatSearchResults(query, results, toolContext.sessionID);
|
|
42192
|
+
return formatSearchResults(query, results, toolContext.sessionID, diagnostics);
|
|
41535
42193
|
}
|
|
41536
42194
|
});
|
|
41537
42195
|
}
|
|
@@ -41945,6 +42603,7 @@ var server = async (ctx) => {
|
|
|
41945
42603
|
});
|
|
41946
42604
|
const loadedPluginConfig = loadPluginConfigDetailed(ctx.directory);
|
|
41947
42605
|
const pluginConfig = loadedPluginConfig.config;
|
|
42606
|
+
reloadWindowOverlay(pluginConfig.models?.window_overlay_path);
|
|
41948
42607
|
const promptSurfaceRuntime = createPromptSurfaceRuntime({
|
|
41949
42608
|
harness: "opencode",
|
|
41950
42609
|
directory: ctx.directory,
|
|
@@ -41980,7 +42639,7 @@ var server = async (ctx) => {
|
|
|
41980
42639
|
`);
|
|
41981
42640
|
setTimeout(async () => {
|
|
41982
42641
|
try {
|
|
41983
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
42642
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
|
|
41984
42643
|
const clientWithSessions = ctx.client;
|
|
41985
42644
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
41986
42645
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -42009,7 +42668,9 @@ var server = async (ctx) => {
|
|
|
42009
42668
|
}
|
|
42010
42669
|
}
|
|
42011
42670
|
const liveSessionState = createLiveSessionState();
|
|
42012
|
-
const
|
|
42671
|
+
const rustModeModuleTransport = pluginConfig.transform_mode === "rust" ? new SubcModuleTransport(pluginConfig.subc?.connection_file) : undefined;
|
|
42672
|
+
const rustModeModuleClient = rustModeModuleTransport;
|
|
42673
|
+
const sessionCleanupModuleClient = pluginConfig.enabled ? rustModeModuleTransport ?? new SubcModuleTransport(pluginConfig.subc?.connection_file) : undefined;
|
|
42013
42674
|
const hooks = await createSessionHooksAsync({
|
|
42014
42675
|
ctx,
|
|
42015
42676
|
pluginConfig,
|
|
@@ -42149,7 +42810,8 @@ var server = async (ctx) => {
|
|
|
42149
42810
|
liveSessionState.dreamerProgressByProject.delete(timerProjectIdentity);
|
|
42150
42811
|
}
|
|
42151
42812
|
},
|
|
42152
|
-
moduleClient: classifyModuleClient
|
|
42813
|
+
moduleClient: classifyModuleClient,
|
|
42814
|
+
sessionCleanupModuleClient
|
|
42153
42815
|
};
|
|
42154
42816
|
try {
|
|
42155
42817
|
stopDreamTimerRegistration = await startDreamScheduleTimer(timerRegistration);
|
|
@@ -42173,7 +42835,7 @@ var server = async (ctx) => {
|
|
|
42173
42835
|
{
|
|
42174
42836
|
const fence = getSchemaFenceRejection();
|
|
42175
42837
|
if (fence) {
|
|
42176
|
-
import("./conflict-warning-hook-
|
|
42838
|
+
import("./conflict-warning-hook-rf17b6et.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
|
|
42177
42839
|
}
|
|
42178
42840
|
}
|
|
42179
42841
|
if (conflictResult?.hasConflict) {
|
|
@@ -42194,7 +42856,7 @@ var server = async (ctx) => {
|
|
|
42194
42856
|
} = await import("./announcement-3g9xg433.js");
|
|
42195
42857
|
if (shouldShowAnnouncement2()) {
|
|
42196
42858
|
setTimeout(() => {
|
|
42197
|
-
import("./conflict-warning-hook-
|
|
42859
|
+
import("./conflict-warning-hook-rf17b6et.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
|
|
42198
42860
|
}, 8000);
|
|
42199
42861
|
}
|
|
42200
42862
|
} catch {}
|