Skip to content

Commit 9b266e3

Browse files
[Kotlin] Major enhancements and refactoring (#600)
* chore: upgrade Kotlin toolchain and align Compose 1.9.1 * Remove SwiftUI sample Gradle wrapper jar * Switch SwiftUI chat messages to MarkdownUI rendering * Add tests for chatapp-shared auth and repository * Expose settings dependency and add chat controller test harness * Add Wear OS chat sample, refactor shared core, and modernize Java/iOS examples * feat(chatapp-java): render markdown with Markwon * chore: prune xcsettings artifacts * feat(chatapp-java): support change background tool * Handle frontend tool lifecycle and fix Swift agent snapshot usage * Added support for some of the events (Chunks, Thinking, Tool Call Result, Raw & Custom Events) that were currently missing from the implementation. * Refactor chat controller around agent subscribers * Chat app history fix + logging cleanup * Minor updates to WearOs example. (cherry picked from commit 2f3d987) * Remove Railway Deployment instructions from README Removed the Railway Deployment section from the README.
1 parent a71fbb7 commit 9b266e3

File tree

174 files changed

+9524
-9884
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+9524
-9884
lines changed

docs/sdk/kotlin/client/overview.mdx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,17 @@ Real-time event streaming using Kotlin Flows:
6565
- Server-sent events (SSE) parsing
6666
- Automatic reconnection handling
6767
- Backpressure management
68+
- Automatic expansion of `TEXT_MESSAGE_CHUNK` / `TOOL_CALL_CHUNK` events into start/content/end triads
69+
- Thinking telemetry exposed through `AgentState.thinking`
6870

6971
### State Management
7072
Comprehensive state synchronization:
7173
- JSON Patch-based state updates
7274
- Automatic state validation
7375
- Error state handling
76+
- Tool call results surfaced as `ToolMessage` entries without additional wiring
77+
- Access to raw/custom protocol events via `AgentState.rawEvents` and `AgentState.customEvents`
78+
- Thinking streams exposed through `AgentState.thinking`
7479

7580
### Tool Integration
7681
Client-side tool execution framework:
@@ -108,6 +113,21 @@ agent.sendMessage("Hello!").collect { state ->
108113
}
109114
```
110115

116+
### Reading Thinking Telemetry
117+
118+
```kotlin
119+
agent.sendMessage("Plan the next steps").collect { state ->
120+
state.thinking?.let { thinking ->
121+
if (thinking.isThinking) {
122+
val thought = thinking.messages.lastOrNull().orEmpty()
123+
println("🤔 Agent thinking: $thought")
124+
} else if (thinking.messages.isNotEmpty()) {
125+
println("💡 Agent finished thinking: ${thinking.messages.joinToString()}")
126+
}
127+
}
128+
}
129+
```
130+
111131
### Convenience Builders
112132

113133
The SDK provides convenience builders for common configurations:
@@ -139,6 +159,12 @@ val chatAgent = StatefulAgUiAgent("https://api.example.com/agent") {
139159
chatAgent.chat("My name is Alice").collect { }
140160
chatAgent.chat("What's my name?").collect { state ->
141161
// Agent knows the name from previous message
162+
state.customEvents?.forEach { custom ->
163+
println("Custom event ${custom.name}: ${custom.value}")
164+
}
165+
state.rawEvents?.forEach { raw ->
166+
println("Raw payload: ${raw.event}")
167+
}
142168
}
143169
```
144170

@@ -170,4 +196,4 @@ val agent = AgUiAgent("https://api.example.com/agent") {
170196
- Initial state setup
171197
- State validation rules
172198
- Update strategies
173-
- Persistence options
199+
- Persistence options

docs/sdk/kotlin/overview.mdx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ chatAgent.chat("What's my name?").collect { state ->
106106
}
107107
```
108108

109+
Chunked protocol events (`TEXT_MESSAGE_CHUNK`, `TOOL_CALL_CHUNK`) are automatically rewritten into
110+
their corresponding start/content/end sequences, so Kotlin clients see the same structured events
111+
as non-chunked streams.
112+
113+
Thinking telemetry (`THINKING_*` events) is surfaced alongside normal messages, allowing UIs to indicate
114+
when an agent is reasoning internally before responding.
115+
109116
### Client-Side Tool Integration
110117

111118
```kotlin
@@ -172,4 +179,22 @@ println("Messages: ${currentState.messages.size}")
172179
agent.sendMessage("Hello").collect { state ->
173180
println("Updated state: ${state.messages.last()}")
174181
}
175-
```
182+
183+
// RAW and CUSTOM protocol events are surfaced for inspection
184+
state.rawEvents?.forEach { raw ->
185+
println("Raw event from ${raw.source ?: "unknown"}: ${raw.event}")
186+
}
187+
state.customEvents?.forEach { custom ->
188+
println("Custom event ${custom.name}: ${custom.value}")
189+
}
190+
191+
// Thinking telemetry stream
192+
state.thinking?.let { thinking ->
193+
if (thinking.isThinking) {
194+
val latest = thinking.messages.lastOrNull().orEmpty()
195+
println("Agent is thinking: $latest")
196+
} else if (thinking.messages.isNotEmpty()) {
197+
println("Agent finished thinking: ${thinking.messages.joinToString()}")
198+
}
199+
}
200+
```

sdks/community/kotlin/.gitignore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ captures/
4242
*.perspectivev3
4343
**/*.xcworkspace/xcuserdata/
4444
**/*.xcodeproj/xcuserdata/
45-
*.xccheckout
46-
*.xcscmblueprint
47-
DerivedData/
45+
*.xccheckout
46+
*.xcscmblueprint
47+
*.xcsettings
48+
DerivedData/
4849
*.hmap
4950
*.ipa
5051
*.dSYM.zip
@@ -101,4 +102,4 @@ temp/
101102
*.rar
102103

103104
# Virtual machine crash logs
104-
hs_err_pid*
105+
hs_err_pid*

sdks/community/kotlin/CHANGELOG.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,23 @@
44
- Smaller binary sizes due to better optimization
55
- Improved coroutine performance with latest kotlinx.coroutines# Changelog
66

7-
All notable changes to ag-ui-4k will be documented in this file.
8-
9-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
10-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
All notable changes to ag-ui-4k will be documented in this file.
8+
9+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
10+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
11+
12+
## [Unreleased]
13+
14+
### Added
15+
- Agent subscriber system for opt-in lifecycle and event interception.
16+
- Text message role fidelity in chunk transformation and state application.
17+
18+
### Changed
19+
- Default apply pipeline now routes every event through subscribers before mutating state.
20+
- State application respects developer/system/user roles when constructing streaming messages.
21+
22+
### Tests
23+
- Expanded chunk transformation and state application coverage for role propagation and subscriber behavior.
1124

1225
## [0.1.0] - 2025-06-14
1326

sdks/community/kotlin/OVERVIEW.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ AG-UI Kotlin SDK follows the design patterns of the TypeScript SDK while leverag
2121
- **kotlin-client**: HTTP transport, state management, and high-level agent APIs
2222
- **kotlin-tools**: Tool execution framework with registry and circuit breakers
2323

24-
The SDK maintains conceptual parity with the TypeScript implementation while providing native Kotlin idioms like sealed classes, suspend functions, and Kotlin Flows for streaming responses.
24+
The SDK maintains conceptual parity with the TypeScript implementation while providing native Kotlin idioms like sealed classes, suspend functions, and Kotlin Flows for streaming responses.
25+
26+
## Lifecycle subscribers and role fidelity
27+
28+
- **AgentSubscriber hooks** – Agents now expose a subscription API so applications can observe run initialization, per-event delivery, and state mutations before the built-in handlers execute. This enables cross-cutting concerns like analytics, tracing, or custom persistence without forking the pipeline.
29+
- **Role-aware text streaming** – Text message events preserve their declared roles (developer, system, assistant, user) throughout chunk transformation and state application, ensuring downstream UI state mirrors the protocol payloads exactly.

sdks/community/kotlin/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The comprehensive documentation covers:
2121

2222
```kotlin
2323
dependencies {
24-
implementation("com.agui:kotlin-client:0.2.1")
24+
implementation("com.agui:kotlin-client:0.2.3")
2525
}
2626
```
2727

sdks/community/kotlin/build.gradle.kts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
22

3-
plugins {
4-
kotlin("multiplatform") version "2.1.21"
5-
kotlin("plugin.serialization") version "2.1.21"
3+
plugins {
4+
kotlin("multiplatform") version "2.2.20"
5+
kotlin("plugin.serialization") version "2.2.20"
66
id("com.android.library") version "8.2.2"
77
id("io.gitlab.arturbosch.detekt") version "1.23.4"
88
id("maven-publish")
@@ -34,8 +34,8 @@ kotlin {
3434
freeCompilerArgs.add("-Xopt-in=kotlin.RequiresOptIn")
3535
freeCompilerArgs.add("-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi")
3636
freeCompilerArgs.add("-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi")
37-
languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_1)
38-
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_1)
37+
languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
38+
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
3939
}
4040
}
4141
}
@@ -226,4 +226,4 @@ tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
226226
sarif.required.set(true)
227227
md.required.set(true)
228228
}
229-
}
229+
}

0 commit comments

Comments
 (0)