Изменения вводят live-канал OnlineOutbox и фоновую синхронизацию диалогов.
This commit is contained in:
@@ -5,6 +5,7 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertIs
|
||||
import kotlin.test.assertTrue
|
||||
import pw.binom.agentik.outbox.Event
|
||||
import pw.binom.agentik.outbox.OnlineEvent
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
@@ -13,8 +14,14 @@ class LiveTurnTest {
|
||||
private val now = Clock.System.now()
|
||||
private fun at() = Instant.fromEpochMilliseconds(now.toEpochMilliseconds())
|
||||
|
||||
private fun LiveTurn.feed(vararg events: Event) {
|
||||
events.forEach { apply(it) }
|
||||
private fun LiveTurn.feed(vararg events: Any) {
|
||||
events.forEach {
|
||||
when (it) {
|
||||
is Event -> apply(it)
|
||||
is OnlineEvent -> applyOnline(it)
|
||||
else -> error("unexpected event: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -22,12 +29,12 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartReasoning(at()),
|
||||
Event.AppendText(at(), "сначала "),
|
||||
Event.AppendText(at(), "подумаем"),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
Event.AppendText(at(), "Привет, "),
|
||||
Event.AppendText(at(), "мир!"),
|
||||
OnlineEvent.StartReasoning(at()),
|
||||
OnlineEvent.AppendText(at(), "сначала "),
|
||||
OnlineEvent.AppendText(at(), "подумаем"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
OnlineEvent.AppendText(at(), "Привет, "),
|
||||
OnlineEvent.AppendText(at(), "мир!"),
|
||||
Event.End(at()),
|
||||
)
|
||||
|
||||
@@ -46,7 +53,7 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
Event.ToolCall(at(), id = "t1", title = "grep", toolName = "grep", toolArgs = "{\"q\":\"x\"}"),
|
||||
Event.ToolResult(at(), toolCallId = "t1", toolName = "grep", result = "found 3"),
|
||||
Event.End(at()),
|
||||
@@ -66,7 +73,7 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
Event.ToolResult(at(), toolCallId = "missing", toolName = null, result = "ok"),
|
||||
)
|
||||
|
||||
@@ -94,8 +101,8 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
Event.AppendText(at(), "partial"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
OnlineEvent.AppendText(at(), "partial"),
|
||||
Event.Error(at(), message = "llm down", code = "E500"),
|
||||
)
|
||||
|
||||
@@ -112,8 +119,8 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
Event.AppendText(at(), "не до конца"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
OnlineEvent.AppendText(at(), "не до конца"),
|
||||
Event.Interrupted(at()),
|
||||
)
|
||||
|
||||
@@ -127,10 +134,10 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
Event.AppendText(at(), "до"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
OnlineEvent.AppendText(at(), "до"),
|
||||
Event.ToolCall(at(), id = "t1", title = null, toolName = "grep", toolArgs = "{}"),
|
||||
Event.AppendText(at(), "после"),
|
||||
OnlineEvent.AppendText(at(), "после"),
|
||||
)
|
||||
|
||||
val answers = turn.blocks.filterIsInstance<LiveBlock.Answer>()
|
||||
@@ -146,8 +153,8 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.IMAGE),
|
||||
Event.AppendImage(at(), body = bytes, mime = "image/png"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.IMAGE),
|
||||
OnlineEvent.AppendImage(at(), body = bytes, mime = "image/png"),
|
||||
Event.End(at()),
|
||||
)
|
||||
|
||||
@@ -162,11 +169,11 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.StartResponse(at(), Event.ResponseType.TEXT),
|
||||
Event.AppendText(at(), "старое"),
|
||||
OnlineEvent.StartResponse(at(), OnlineEvent.ResponseType.TEXT),
|
||||
OnlineEvent.AppendText(at(), "старое"),
|
||||
Event.End(at()),
|
||||
)
|
||||
turn.feed(Event.Working(at()), Event.AppendText(at(), "новое"))
|
||||
turn.feed(Event.Working(at()), OnlineEvent.AppendText(at(), "новое"))
|
||||
|
||||
assertEquals(1, turn.blocks.size)
|
||||
assertEquals("новое", turn.answerText())
|
||||
@@ -175,7 +182,7 @@ class LiveTurnTest {
|
||||
@Test
|
||||
fun `append without explicit start response still streams as answer`() {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(Event.Working(at()), Event.AppendText(at(), "без старта"))
|
||||
turn.feed(Event.Working(at()), OnlineEvent.AppendText(at(), "без старта"))
|
||||
|
||||
assertEquals(TurnPhase.RESPONDING, turn.phase)
|
||||
assertEquals("без старта", turn.answerText())
|
||||
@@ -186,7 +193,7 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
var count = 0
|
||||
turn.onChange = { count++ }
|
||||
turn.feed(Event.Working(at()), Event.AppendText(at(), "x"))
|
||||
turn.feed(Event.Working(at()), OnlineEvent.AppendText(at(), "x"))
|
||||
|
||||
assertEquals(2, count)
|
||||
}
|
||||
@@ -196,12 +203,12 @@ class LiveTurnTest {
|
||||
val turn = LiveTurn()
|
||||
turn.feed(
|
||||
Event.Working(at()),
|
||||
Event.AppendText(at(), "Первая строка\n\nвторая строка "),
|
||||
OnlineEvent.AppendText(at(), "Первая строка\n\nвторая строка "),
|
||||
)
|
||||
assertEquals("Первая строка вторая строка", turn.previewText())
|
||||
|
||||
val long = LiveTurn()
|
||||
long.feed(Event.Working(at()), Event.AppendText(at(), "слово ".repeat(60)))
|
||||
long.feed(Event.Working(at()), OnlineEvent.AppendText(at(), "слово ".repeat(60)))
|
||||
val preview = long.previewText(maxLength = 30)
|
||||
assertTrue(preview.length <= 31)
|
||||
assertTrue(preview.endsWith("…"))
|
||||
|
||||
Reference in New Issue
Block a user