feature(event-sourcing): baseline for the architecture review fixes.

- fixed the tool overlay in tui.
- fixed tool calling - added schemas.
- getting all sessionIds via event store.
- instead of sending all events on the replay - there's a new way for replaying.
- session snapshot is now a thing getting sent for previously created sessions.
- added logging to important parts.
- revert workflowId from WorkflowCompletedEvent.
This commit is contained in:
2026-05-24 18:50:00 +04:00
parent f827685ed0
commit fc7b879891
43 changed files with 525 additions and 211 deletions
@@ -63,6 +63,8 @@ class InMemoryEventStore : EventStore {
.flatMap { stream -> synchronized(stream) { stream.toList() } }
.asSequence()
override fun allSessionIds(): Set<SessionId> = sequences.keys
private fun doAppend(event: NewEvent, stream: MutableList<StoredEvent>): StoredEvent {
val seq = sequences.computeIfAbsent(event.metadata.sessionId) { AtomicLong(0) }
.incrementAndGet()
@@ -42,7 +42,7 @@ class SqliteEventStore(
correlation_id TEXT,
payload TEXT NOT NULL
);
""".trimIndent()
""".trimIndent(),
)
}
}
@@ -60,7 +60,7 @@ class SqliteEventStore(
val s = StoredEvent(
metadata = event.metadata,
sequence = seq,
payload = event.payload
payload = event.payload,
)
insert(s)
@@ -91,7 +91,7 @@ class SqliteEventStore(
val s = StoredEvent(
metadata = event.metadata,
sequence = seq,
payload = event.payload
payload = event.payload,
)
insert(s)
@@ -111,7 +111,7 @@ class SqliteEventStore(
SELECT * FROM events
WHERE session_id = ?
ORDER BY sequence ASC
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, sessionId.value)
@@ -131,7 +131,7 @@ class SqliteEventStore(
WHERE session_id = ?
AND sequence > ?
ORDER BY sequence ASC
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, sessionId.value)
ps.setLong(2, fromSequence)
@@ -151,7 +151,7 @@ class SqliteEventStore(
SELECT MAX(sequence)
FROM events
WHERE session_id = ?
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, sessionId.value)
@@ -169,7 +169,7 @@ class SqliteEventStore(
"""
SELECT * FROM events
ORDER BY session_id ASC, sequence ASC
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.executeQuery().use { rs ->
buildList {
@@ -180,6 +180,15 @@ class SqliteEventStore(
}
}.asSequence()
override fun allSessionIds(): Set<SessionId> =
mutableSetOf<SessionId>().apply {
connection.prepareStatement("SELECT DISTINCT session_id FROM events").use { ps ->
ps.executeQuery().use { rs ->
while (rs.next()) add(SessionId(rs.getString("session_id")))
}
}
}
// ---------- helpers ----------
private fun nextSequence(sessionId: SessionId): Long =
@@ -188,7 +197,7 @@ class SqliteEventStore(
SELECT COALESCE(MAX(sequence), 0)
FROM events
WHERE session_id = ?
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, sessionId.value)
ps.executeQuery().use { rs ->
@@ -211,7 +220,7 @@ class SqliteEventStore(
correlation_id,
payload
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, event.metadata.eventId.value)
ps.setString(2, event.metadata.sessionId.value)
@@ -231,7 +240,7 @@ class SqliteEventStore(
"""
SELECT * FROM events
WHERE event_id = ?
""".trimIndent()
""".trimIndent(),
).use { ps ->
ps.setString(1, eventId.value)
@@ -250,8 +259,8 @@ private fun ResultSet.toStoredEvent(jsonSerializer: JsonEventSerializer): Stored
timestamp = Instant.parse(getString("timestamp")),
schemaVersion = getInt("schema_version"),
causationId = getString("causation_id")?.let { CausationId(it) },
correlationId = getString("correlation_id")?.let { CorrelationId(it) }
correlationId = getString("correlation_id")?.let { CorrelationId(it) },
),
sequence = getLong("sequence"),
payload = jsonSerializer.deserialize(getString("payload"))
payload = jsonSerializer.deserialize(getString("payload")),
)