fix: polish SEP-1577 sampling handling (#765)

## Summary
- reject empty sampling content in SamplingMessage and
CreateMessageResult constructors
- clarify sampling validation docs and emit an explicit error when
tool_use is not followed by tool_result
- return sampled text from the conformance test_sampling tool instead of
content object strings

Fixes #730

## Testing
- ./gradlew
-Dorg.gradle.java.installations.paths="/Users/ubl/Documents/New
project/oss-contributions/.jdks/jdk-21.0.11+10/Contents/Home"
:kotlin-sdk-core:jvmTest :kotlin-sdk-server:jvmTest
:conformance-test:compileKotlin

Co-authored-by: Pavel Gorgulov <devcrocod@gmail.com>
This commit is contained in:
Mukunda Rao Katta 2026-06-17 10:11:23 -07:00 • committed by GitHub
commit 75a944fb8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 56 additions and 3 deletions

View file

@ -91,6 +91,10 @@ public data class SamplingMessage(
@SerialName("_meta")
val meta: JsonObject? = null,
) {
init {
require(content.isNotEmpty()) { "content must contain at least one block" }
}
/**
* Convenience constructor for a single-block message. Wraps [content] in a
* singleton list so call sites can write `SamplingMessage(Role.User, TextContent("hi"))`
@ -273,6 +277,10 @@ public data class CreateMessageResult(
@SerialName("_meta")
override val meta: JsonObject? = null,
) : ClientResult {
init {
require(content.isNotEmpty()) { "content must contain at least one block" }
}
/**
* Convenience constructor for a single-block response. Wraps [content] in a
* singleton list so call sites can write

View file

@ -302,6 +302,13 @@ class SamplingTest {
(m.content[0] as TextContent).text shouldBe "hi"
}
@Test
fun `SamplingMessage rejects empty content`() {
assertFailsWith<IllegalArgumentException> {
SamplingMessage(role = Role.User, content = emptyList())
}
}
@Test
fun `SamplingMessage single-element content serialises as single object`() {
val m = SamplingMessage(role = Role.User, content = listOf(TextContent("hi")))
@ -408,6 +415,17 @@ class SamplingTest {
(decoded.content[0] as TextContent).text shouldBe "hi"
}
@Test
fun `CreateMessageResult rejects empty content`() {
assertFailsWith<IllegalArgumentException> {
CreateMessageResult(
role = Role.Assistant,
content = emptyList(),
model = "test-model",
)
}
}
// ============================================================================
// SamplingContentSerializer (single-or-array wire heuristic)
// ============================================================================