Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ object CommunicateTool {
),
) { input ->
val parsed = tools.jackson.databind.ObjectMapper().readTree(input)
val message = parsed.get("message")?.asText()
val message = parsed.get("message")?.asString()
?: return@of Tool.Result.error("Missing 'message' parameter")

val process = AgentProcess.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object ProgressTool {
),
) { input ->
val parsed = tools.jackson.databind.ObjectMapper().readTree(input)
val status = parsed.get("status")?.asText()
val status = parsed.get("status")?.asString()
?: return@of Tool.Result.error("Missing 'status' parameter")

val process = AgentProcess.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ internal class MaybeReturnDeserializer<T> private constructor(

private fun deserializeFailure(failureNode: JsonNode): MaybeReturn<T> = when {
failureNode is NullNode -> MaybeReturn.failure(ERROR_FAILURE_NULL)
!failureNode.isTextual -> MaybeReturn.failure(ERROR_FAILURE_NOT_STRING)
failureNode.asText().isBlank() -> MaybeReturn.failure(ERROR_FAILURE_EMPTY)
else -> MaybeReturn.failure(failureNode.asText())
!failureNode.isString -> MaybeReturn.failure(ERROR_FAILURE_NOT_STRING)
failureNode.asString().isBlank() -> MaybeReturn.failure(ERROR_FAILURE_EMPTY)
else -> MaybeReturn.failure(failureNode.asString())
}

private fun deserializeSuccess(successNode: JsonNode, ctxt: DeserializationContext): MaybeReturn<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class ContentPartDeserializer : ValueDeserializer<ContentPart>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): ContentPart {
val node: JsonNode = context.readTree(parser)

node[TEXT_FIELD]?.asText()?.let { text ->
node[TEXT_FIELD]?.asString()?.let { text ->
return TextPart(text)
}

val mimeType = node[MIME_TYPE_FIELD]?.asText()
val mimeType = node[MIME_TYPE_FIELD]?.asString()
?: throw MismatchedInputException.from(
parser, ContentPart::class.java,
"Content part must contain '$TEXT_FIELD' or '$MIME_TYPE_FIELD'",
Expand All @@ -53,7 +53,7 @@ class ContentPartDeserializer : ValueDeserializer<ContentPart>() {

return when (classifyMimeType(mimeType)) {
MediaKind.IMAGE -> ImagePart(mimeType, data)
MediaKind.DOCUMENT -> DocumentPart(mimeType, data, node[FILENAME_FIELD]?.takeUnless { it.isNull }?.asText())
MediaKind.DOCUMENT -> DocumentPart(mimeType, data, node[FILENAME_FIELD]?.takeUnless { it.isNull }?.asString())
null -> throw MismatchedInputException.from(
parser, ContentPart::class.java,
"Unsupported media MIME type: $mimeType",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ class DomainTypeInputSchemaTest {
val jsonSchema = schema.toJsonSchema()
val parsed = objectMapper.readTree(jsonSchema)

assertEquals("object", parsed.get("type").asText())
assertEquals("object", parsed.get("type").asString())
}

@Test
Expand Down Expand Up @@ -424,10 +424,10 @@ class DomainTypeInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val properties = parsed.get("properties")

assertEquals("string", properties.get("name").get("type").asText())
assertEquals("integer", properties.get("count").get("type").asText())
assertEquals("number", properties.get("price").get("type").asText())
assertEquals("boolean", properties.get("active").get("type").asText())
assertEquals("string", properties.get("name").get("type").asString())
assertEquals("integer", properties.get("count").get("type").asString())
assertEquals("number", properties.get("price").get("type").asString())
assertEquals("boolean", properties.get("active").get("type").asString())
}

@Test
Expand Down Expand Up @@ -470,11 +470,11 @@ class DomainTypeInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val tagsProperty = parsed.get("properties").get("tags")

assertEquals("array", tagsProperty.get("type").asText())
assertEquals("array", tagsProperty.get("type").asString())

val items = tagsProperty.get("items")
assertNotNull(items, "Array schema must have 'items' property")
assertEquals("string", items.get("type").asText())
assertEquals("string", items.get("type").asString())
}

@Test
Expand Down Expand Up @@ -503,7 +503,7 @@ class DomainTypeInputSchemaTest {
val properties = parsed.get("properties")

val addressProperty = properties.get("address")
assertEquals("object", addressProperty.get("type").asText())
assertEquals("object", addressProperty.get("type").asString())

val nestedProperties = addressProperty.get("properties")
assertNotNull(nestedProperties)
Expand Down Expand Up @@ -660,7 +660,7 @@ class DomainTypeInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)

val itemsProperty = parsed.get("properties").get("items")
assertEquals("array", itemsProperty.get("type").asText())
assertEquals("array", itemsProperty.get("type").asString())

val itemsSchema = itemsProperty.get("items")
assertNotNull(itemsSchema)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class TypeBasedInputSchemaTest {
val jsonSchema = schema.toJsonSchema()
val parsed = objectMapper.readTree(jsonSchema)

assertEquals("object", parsed.get("type").asText())
assertEquals("object", parsed.get("type").asString())
}

@Test
Expand All @@ -231,9 +231,9 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val properties = parsed.get("properties")

assertEquals("string", properties.get("stringField").get("type").asText())
assertEquals("integer", properties.get("intField").get("type").asText())
assertEquals("boolean", properties.get("booleanField").get("type").asText())
assertEquals("string", properties.get("stringField").get("type").asString())
assertEquals("integer", properties.get("intField").get("type").asString())
assertEquals("boolean", properties.get("booleanField").get("type").asString())
}

@Test
Expand Down Expand Up @@ -265,10 +265,10 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val properties = parsed.get("properties")

assertEquals("integer", properties.get("intField").get("type").asText())
assertEquals("integer", properties.get("longField").get("type").asText())
assertEquals("number", properties.get("doubleField").get("type").asText())
assertEquals("number", properties.get("floatField").get("type").asText())
assertEquals("integer", properties.get("intField").get("type").asString())
assertEquals("integer", properties.get("longField").get("type").asString())
assertEquals("number", properties.get("doubleField").get("type").asString())
assertEquals("number", properties.get("floatField").get("type").asString())
}

@Test
Expand All @@ -282,7 +282,7 @@ class TypeBasedInputSchemaTest {
// List may be detected as object due to type erasure
assertNotNull(properties.get("listField"))
// Array types are correctly detected
assertEquals("array", properties.get("arrayField").get("type").asText())
assertEquals("array", properties.get("arrayField").get("type").asString())
}

@Test
Expand All @@ -293,7 +293,7 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val properties = parsed.get("properties")

assertEquals("object", properties.get("nested").get("type").asText())
assertEquals("object", properties.get("nested").get("type").asString())
}
}

Expand All @@ -310,7 +310,7 @@ class TypeBasedInputSchemaTest {
assertNotNull(jsonSchema)

val parsed = objectMapper.readTree(jsonSchema)
assertEquals("object", parsed.get("type").asText())
assertEquals("object", parsed.get("type").asString())
}
}

