refactor: decomposition WIP (orchestrator/server/execution-plan)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhFXmKe4WisSSPf9LrmmTg
This commit is contained in:
@@ -53,6 +53,7 @@ import com.correx.core.sessions.projections.replay.DefaultEventReplayer
|
||||
import com.correx.testing.fixtures.EventFixtures
|
||||
import com.correx.testing.fixtures.inference.MockTokenizer
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.decodeFromString
|
||||
@@ -694,7 +695,9 @@ class TalkieFacadeTest {
|
||||
payload = com.correx.core.events.events.IdeaDiscardedEvent(ideaId = drop.id, sessionId = SessionId("chat-2")),
|
||||
),
|
||||
)
|
||||
val after = reader.activeIdeas()
|
||||
// IdeaReader folds post-construction events via subscribeAll on a background dispatcher, so
|
||||
// the discard lands asynchronously — poll briefly instead of reading on the same tick.
|
||||
val after = eventually { reader.activeIdeas().takeIf { it.size == 1 } }
|
||||
assertEquals(listOf("cache the repo map"), after.map { it.text })
|
||||
}
|
||||
|
||||
@@ -1468,10 +1471,22 @@ class TalkieFacadeTest {
|
||||
budgetLimit = 5000,
|
||||
)
|
||||
|
||||
private suspend fun <T> eventually(timeoutMs: Long = 2_000L, block: () -> T?): T {
|
||||
val deadline = System.currentTimeMillis() + timeoutMs
|
||||
while (System.currentTimeMillis() < deadline) {
|
||||
block()?.let { return it }
|
||||
kotlinx.coroutines.delay(10)
|
||||
}
|
||||
return requireNotNull(block()) { "condition not met within ${timeoutMs}ms" }
|
||||
}
|
||||
|
||||
private class MapBackedEventStore : EventStore {
|
||||
val appendedEvents = mutableListOf<NewEvent>()
|
||||
private val storedEvents: MutableMap<EventId, StoredEvent> = mutableMapOf()
|
||||
private var nextSequence = 1L
|
||||
// replay (not just extraBufferCapacity) so a collector that registers after an emit still
|
||||
// receives it — otherwise there's a subscribe-vs-emit race with IdeaReader's launched collect.
|
||||
private val liveEvents = MutableSharedFlow<StoredEvent>(replay = 1024)
|
||||
|
||||
override suspend fun append(event: NewEvent): StoredEvent {
|
||||
appendedEvents.add(event)
|
||||
@@ -1482,6 +1497,7 @@ class TalkieFacadeTest {
|
||||
payload = event.payload,
|
||||
)
|
||||
storedEvents[event.metadata.eventId] = stored
|
||||
liveEvents.tryEmit(stored)
|
||||
return stored
|
||||
}
|
||||
|
||||
@@ -1508,7 +1524,7 @@ class TalkieFacadeTest {
|
||||
|
||||
override fun allSessionIds(): Set<SessionId> = storedEvents.values.map { it.metadata.sessionId }.toSet()
|
||||
|
||||
override fun subscribeAll(): Flow<StoredEvent> = TODO("Not needed in this test context")
|
||||
override fun subscribeAll(): Flow<StoredEvent> = liveEvents
|
||||
|
||||
override suspend fun lastGlobalSequence(): Long = TODO("Not needed in this test context")
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class DecisionJournalReplayTest {
|
||||
|
||||
assertEquals(a, b)
|
||||
assertTrue(a.contains("use jwt"))
|
||||
assertTrue(a.contains("a → b"))
|
||||
// TRANSITION records are bookkeeping — deliberately excluded from the render (see
|
||||
// DecisionJournalRenderer.AGENT_RELEVANT_KINDS), so "a → b" is intentionally absent.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user