Skip to content

Commit 6411f36

Browse files
author
Robert Winkler
committed
Improved ThingBuilder
1 parent 30ebfbc commit 6411f36

File tree

9 files changed

+42
-19
lines changed

9 files changed

+42
-19
lines changed

kotlin-wot-integration-tests/src/main/kotlin/integration/HttpAgent.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ai.ancf.lmos.wot.integration
22

33
import ai.ancf.lmos.wot.Wot
4+
import ai.ancf.lmos.wot.reflection.ThingBuilder
45
import ai.ancf.lmos.wot.reflection.annotations.ThingAgent
6+
import ai.ancf.lmos.wot.thing.schema.WoTExposedThing
57
import kotlinx.coroutines.Job
68
import kotlinx.coroutines.launch
79
import kotlinx.coroutines.runBlocking
@@ -21,12 +23,12 @@ fun main(): Unit = runBlocking {
2123
})
2224

2325
val wot = Wot.create(servient)
24-
val exposedThing = createExposedThing(wot, agent)
26+
val exposedThing = ThingBuilder.createExposedThing(wot, agent, ThingAgent::class)
2527

2628
// Start `servient` in a separate coroutine
2729
servient.start()
2830
// Add and expose the thing after `start()` has had time to begin
29-
servient.addThing(exposedThing)
31+
servient.addThing(exposedThing as WoTExposedThing)
3032
servient.expose("agent")
3133

3234
println("Exposed Agent on HTTP Server")

kotlin-wot-integration-tests/src/main/kotlin/integration/MqttAgent.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ai.ancf.lmos.wot.integration
22

33
import ai.ancf.lmos.wot.Wot
4+
import ai.ancf.lmos.wot.reflection.ThingBuilder
45
import ai.ancf.lmos.wot.reflection.annotations.ThingAgent
6+
import ai.ancf.lmos.wot.thing.schema.WoTExposedThing
57
import kotlinx.coroutines.Job
68
import kotlinx.coroutines.launch
79
import kotlinx.coroutines.runBlocking
@@ -20,14 +22,14 @@ fun main(): Unit = runBlocking {
2022
})
2123

2224
val wot = Wot.create(servient)
23-
val exposedThing = createExposedThing(wot, agent)
24-
25+
val exposedThing = ThingBuilder.createExposedThing(wot, agent, ThingAgent::class)
2526
// Start `servient` in a separate coroutine
2627
servient.start()
2728
// Add and expose the thing after `start()` has had time to begin
28-
servient.addThing(exposedThing)
29+
servient.addThing(exposedThing as WoTExposedThing)
2930
servient.expose("agent")
3031
println("Exposed Agent on MQTT Server")
32+
println("Exposed Thing:${exposedThing.toJson()}")
3133
// Keep the application running until process is stopped
3234
Job().join()
3335
}

kotlin-wot-integration-tests/src/main/kotlin/integration/ThingAgent.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
package ai.ancf.lmos.wot.reflection.annotations
22

33
import dev.langchain4j.model.azure.AzureOpenAiChatModel
4+
import kotlinx.coroutines.flow.Flow
5+
import kotlinx.coroutines.flow.MutableSharedFlow
46

57

