AG-UI as in-process KMP API with Ktor client/server transports #1

Merged
subochev merged 2 commits from feat/agui-kmp into main 2026-09-09 20:44:11 +00:00
24 changed files with 203 additions and 171 deletions
Showing only changes of commit 4ca54a9b05 - Show all commits
+8
View File
@@ -6,6 +6,14 @@ plugins {
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
jvm() jvm()
Review

Добавь цели сборки все возможные. mac цели тоже. android не надо, jvm цель и так его покроет

Добавь цели сборки все возможные. mac цели тоже. android не надо, jvm цель и так его покроет
macosX64()
macosArm64()
iosX64()
iosArm64()
iosSimulatorArm64()
linuxX64()
linuxArm64()
mingwX64()
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
@@ -1,14 +1,14 @@
package com.agui.api.agent package pw.binom.agui.api.agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.api.run.RunAgentParameters import pw.binom.agui.api.run.RunAgentParameters
import com.agui.api.run.randomRunId import pw.binom.agui.api.run.randomRunId
import com.agui.api.run.toParameters import pw.binom.agui.api.run.toParameters
import com.agui.api.run.toRunAgentInput import pw.binom.agui.api.run.toRunAgentInput
import com.agui.api.state.State import pw.binom.agui.api.state.State
import com.agui.api.state.mutableState import pw.binom.agui.api.state.mutableState
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
/** /**
@@ -1,7 +1,7 @@
package com.agui.api.agent package pw.binom.agui.api.agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
/** /**
@@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow
* *
* This is the network-agnostic heart of the protocol. A concrete [Agent] can be: * This is the network-agnostic heart of the protocol. A concrete [Agent] can be:
* *
* - remote — [com.agui.client.HttpAgent] streams events over SSE; * - remote — [pw.binom.agui.client.HttpAgent] streams events over SSE;
* - local — a real agent implementation; * - local — a real agent implementation;
* - composed/decorated — logging, auth, retry, observability wrappers. * - composed/decorated — logging, auth, retry, observability wrappers.
*/ */
@@ -1,23 +1,23 @@
package com.agui.api.agent package pw.binom.agui.api.agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.CustomEvent import pw.binom.agui.api.event.CustomEvent
import com.agui.api.event.MessagesSnapshotEvent import pw.binom.agui.api.event.MessagesSnapshotEvent
import com.agui.api.event.RawEvent import pw.binom.agui.api.event.RawEvent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateDeltaEvent import pw.binom.agui.api.event.StateDeltaEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.StepFinishedEvent import pw.binom.agui.api.event.StepFinishedEvent
import com.agui.api.event.StepStartedEvent import pw.binom.agui.api.event.StepStartedEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.event.ToolCallArgsEvent import pw.binom.agui.api.event.ToolCallArgsEvent
import com.agui.api.event.ToolCallEndEvent import pw.binom.agui.api.event.ToolCallEndEvent
import com.agui.api.event.ToolCallResultEvent import pw.binom.agui.api.event.ToolCallResultEvent
import com.agui.api.event.ToolCallStartEvent import pw.binom.agui.api.event.ToolCallStartEvent
/** /**
* Observer for a stream of [BaseEvent]s. * Observer for a stream of [BaseEvent]s.
@@ -1,23 +1,23 @@
package com.agui.api.agent package pw.binom.agui.api.agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.CustomEvent import pw.binom.agui.api.event.CustomEvent
import com.agui.api.event.MessagesSnapshotEvent import pw.binom.agui.api.event.MessagesSnapshotEvent
import com.agui.api.event.RawEvent import pw.binom.agui.api.event.RawEvent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateDeltaEvent import pw.binom.agui.api.event.StateDeltaEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.StepFinishedEvent import pw.binom.agui.api.event.StepFinishedEvent
import com.agui.api.event.StepStartedEvent import pw.binom.agui.api.event.StepStartedEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.event.ToolCallArgsEvent import pw.binom.agui.api.event.ToolCallArgsEvent
import com.agui.api.event.ToolCallEndEvent import pw.binom.agui.api.event.ToolCallEndEvent
import com.agui.api.event.ToolCallResultEvent import pw.binom.agui.api.event.ToolCallResultEvent
import com.agui.api.event.ToolCallStartEvent import pw.binom.agui.api.event.ToolCallStartEvent
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
/** /**
@@ -1,4 +1,4 @@
package com.agui.api.context package pw.binom.agui.api.context
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -1,8 +1,8 @@
package com.agui.api.event package pw.binom.agui.api.event
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.message.MessageRole import pw.binom.agui.api.message.MessageRole
import com.agui.api.state.State import pw.binom.agui.api.state.State
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
@@ -14,6 +14,7 @@ import kotlinx.serialization.json.JsonElement
* subclasses mirror the AG-UI protocol event catalogue and are (de)serialized * subclasses mirror the AG-UI protocol event catalogue and are (de)serialized
* polymorphically by the `type` discriminator field. * polymorphically by the `type` discriminator field.
*/ */
@Serializable
public sealed interface BaseEvent { public sealed interface BaseEvent {
/** Event creation timestamp in epoch milliseconds, if provided. */ /** Event creation timestamp in epoch milliseconds, if provided. */
@@ -1,4 +1,4 @@
package com.agui.api.message package pw.binom.agui.api.message
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -1,9 +1,9 @@
package com.agui.api.run package pw.binom.agui.api.run
import com.agui.api.context.Context import pw.binom.agui.api.context.Context
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.state.State import pw.binom.agui.api.state.State
import com.agui.api.tool.Tool import pw.binom.agui.api.tool.Tool
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlin.random.Random import kotlin.random.Random
@@ -1,23 +1,23 @@
package com.agui.api.serialization package pw.binom.agui.api.serialization
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.CustomEvent import pw.binom.agui.api.event.CustomEvent
import com.agui.api.event.MessagesSnapshotEvent import pw.binom.agui.api.event.MessagesSnapshotEvent
import com.agui.api.event.RawEvent import pw.binom.agui.api.event.RawEvent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateDeltaEvent import pw.binom.agui.api.event.StateDeltaEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.StepFinishedEvent import pw.binom.agui.api.event.StepFinishedEvent
import com.agui.api.event.StepStartedEvent import pw.binom.agui.api.event.StepStartedEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.event.ToolCallArgsEvent import pw.binom.agui.api.event.ToolCallArgsEvent
import com.agui.api.event.ToolCallEndEvent import pw.binom.agui.api.event.ToolCallEndEvent
import com.agui.api.event.ToolCallResultEvent import pw.binom.agui.api.event.ToolCallResultEvent
import com.agui.api.event.ToolCallStartEvent import pw.binom.agui.api.event.ToolCallStartEvent
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.polymorphic
@@ -1,10 +1,10 @@
package com.agui.api.state package pw.binom.agui.api.state
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
/** /**
* A loosely-typed, platform-agnostic bag of agent state carried in AG-UI * A loosely-typed, platform-agnostic bag of agent state carried in AG-UI
* `STATE_SNAPSHOT`/`STATE_DELTA` events and in [com.agui.api.run.RunAgentInput.state]. * `STATE_SNAPSHOT`/`STATE_DELTA` events and in [pw.binom.agui.api.run.RunAgentInput.state].
* *
* Because the value is a JSON element, it can be any JSON scalar, object or array — the * Because the value is a JSON element, it can be any JSON scalar, object or array — the
* protocol does not prescribe a concrete schema. * protocol does not prescribe a concrete schema.
@@ -1,4 +1,4 @@
package com.agui.api.tool package pw.binom.agui.api.tool
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
@@ -1,19 +1,19 @@
package com.agui.api package pw.binom.agui.api
import com.agui.api.agent.AbstractAgent import pw.binom.agui.api.agent.AbstractAgent
import com.agui.api.agent.AgentSubscriber import pw.binom.agui.api.agent.AgentSubscriber
import com.agui.api.agent.EventDispatcher import pw.binom.agui.api.agent.EventDispatcher
import com.agui.api.agent.dispatchTo import pw.binom.agui.api.agent.dispatchTo
import com.agui.api.context.Context import pw.binom.agui.api.context.Context
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.CustomEvent import pw.binom.agui.api.event.CustomEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.api.run.RunAgentParameters import pw.binom.agui.api.run.RunAgentParameters
import com.agui.api.run.randomRunId import pw.binom.agui.api.run.randomRunId
import com.agui.api.run.toParameters import pw.binom.agui.api.run.toParameters
import com.agui.api.run.toRunAgentInput import pw.binom.agui.api.run.toRunAgentInput
import com.agui.api.tool.Tool import pw.binom.agui.api.tool.Tool
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
@@ -1,27 +1,27 @@
package com.agui.api package pw.binom.agui.api
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.CustomEvent import pw.binom.agui.api.event.CustomEvent
import com.agui.api.event.MessagesSnapshotEvent import pw.binom.agui.api.event.MessagesSnapshotEvent
import com.agui.api.event.RawEvent import pw.binom.agui.api.event.RawEvent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateDeltaEvent import pw.binom.agui.api.event.StateDeltaEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.StepFinishedEvent import pw.binom.agui.api.event.StepFinishedEvent
import com.agui.api.event.StepStartedEvent import pw.binom.agui.api.event.StepStartedEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.event.ToolCallArgsEvent import pw.binom.agui.api.event.ToolCallArgsEvent
import com.agui.api.event.ToolCallEndEvent import pw.binom.agui.api.event.ToolCallEndEvent
import com.agui.api.event.ToolCallResultEvent import pw.binom.agui.api.event.ToolCallResultEvent
import com.agui.api.event.ToolCallStartEvent import pw.binom.agui.api.event.ToolCallStartEvent
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.message.MessageRole import pw.binom.agui.api.message.MessageRole
import com.agui.api.serialization.AguiJson import pw.binom.agui.api.serialization.AguiJson
import com.agui.api.state.mutableState import pw.binom.agui.api.state.mutableState
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.JsonPrimitive
+1 -1
View File
@@ -4,6 +4,6 @@ plugins {
} }
allprojects { allprojects {
group = "com.agui" group = "pw.binom.agui"
version = "0.1.0-SNAPSHOT" version = "0.1.0-SNAPSHOT"
} }
+11
View File
@@ -6,6 +6,14 @@ plugins {
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
jvm() jvm()
Review

тут тоже надо добавить все возможные цели. android не надо т.к. jvm цель и так его покроет

тут тоже надо добавить все возможные цели. android не надо т.к. jvm цель и так его покроет
macosX64()
macosArm64()
iosX64()
iosArm64()
iosSimulatorArm64()
linuxX64()
linuxArm64()
mingwX64()
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
@@ -17,6 +25,9 @@ kotlin {
jvmMain.dependencies { jvmMain.dependencies {
implementation(libs.ktor.client.cio) implementation(libs.ktor.client.cio)
} }
nativeMain.dependencies {
implementation(libs.ktor.client.cio)
}
commonTest.dependencies { commonTest.dependencies {
implementation(kotlin("test")) implementation(kotlin("test"))
} }
@@ -1,9 +1,9 @@
package com.agui.client package pw.binom.agui.client
import com.agui.api.agent.Agent import pw.binom.agui.api.agent.Agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.api.serialization.AguiJson import pw.binom.agui.api.serialization.AguiJson
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.plugins.sse.sse import io.ktor.client.plugins.sse.sse
import io.ktor.client.request.setBody import io.ktor.client.request.setBody
@@ -1,4 +1,4 @@
package com.agui.client package pw.binom.agui.client
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig import io.ktor.client.HttpClientConfig
@@ -1,15 +1,15 @@
package com.agui.client package pw.binom.agui.client
import com.agui.api.agent.Agent import pw.binom.agui.api.agent.Agent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.message.MessageRole import pw.binom.agui.api.message.MessageRole
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.server.agui import pw.binom.agui.server.agui
import io.ktor.client.plugins.sse.SSE import io.ktor.client.plugins.sse.SSE
import io.ktor.server.application.application import io.ktor.server.application.application
import io.ktor.server.testing.testApplication import io.ktor.server.testing.testApplication
@@ -21,7 +21,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertIs import kotlin.test.assertIs
/** /**
* Exercises [HttpAgent] against the real AG-UI endpoint exposed by [com.agui.server.agui], * Exercises [HttpAgent] against the real AG-UI endpoint exposed by [pw.binom.agui.server.agui],
* using the Ktor test host so the SSE transport is exercised end-to-end over HTTP. * using the Ktor test host so the SSE transport is exercised end-to-end over HTTP.
*/ */
class HttpAgentTest { class HttpAgentTest {
+1
View File
@@ -12,6 +12,7 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" } ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
ktor-server-sse = { module = "io.ktor:ktor-server-sse", version.ref = "ktor" } ktor-server-sse = { module = "io.ktor:ktor-server-sse", version.ref = "ktor" }
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" } ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" }
ktor-server-test-host = { module = "io.ktor:ktor-server-test-host", version.ref = "ktor" } ktor-server-test-host = { module = "io.ktor:ktor-server-test-host", version.ref = "ktor" }
+11
View File
@@ -6,6 +6,14 @@ plugins {
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
jvm() jvm()
macosX64()
macosArm64()
iosX64()
iosArm64()
iosSimulatorArm64()
linuxX64()
linuxArm64()
mingwX64()
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
@@ -18,6 +26,9 @@ kotlin {
jvmMain.dependencies { jvmMain.dependencies {
implementation(libs.ktor.server.netty) implementation(libs.ktor.server.netty)
} }
nativeMain.dependencies {
implementation(libs.ktor.server.cio)
}
jvmTest.dependencies { jvmTest.dependencies {
implementation(kotlin("test")) implementation(kotlin("test"))
implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.coroutines.test)
@@ -1,10 +1,10 @@
package com.agui.server package pw.binom.agui.server
import com.agui.api.agent.Agent import pw.binom.agui.api.agent.Agent
import com.agui.api.event.BaseEvent import pw.binom.agui.api.event.BaseEvent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.api.serialization.AguiJson import pw.binom.agui.api.serialization.AguiJson
import io.ktor.server.application.Application import io.ktor.server.application.Application
import io.ktor.server.application.ApplicationCall import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call import io.ktor.server.application.call
@@ -1,13 +1,13 @@
package com.agui.server.demo package pw.binom.agui.server.demo
import com.agui.api.agent.Agent import pw.binom.agui.api.agent.Agent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.server.agui import pw.binom.agui.server.agui
import io.ktor.server.engine.embeddedServer import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty import io.ktor.server.netty.Netty
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@@ -1,18 +1,18 @@
package com.agui.server package pw.binom.agui.server
import com.agui.api.agent.Agent import pw.binom.agui.api.agent.Agent
import com.agui.api.event.RunErrorEvent import pw.binom.agui.api.event.RunErrorEvent
import com.agui.api.event.RunFinishedEvent import pw.binom.agui.api.event.RunFinishedEvent
import com.agui.api.event.RunStartedEvent import pw.binom.agui.api.event.RunStartedEvent
import com.agui.api.event.StateSnapshotEvent import pw.binom.agui.api.event.StateSnapshotEvent
import com.agui.api.event.TextMessageContentEvent import pw.binom.agui.api.event.TextMessageContentEvent
import com.agui.api.event.TextMessageEndEvent import pw.binom.agui.api.event.TextMessageEndEvent
import com.agui.api.event.TextMessageStartEvent import pw.binom.agui.api.event.TextMessageStartEvent
import com.agui.api.message.Message import pw.binom.agui.api.message.Message
import com.agui.api.message.MessageRole import pw.binom.agui.api.message.MessageRole
import com.agui.api.run.RunAgentInput import pw.binom.agui.api.run.RunAgentInput
import com.agui.api.state.mutableState import pw.binom.agui.api.state.mutableState
import com.agui.client.HttpAgent import pw.binom.agui.client.HttpAgent
import io.ktor.client.plugins.sse.SSE import io.ktor.client.plugins.sse.SSE
import io.ktor.server.application.application import io.ktor.server.application.application
import io.ktor.server.testing.testApplication import io.ktor.server.testing.testApplication