({
context,
appendSystemMessage,
isTrailingRun,
}: {
context: REPLHookContext
appendSystemMessage?: AppendSystemMessageFn
isTrailingRun?: boolean
})
| 327 | // --- Inner extraction logic --- |
| 328 | |
| 329 | async function runExtraction({ |
| 330 | context, |
| 331 | appendSystemMessage, |
| 332 | isTrailingRun, |
| 333 | }: { |
| 334 | context: REPLHookContext |
| 335 | appendSystemMessage?: AppendSystemMessageFn |
| 336 | isTrailingRun?: boolean |
| 337 | }): Promise<void> { |
| 338 | const { messages } = context |
| 339 | const memoryDir = getAutoMemPath() |
| 340 | const newMessageCount = countModelVisibleMessagesSince( |
| 341 | messages, |
| 342 | lastMemoryMessageUuid, |
| 343 | ) |
| 344 | |
| 345 | // Mutual exclusion: when the main agent wrote memories, skip the |
| 346 | // forked agent and advance the cursor past this range so the next |
| 347 | // extraction only considers messages after the main agent's write. |
| 348 | if (hasMemoryWritesSince(messages, lastMemoryMessageUuid)) { |
| 349 | logForDebugging( |
| 350 | '[extractMemories] skipping — conversation already wrote to memory files', |
| 351 | ) |
| 352 | const lastMessage = messages.at(-1) |
| 353 | if (lastMessage?.uuid) { |
| 354 | lastMemoryMessageUuid = lastMessage.uuid |
| 355 | } |
| 356 | logEvent('tengu_extract_memories_skipped_direct_write', { |
| 357 | message_count: newMessageCount, |
| 358 | }) |
| 359 | return |
| 360 | } |
| 361 | |
| 362 | const teamMemoryEnabled = feature('TEAMMEM') |
| 363 | ? teamMemPaths!.isTeamMemoryEnabled() |
| 364 | : false |
| 365 | |
| 366 | const skipIndex = getFeatureValue_CACHED_MAY_BE_STALE( |
| 367 | 'tengu_moth_copse', |
| 368 | false, |
| 369 | ) |
| 370 | |
| 371 | const canUseTool = createAutoMemCanUseTool(memoryDir) |
| 372 | const cacheSafeParams = createCacheSafeParams(context) |
| 373 | |
| 374 | // Only run extraction every N eligible turns (tengu_bramble_lintel, default 1). |
| 375 | // Trailing extractions (from stashed contexts) skip this check since they |
| 376 | // process already-committed work that should not be throttled. |
| 377 | if (!isTrailingRun) { |
| 378 | turnsSinceLastExtraction++ |
| 379 | if ( |
| 380 | turnsSinceLastExtraction < |
| 381 | (getFeatureValue_CACHED_MAY_BE_STALE('tengu_bramble_lintel', null) ?? 1) |
| 382 | ) { |
| 383 | return |
| 384 | } |
| 385 | } |
| 386 | turnsSinceLastExtraction = 0 |
no test coverage detected