68
@Thing(id= "agent", title="Agent",
79
description= "A simple agent.")
8-
class ThingAgent() {
10+
class ThingAgent(@Property(name = "modelTemperature", readOnly = true)
11+
val modelConfiguration: ModelConfiguration = ModelConfiguration(0.5, 50)) {
12+
13+
private val messageFlow = MutableSharedFlow<String>(replay = 1) // Replay last emitted value
914

1015
private val model: AzureOpenAiChatModel = AzureOpenAiChatModel.builder()
1116
.apiKey("af12dab9c046453e82dcf4b24af90bca")
1217
.deploymentName("GPT35T-1106")
1318
.endpoint("https://gpt4-uk.openai.azure.com/")
19+
.temperature(modelConfiguration.modelTemperature)
1420
.build();
1521

16-
@Property(name = "modelTemperature", readOnly = true)
17-
var modelTemperature: ModelConfiguration = ModelConfiguration(0.5, 50)
22+
@Action(name = "ask", title = "Ask", description = "Ask the agent a question.")
23+
suspend fun ask(message : String) : String {
24+
val response = model.generate(message)
25+
messageFlow.emit(response)
26+
return model.generate(response)
27+
}
1828

19-
@Action(name = "ask")
20-
fun ask(message : String) : String {
21-
return model.generate(message)
29+
@Event(name = "messageGenerated", title = "Generated message")
30+
fun messageGenerated() : Flow<String> {
31+
return messageFlow
2232
}
2333
}
2434

kotlin-wot-integration-tests/src/main/kotlin/integration/Util.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fun createServient(protocol: String): Servient {
2525
clientFactories = listOf(HttpProtocolClientFactory())
2626
)
2727
"MQTT" -> {
28-
val mqttConfig = MqttClientConfig("localhost", 54884, "wotServer")
28+
val mqttConfig = MqttClientConfig("localhost", 60234, "wotServer")
2929
Servient(
3030
servers = listOf(MqttProtocolServer(mqttConfig))
3131
)

kotlin-wot-integration-tests/src/test/kotlin/integration/AgentBuilderTest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import ai.ancf.lmos.wot.Servient
55
import ai.ancf.lmos.wot.Wot
66
import ai.ancf.lmos.wot.binding.http.HttpProtocolClientFactory
77
import ai.ancf.lmos.wot.binding.http.HttpProtocolServer
8+
import ai.ancf.lmos.wot.reflection.ThingBuilder.createExposedThing
89
import ai.ancf.lmos.wot.reflection.annotations.ThingAgent
9-
import ai.ancf.lmos.wot.reflection.annotations.ThingBuilder
1010
import ai.ancf.lmos.wot.thing.schema.WoTExposedThing
1111
import ai.ancf.lmos.wot.thing.schema.toInteractionInputValue
1212
import kotlinx.coroutines.test.runTest
@@ -26,8 +26,7 @@ class AgentBuilderTest {
2626
servient.start()
2727

2828
val wot = Wot.create(servient)
29-
val exposedThing = ThingBuilder()
30-
.createThingDescription(wot, ThingAgent(), ThingAgent::class)
29+
val exposedThing = createExposedThing(wot, ThingAgent(), ThingAgent::class)
3130
if(exposedThing != null){
3231

3332

kotlin-wot-reflection/src/main/kotlin/reflection/ThingBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object ThingBuilder {
4444
* @param clazz The KClass of the object to be described.
4545
* @return An [ExposedThing] or null if no description could be generated.
4646
*/
47-
fun <T : Any> createThingDescription(wot: Wot, instance: T, clazz: KClass<T>): ExposedThing? {
47+
fun <T : Any> createExposedThing(wot: Wot, instance: T, clazz: KClass<T>): ExposedThing? {
4848
log.debug("Creating ThingDescription for class: ${clazz.simpleName}")
4949

5050
// 1. Get the @Thing annotation from the class

kotlin-wot-reflection/src/test/kotlin/reflection/ComplexThingTest.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class ComplexThingTest {
2525
complexThing = ComplexThing()
2626

2727
// Generate ThingDescription from the class
28-
exposedThing = ThingBuilder.createThingDescription(wot, complexThing, ComplexThing::class) as WoTExposedThing
28+
exposedThing = ThingBuilder.createExposedThing(wot, complexThing, ComplexThing::class) as WoTExposedThing
2929
thingDescription = exposedThing.getThingDescription()
3030
}
3131

@@ -47,6 +47,16 @@ class ComplexThingTest {
4747
assertEquals("Hello World", exampleStringProperty.const)
4848
}
4949

50+
@Test
51+
fun `test constructorProperty in ThingDescription`() {
52+
// Assertions for String Property
53+
assertTrue(thingDescription.properties.containsKey("constructorProperty"), "ThingDescription should contain 'constructorProperty' property")
54+
val exampleStringProperty = thingDescription.properties["constructorProperty"]
55+
assertNotNull(exampleStringProperty, "'constructorProperty' property should not be null")
56+
assertIs<StringProperty>(exampleStringProperty, "'constructorProperty' should be a StringProperty")
57+
assertEquals("Hello World", exampleStringProperty.const)
58+
}
59+
5060
@Test
5161
fun `test exampleIntProperty in ThingDescription`() {
5262
// Assertions for Int Property

kotlin-wot-reflection/src/test/kotlin/reflection/SimpleThingTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class SimpleThingTest {
4040
simpleThing = SimpleThing()
4141

4242
// Generate ThingDescription from the class
43-
exposedThing = ThingBuilder.createThingDescription(wot, simpleThing, SimpleThing::class)!!
43+
exposedThing = ThingBuilder.createExposedThing(wot, simpleThing, SimpleThing::class)!!
4444

4545
servient.addThing(exposedThing)
4646
servient.expose("simpleThing")

kotlin-wot-reflection/src/test/kotlin/reflection/things/ComplexThing.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import kotlin.random.Random
1616
title = "Complex Thing",
1717
description = "A thing with complex properties, actions, and events."
1818
)
19-
class ComplexThing {
19+
class ComplexThing(@Property(name = "constructorProperty", readOnly = true) val constructorProperty: String = "Hello World") {
2020

2121
private val statusChangedFlow = MutableSharedFlow<String>(replay = 1) // Replay last emitted value
2222

0 commit comments

Comments
 (0)