Expand All @@ -329,12 +329,12 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val tagsProperty = parsed.get("properties").get("tags")

assertEquals("array", tagsProperty.get("type").asText())
assertEquals("array", tagsProperty.get("type").asString())

// This is the key assertion - arrays MUST have items property
val items = tagsProperty.get("items")
assertNotNull(items, "Array schema must have 'items' property for OpenAI compatibility")
assertEquals("string", items.get("type").asText())
assertEquals("string", items.get("type").asString())
}

@Test
Expand All @@ -345,11 +345,11 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val scoresProperty = parsed.get("properties").get("scores")

assertEquals("array", scoresProperty.get("type").asText())
assertEquals("array", scoresProperty.get("type").asString())

val items = scoresProperty.get("items")
assertNotNull(items, "Array schema must have 'items' property for OpenAI compatibility")
assertEquals("integer", items.get("type").asText())
assertEquals("integer", items.get("type").asString())
}

@Test
Expand All @@ -360,12 +360,12 @@ class TypeBasedInputSchemaTest {
val parsed = objectMapper.readTree(jsonSchema)
val itemsProperty = parsed.get("properties").get("items")

assertEquals("array", itemsProperty.get("type").asText())
assertEquals("array", itemsProperty.get("type").asString())

// Array items should have a nested object schema
val items = itemsProperty.get("items")
assertNotNull(items, "Array schema must have 'items' property for OpenAI compatibility")
assertEquals("object", items.get("type").asText())
assertEquals("object", items.get("type").asString())

// The nested object should have its own properties defined
val nestedProperties = items.get("properties")
Expand All @@ -383,22 +383,22 @@ class TypeBasedInputSchemaTest {

// Top-level properties
val properties = parsed.get("properties")
assertEquals("string", properties.get("title").get("type").asText())
assertEquals("integer", properties.get("count").get("type").asText())
assertEquals("string", properties.get("title").get("type").asString())
assertEquals("integer", properties.get("count").get("type").asString())

// Entries array
val entriesProperty = properties.get("entries")
assertEquals("array", entriesProperty.get("type").asText())
assertEquals("array", entriesProperty.get("type").asString())

val items = entriesProperty.get("items")
assertNotNull(items, "Array schema must have 'items' property")
assertEquals("object", items.get("type").asText())
assertEquals("object", items.get("type").asString())

// Nested properties in the array items
val nestedProperties = items.get("properties")
assertNotNull(nestedProperties)
assertEquals("string", nestedProperties.get("name").get("type").asText())
assertEquals("integer", nestedProperties.get("value").get("type").asText())
assertEquals("string", nestedProperties.get("name").get("type").asString())
assertEquals("integer", nestedProperties.get("value").get("type").asString())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class UnfoldingShortcutTest {
),
) { input ->
val parsed = tools.jackson.module.kotlin.jacksonObjectMapper().readTree(input)
taskName = parsed.get("name")?.asText()
taskName = parsed.get("name")?.asString()
Tool.Result.text("Task '$taskName' created")
}
val listTasks = Tool.of("list_tasks", "List tasks") { Tool.Result.text("No tasks") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class ToolLoopLlmOperationsTest {
MaybeReturn(success = successValue)
}
tree.has("failure") -> {
MaybeReturn(failure = tree.get("failure").asText())
MaybeReturn(failure = tree.get("failure").asString())
}
else -> null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fun parseJsonSchema(schema: String): JsonNode? =
/**
* Return the schema `type` value if present.
*/
fun JsonNode.schemaType(): String? = get("type")?.asText()
fun JsonNode.schemaType(): String? = get("type")?.asString()

/**
* Return the `properties` node if present.
Expand All @@ -77,7 +77,7 @@ fun JsonNode.propertiesNode(): JsonNode? = get("properties")
fun JsonNode.requiredFieldNames(): Set<String> =
get("required")
?.takeIf { it.isArray }
?.mapNotNull { if (it.isTextual) it.asText() else null }
?.mapNotNull { if (it.isString) it.asString() else null }
?.toSet()
.orEmpty()

Expand Down Expand Up @@ -193,7 +193,7 @@ private fun normalizeArraySchema(
}

private fun resolveLocalSchemaRef(rootSchemaNode: JsonNode, schemaNode: ObjectNode): ObjectNode? {
val ref = schemaNode.get("\$ref")?.takeIf { it.isTextual }?.asText() ?: return null
val ref = schemaNode.get("\$ref")?.takeIf { it.isString }?.asString() ?: return null
if (!ref.startsWith("#/")) {
return null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ World"""
private fun tools.jackson.databind.JsonNode.requiredFieldNamesOrRefResolved(
rootSchema: tools.jackson.databind.JsonNode,
): Set<String> {
val ref = get("\$ref")?.takeIf { it.isTextual }?.asText()
val ref = get("\$ref")?.takeIf { it.isString }?.asString()
if (ref != null && ref.startsWith("#/")) {
val resolved = ref
.removePrefix("#/")
Expand Down
Loading