Skip to content

Commit f5a4107

Browse files
hsudbrockRobert Winkler
authored andcommitted
Very very first version of kotlin-sdk for lmos
1 parent 9e41fe4 commit f5a4107

File tree

14 files changed

+354
-1
lines changed

14 files changed

+354
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dependencies {
2+
api(project(":kotlin-wot"))
3+
implementation("org.jetbrains.kotlin:kotlin-reflect")
4+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package ai.ancf.lmos.kotlinsdk.base
2+
3+
import ai.ancf.lmos.wot.thing.schema.*
4+
import kotlin.reflect.KClass
5+
import kotlin.reflect.KType
6+
import kotlin.reflect.full.memberProperties
7+
8+
object DataSchemaBuilder {
9+
10+
// TODO: Move to kotlin-wot
11+
12+
fun mapTypeToSchema(type: KType): DataSchema<out Any> {
13+
return when (type.classifier) {
14+
Int::class -> IntegerSchema()
15+
Float::class -> NumberSchema()
16+
Double::class -> NumberSchema()
17+
Long::class -> NumberSchema()
18+
String::class -> StringSchema()
19+
Boolean::class -> BooleanSchema()
20+
List::class, Set::class -> {
21+
val genericType = type.arguments.firstOrNull()?.type
22+
val itemSchema = if (genericType != null) {
23+
mapTypeToSchema(genericType)
24+
} else {
25+
StringSchema()
26+
}
27+
ArraySchema(items = itemSchema)
28+
}
29+
IntArray::class -> ArraySchema(items = IntegerSchema())
30+
FloatArray::class -> ArraySchema(items = NumberSchema())
31+
DoubleArray::class -> ArraySchema(items = NumberSchema())
32+
NumberSchema::class -> ArraySchema(items = NumberSchema())
33+
Array<String>::class -> ArraySchema(items = StringSchema())
34+
Array<Number>::class -> ArraySchema(items = NumberSchema())
35+
Array<Boolean>::class -> ArraySchema(items = BooleanSchema())
36+
Array<Int>::class -> ArraySchema(items = IntegerSchema())
37+
Array<Float>::class -> ArraySchema(items = NumberSchema())
38+
Array<Long>::class -> ArraySchema(items = NumberSchema())
39+
Unit::class -> NullSchema()
40+
else -> buildObjectSchema(type)
41+
}
42+
}
43+
44+
private fun buildObjectSchema(type: KType): ObjectSchema {
45+
if (type.classifier == Map::class) {
46+
return buildMapSchema(type)
47+
}
48+
49+
val kClass = type.classifier as? KClass<*>
50+
?: throw IllegalArgumentException("Type is not a valid class: $type")
51+
52+
val (properties, required) = extractProperties(kClass)
53+
return ObjectSchema(properties, required)
54+
}
55+
56+
private fun buildMapSchema(type: KType): ObjectSchema {
57+
val keyType = type.arguments.getOrNull(0)?.type
58+
val valueType = type.arguments.getOrNull(1)?.type
59+
60+
val keySchema = if (keyType != null) mapTypeToSchema(keyType) else StringSchema()
61+
val valueSchema = if (valueType != null) mapTypeToSchema(valueType) else StringSchema()
62+
63+
return ObjectSchema(
64+
properties = mutableMapOf(
65+
"keys" to ArraySchema(items = keySchema),
66+
"values" to ArraySchema(items = valueSchema)
67+
)
68+
)
69+
}
70+
71+
private fun extractProperties(kClass: KClass<*>): Pair<MutableMap<String, DataSchema<*>>, MutableList<String>> {
72+
val properties: MutableMap<String, DataSchema<*>> = mutableMapOf()
73+
val required: MutableList<String> = mutableListOf()
74+
75+
kClass.memberProperties.forEach { property ->
76+
val returnType = property.returnType
77+
val schemaForParam = mapTypeToSchema(returnType)
78+
properties[property.name] = schemaForParam
79+
if (!returnType.isMarkedNullable) {
80+
required.add(property.name)
81+
}
82+
}
83+
return Pair(properties, required)
84+
}
85+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package ai.ancf.lmos.kotlinsdk.base
2+
3+
object LMOSContext {
4+
const val prefix = "lmos"
5+
const val url = "https://eclipse.dev/lmos/protocol/v1"
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ai.ancf.lmos.kotlinsdk.base
2+
3+
import ai.ancf.lmos.wot.thing.schema.Type
4+
5+
object LmosThingTypes {
6+
val TOOL = Type("lmos:Tool")
7+
val AGENT = Type("lmos:Agent")
8+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ai.ancf.lmos.kotlinsdk.base.model
2+
3+
data class AgentRequest(
4+
val messages: List<Message>,
5+
val conversationContext: ConversationContext,
6+
val systemContext: List<SystemContextEntry>,
7+
val userContext: UserContext,
8+
)
9+
10+
data class UserContext(
11+
val userId: String? = null,
12+
val userToken: String? = null,
13+
val profile: List<ProfileEntry>,
14+
)
15+
16+
data class ConversationContext(
17+
val conversationId: String,
18+
val turnId: String? = null,
19+
val anonymizationEntities: List<AnonymizationEntity>? = null,
20+
)
21+
22+
data class ProfileEntry(
23+
val key: String,
24+
val value: String,
25+
)
26+
27+
data class SystemContextEntry(
28+
val key: String,
29+
val value: String,
30+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ai.ancf.lmos.kotlinsdk.base.model
2+
3+
data class AgentResult(
4+
val status: String? = null,
5+
val responseTime: Double = -1.0,
6+
val messages: List<Message>,
7+
val anonymizationEntities: List<AnonymizationEntity>? = null,
8+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package ai.ancf.lmos.kotlinsdk.base.model
2+
3+
data class AnonymizationEntity(val type: String, val value: String, val replacement: String)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ai.ancf.lmos.kotlinsdk.base.model
2+
3+
data class Message(
4+
val role: String,
5+
val content: String,
6+
val format: String = "text",
7+
val turnId: String? = null,
8+
val binaryData: List<BinaryData>? = null,
9+
)
10+
11+
class BinaryData(val mimeType: String, val dataAsBase64: String? = null, val source: String? = null)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dependencies {
2+
api(project(":kotlin-wot"))
3+
api(project(":lmos-kotlin-sdk-base"))
4+
implementation("org.slf4j:slf4j-api:2.0.16")
5+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
dependencies {
2+
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
3+
api(project(":kotlin-wot"))
4+
api(project(":lmos-kotlin-sdk-base"))
5+
implementation("org.slf4j:slf4j-api:2.0.16")
6+
7+
testImplementation(platform("io.ktor:ktor-bom:3.1.0"))
8+
testImplementation(project(":kotlin-wot-binding-http"))
9+
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0")
10+
testImplementation("io.ktor:ktor-client-okhttp")
11+
testImplementation("io.ktor:ktor-client-json")
12+
testImplementation("io.ktor:ktor-client-jackson")
13+
testImplementation("io.ktor:ktor-client-serialization")
14+
testImplementation("io.ktor:ktor-client-content-negotiation")
15+
testImplementation("io.ktor:ktor-serialization-jackson")
16+
testImplementation("org.assertj:assertj-core:3.24.2")
17+
}
18+
19+
tasks.register("listConfigurations") {
20+
doLast {
21+
configurations.forEach { config ->
22+
println("Configuration: ${config.name}")
23+
println(" Can be resolved: ${config.isCanBeResolved}")
24+
println(" Can be consumed: ${config.isCanBeConsumed}")
25+
println(" Extends from: ${config.extendsFrom.joinToString { it.name }}")
26+
println()
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)