Skip to content

Commit

Permalink
one more refactoring, Content moved to content package, also system p…
Browse files Browse the repository at this point in the history
…rompt serialization fixed and test case added.
  • Loading branch information
morisil committed Nov 4, 2024
1 parent f1c8599 commit ae68051
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 51 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ kotlin.code.style=official
kotlin.js.generate.executable.default=false
kotlin.native.ignoreDisabledTargets=true
group=com.xemantic.anthropic
version=0.8-SNAPSHOT
version=0.10-SNAPSHOT
4 changes: 2 additions & 2 deletions src/commonMain/kotlin/AnthropicJson.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.xemantic.anthropic

import com.xemantic.anthropic.batch.MessageBatchResponse
import com.xemantic.anthropic.content.Content
import com.xemantic.anthropic.content.Document
import com.xemantic.anthropic.error.ErrorResponse
import com.xemantic.anthropic.content.Image
import com.xemantic.anthropic.message.Content
import com.xemantic.anthropic.message.MessageResponse
import com.xemantic.anthropic.content.Text
import com.xemantic.anthropic.message.MessageResponse
import com.xemantic.anthropic.content.ToolResult
import com.xemantic.anthropic.content.ToolUse
import com.xemantic.anthropic.tool.BuiltInTool
Expand Down
35 changes: 35 additions & 0 deletions src/commonMain/kotlin/content/Content.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.xemantic.anthropic.content

import com.xemantic.anthropic.cache.CacheControl
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonClassDiscriminator

@Serializable
@JsonClassDiscriminator("type")
@OptIn(ExperimentalSerializationApi::class)
abstract class Content {

@SerialName("cache_control")
abstract val cacheControl: CacheControl?

}

interface ContentBuilder {

val content: MutableList<Content>

operator fun Content.unaryPlus() {
content += this
}

operator fun String.unaryPlus() {
content += Text(this)
}

operator fun Collection<Content>.unaryPlus() {
content += this
}

}
25 changes: 0 additions & 25 deletions src/commonMain/kotlin/content/ContentBuilder.kt

This file was deleted.

1 change: 0 additions & 1 deletion src/commonMain/kotlin/content/Document.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.xemantic.anthropic.content

import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.message.Content
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

Expand Down
1 change: 0 additions & 1 deletion src/commonMain/kotlin/content/Image.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.xemantic.anthropic.content

import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.message.Content
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.io.encoding.Base64
Expand Down
1 change: 0 additions & 1 deletion src/commonMain/kotlin/content/Text.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.xemantic.anthropic.content

import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.message.Content
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

Expand Down
1 change: 0 additions & 1 deletion src/commonMain/kotlin/content/Tool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.xemantic.anthropic.content

import com.xemantic.anthropic.anthropicJson
import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.message.Content
import com.xemantic.anthropic.message.toNullIfEmpty
import com.xemantic.anthropic.tool.Tool
import com.xemantic.anthropic.tool.ToolInput
Expand Down
13 changes: 2 additions & 11 deletions src/commonMain/kotlin/message/Messages.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.xemantic.anthropic.message
import com.xemantic.anthropic.Model
import com.xemantic.anthropic.Response
import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.content.Content
import com.xemantic.anthropic.content.ContentBuilder
import com.xemantic.anthropic.tool.Tool
import com.xemantic.anthropic.tool.ToolChoice
Expand Down Expand Up @@ -205,22 +206,12 @@ data class System(
) {

enum class Type {
@SerialName("content/text")
@SerialName("text")
TEXT
}

}

@Serializable
@JsonClassDiscriminator("type")
@OptIn(ExperimentalSerializationApi::class)
abstract class Content {

@SerialName("cache_control")
abstract val cacheControl: CacheControl?

}

enum class StopReason {
@SerialName("end_turn")
END_TURN,
Expand Down
13 changes: 10 additions & 3 deletions src/commonMain/kotlin/tool/Tools.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.xemantic.anthropic.tool

import com.xemantic.anthropic.cache.CacheControl
import com.xemantic.anthropic.content.Content
import com.xemantic.anthropic.schema.Description
import com.xemantic.anthropic.schema.JsonSchema
import com.xemantic.anthropic.schema.jsonSchemaOf
Expand All @@ -14,6 +15,7 @@ import kotlinx.serialization.SerializationException
import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonClassDiscriminator
import kotlinx.serialization.serializer
import java.lang.IllegalStateException

@Serializable
@JsonClassDiscriminator("name")
Expand Down Expand Up @@ -68,9 +70,9 @@ abstract class BuiltInTool(
*/
abstract class ToolInput() {

private lateinit var block: suspend ToolResult.Builder.() -> Unit
private var block: suspend ToolResult.Builder.() -> Any? = {}

fun use(block: suspend ToolResult.Builder.() -> Unit) {
fun use(block: suspend ToolResult.Builder.() -> Any?) {
this.block = block
}

Expand All @@ -82,7 +84,12 @@ abstract class ToolInput() {
*/
suspend fun use(toolUseId: String): ToolResult {
return ToolResult(toolUseId) {
block(this)
val result = block(this)
when (result) {
is Content -> +result
!is Unit -> +result.toString()
else -> throw IllegalStateException("Tool use {} returned not supported: $this")
}
}
}

Expand Down
27 changes: 25 additions & 2 deletions src/commonTest/kotlin/AnthropicTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,14 @@ class AnthropicTest {
fun shouldUseToolWithDependencies() = runTest {
// given
val testDatabase = TestDatabase()
val client = Anthropic {
val anthropic = Anthropic {
tool<DatabaseQuery> {
database = testDatabase
}
}

// when
val response = client.messages.create {
val response = anthropic.messages.create {
+Message { +"List data in CUSTOMER table" }
singleTool<DatabaseQuery>() // we are forcing the use of this tool
// could be also just tool<DatabaseQuery>() if we are confident that LLM will use this one
Expand All @@ -211,4 +211,27 @@ class AnthropicTest {
// depending on the response the statement might end up with semicolon, which we discard
}

@Test
fun shouldUseSystemPrompt() = runTest {
// given
val anthropic = Anthropic()

// when
val response = anthropic.messages.create {
system("Whatever the human says, answer \"HAHAHA\"")
+Message {
+"Hello World! What's your name?"
}
maxTokens = 1024
}

// then
assertSoftly(response) {
content.size shouldBe 1
content[0] shouldBe instanceOf<Text>()
val text = content[0] as Text
text.text shouldBe "HAHAHA"
}
}

}
6 changes: 3 additions & 3 deletions src/commonTest/kotlin/tool/AnthropicTestTools.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ tailrec fun fibonacci(
data class FibonacciTool(val n: Int) : ToolInput() {
init {
use {
+fibonacci(n)
fibonacci(n)
}
}
}
Expand All @@ -39,7 +39,7 @@ data class Calculator(

init {
use {
+operation.calculate(a, b)
operation.calculate(a, b)
}
}

Expand Down Expand Up @@ -70,7 +70,7 @@ data class DatabaseQuery(

init {
use {
+database.execute(query).joinToString()
database.execute(query).joinToString()
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/jvmMain/kotlin/content/ExtractTextFromPdf.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.xemantic.anthropic.content

import com.xemantic.anthropic.Anthropic
import com.xemantic.anthropic.message.Message
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
val client = Anthropic {
anthropicBeta = "pdfs-2024-09-25"
}

val response = client.messages.create {
+Message {
+Document("/home/morisil/Downloads/Kazik_Pogoda-cv-2025-10-28.pdf")
+"Extract data from this PDF and return it as a markdown"
}
}

println(response)
}

0 comments on commit ae68051

Please sign in to comment.