diff --git a/prompt/prompt-executor/prompt-executor-clients/prompt-executor-anthropic-client/src/commonMain/kotlin/ai/koog/prompt/executor/clients/anthropic/DataModel.kt b/prompt/prompt-executor/prompt-executor-clients/prompt-executor-anthropic-client/src/commonMain/kotlin/ai/koog/prompt/executor/clients/anthropic/DataModel.kt index bea04976a..c85bdfbbf 100644 --- a/prompt/prompt-executor/prompt-executor-clients/prompt-executor-anthropic-client/src/commonMain/kotlin/ai/koog/prompt/executor/clients/anthropic/DataModel.kt +++ b/prompt/prompt-executor/prompt-executor-clients/prompt-executor-anthropic-client/src/commonMain/kotlin/ai/koog/prompt/executor/clients/anthropic/DataModel.kt @@ -249,20 +249,23 @@ public data class AnthropicTool( * Represents a schema definition for an Anthropic tool utilized in LLM clients. This data class * defines the structure expected for tools, including the type of schema, properties, and required fields. * - * This API is internal and should not be used outside of its intended scope, as it might be subject + * This API is internal and should not be used outside its intended scope, as it might be subject * to changes or removal without notice. * - * @property type The type of the schema, defaulting to "object". * @property properties A JSON object representing the properties within this schema. * @property required A list of property names that are mandatory within this schema. */ @InternalLLMClientApi @Serializable public data class AnthropicToolSchema( - val type: String = "object", val properties: JsonObject, val required: List -) +) { + /** + * The type of the schema. Always returns "object" for Anthropic tool schemas. + */ + val type: String = "object" +} /** * Represents the response structure from an Anthropic API call. diff --git a/prompt/prompt-executor/prompt-executor-clients/prompt-executor-bedrock-client/src/jvmTest/kotlin/ai/koog/prompt/executor/clients/bedrock/modelfamilies/anthropic/BedrockAnthropicClaudeSerializationTest.kt b/prompt/prompt-executor/prompt-executor-clients/prompt-executor-bedrock-client/src/jvmTest/kotlin/ai/koog/prompt/executor/clients/bedrock/modelfamilies/anthropic/BedrockAnthropicClaudeSerializationTest.kt index c17af8912..ddfe25d15 100644 --- a/prompt/prompt-executor/prompt-executor-clients/prompt-executor-bedrock-client/src/jvmTest/kotlin/ai/koog/prompt/executor/clients/bedrock/modelfamilies/anthropic/BedrockAnthropicClaudeSerializationTest.kt +++ b/prompt/prompt-executor/prompt-executor-clients/prompt-executor-bedrock-client/src/jvmTest/kotlin/ai/koog/prompt/executor/clients/bedrock/modelfamilies/anthropic/BedrockAnthropicClaudeSerializationTest.kt @@ -394,4 +394,41 @@ class BedrockAnthropicClaudeSerializationTest { val content = BedrockAnthropicClaudeSerialization.parseAnthropicStreamChunk(chunkJson) assertEquals("", content) } + + @Test + fun `createAnthropicRequest with tools serializes type field correctly`() { + val tools = listOf( + ToolDescriptor( + name = toolName, + description = toolDescription, + requiredParameters = listOf( + ToolParameterDescriptor("city", "The city name", ToolParameterType.String) + ), + optionalParameters = listOf( + ToolParameterDescriptor("units", "Temperature units", ToolParameterType.String) + ) + ) + ) + val prompt = Prompt.build("test", params = LLMParams(toolChoice = LLMParams.ToolChoice.Auto)) { + user(userMessageQuestion) + } + val request = BedrockAnthropicClaudeSerialization.createAnthropicRequest(prompt, model, tools) + assertNotNull(request) + assertNotNull(request.tools) + assertEquals(1, request.tools?.size) + val tool = request.tools?.get(0) + assertNotNull(tool) + assertEquals(toolName, tool.name) + assertEquals(toolDescription, tool.description) + val schema = tool.inputSchema + assertNotNull(schema) + + // Verify that the type field is always "object" and gets serialized + assertEquals("object", schema.type) + + assertEquals(listOf("city"), schema.required) + val properties = schema.properties.jsonObject + assertNotNull(properties["city"]) + assertNotNull(properties["units"]) + } }