Skip to content

Commit b325131

Browse files
Configured dependencies, initial raw implementation for testing
1 parent 6b7b6ce commit b325131

File tree

6 files changed

+233
-1
lines changed

6 files changed

+233
-1
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ plugins {
66
alias(libs.plugins.composeMultiplatform) apply false
77
alias(libs.plugins.composeCompiler) apply false
88
alias(libs.plugins.kotlinMultiplatform) apply false
9+
alias(libs.plugins.serialization) apply false
910
}

composeApp/build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ plugins {
99
alias(libs.plugins.androidApplication)
1010
alias(libs.plugins.composeMultiplatform)
1111
alias(libs.plugins.composeCompiler)
12+
alias(libs.plugins.serialization)
1213
}
1314

1415
kotlin {
@@ -68,6 +69,14 @@ kotlin {
6869
implementation(compose.components.uiToolingPreview)
6970
implementation(libs.androidx.lifecycle.viewmodel)
7071
implementation(libs.androidx.lifecycle.runtime.compose)
72+
73+
implementation(project.dependencies.platform(libs.ktor.bom))
74+
implementation(libs.ktor.client.android)
75+
implementation(libs.ktor.client.content.negotiation)
76+
implementation(libs.ktor.serialization.kotlinx.json)
77+
implementation(libs.ktor.client.logging)
78+
implementation(libs.ktor.client.mock)
79+
implementation(libs.ktor.client.serialization)
7180
}
7281
desktopMain.dependencies {
7382
implementation(compose.desktop.currentOs)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.developersbreach.kotlindictionarymultiplatform
2+
3+
import kotlinx.serialization.Serializable
4+
import kotlinx.serialization.SerialName
5+
import kotlinx.serialization.json.JsonElement
6+
7+
@Serializable
8+
data class KotlinTopicDetails(
9+
val topicId: String,
10+
val topicName: String,
11+
val intro: String,
12+
val syntax: Syntax,
13+
val sections: List<Section>,
14+
val pitfalls: List<String> = emptyList(),
15+
val relatedTopics: List<String> = emptyList(),
16+
val metadata: Map<String, JsonElement> = emptyMap()
17+
)
18+
19+
@Serializable
20+
data class Syntax(
21+
val signature: String,
22+
val notes: String? = null
23+
)
24+
25+
@Serializable
26+
data class Section(
27+
val heading: String? = null,
28+
val content: String? = null,
29+
val codeExamples: List<CodeExample> = emptyList()
30+
)
31+
32+
@Serializable
33+
data class CodeExample(
34+
val description: String? = null,
35+
val code: String,
36+
val language: String = "kotlin"
37+
)
38+
39+
// --- Request/Response schema for OpenAI Chat Completion ---
40+
@Serializable
41+
data class ChatMessage(
42+
val role: String,
43+
val content: String
44+
)
45+
46+
@Serializable
47+
data class FunctionDefinition(
48+
val name: String,
49+
val description: String,
50+
val parameters: JsonElement
51+
)
52+
53+
@Serializable
54+
data class FunctionCall(
55+
val name: String,
56+
val arguments: String
57+
)
58+
59+
@Serializable
60+
data class ChatCompletionChoice(
61+
val message: ChatCompletionResponseMessage
62+
)
63+
64+
@Serializable
65+
data class ChatCompletionResponseMessage(
66+
val role: String,
67+
val content: String? = null,
68+
@SerialName("function_call")
69+
val functionCall: FunctionCall? = null
70+
)
71+
72+
@Serializable
73+
data class ChatCompletionResponse(
74+
val choices: List<ChatCompletionChoice>
75+
)
76+
77+
@Serializable
78+
data class ChatCompletionRequest(
79+
val model: String,
80+
val messages: List<ChatMessage>,
81+
val functions: List<FunctionDefinition>,
82+
@SerialName("function_call")
83+
val functionCall: Map<String, String>
84+
)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package com.developersbreach.kotlindictionarymultiplatform
2+
3+
import io.ktor.client.HttpClient
4+
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
5+
import io.ktor.client.request.header
6+
import io.ktor.client.request.post
7+
import io.ktor.client.request.setBody
8+
import io.ktor.client.statement.HttpResponse
9+
import io.ktor.client.statement.bodyAsText
10+
import io.ktor.http.ContentType
11+
import io.ktor.http.HttpHeaders
12+
import io.ktor.http.contentType
13+
import io.ktor.serialization.kotlinx.json.json
14+
import kotlinx.serialization.json.Json
15+
import kotlinx.serialization.json.decodeFromJsonElement
16+
import kotlinx.serialization.json.jsonObject
17+
18+
19+
object KtorHttpClient {
20+
private val json = Json { ignoreUnknownKeys = true }
21+
22+
private val client = HttpClient {
23+
install(ContentNegotiation) {
24+
json()
25+
}
26+
}
27+
28+
private val functionSchema = json.parseToJsonElement(
29+
// Paste the full JSON schema for your function here
30+
"""
31+
{
32+
"type": "object",
33+
"properties": {
34+
"topicId": { "type": "string" },
35+
"topicName": { "type": "string" },
36+
"intro": { "type": "string" },
37+
"syntax": {
38+
"type": "object",
39+
"properties": {
40+
"signature": { "type": "string" },
41+
"notes": { "type": "string" }
42+
},
43+
"required": ["signature"]
44+
},
45+
"sections": {
46+
"type": "array",
47+
"items": {
48+
"type": "object",
49+
"properties": {
50+
"heading": { "type": "string" },
51+
"content": { "type": "string" },
52+
"codeExamples": {
53+
"type": "array",
54+
"items": {
55+
"type": "object",
56+
"properties": {
57+
"description": { "type": "string" },
58+
"code": { "type": "string" },
59+
"language": { "type": "string" }
60+
},
61+
"required": ["code"]
62+
}
63+
}
64+
},
65+
"required": ["heading","content"]
66+
}
67+
},
68+
"pitfalls": { "type": "array", "items": { "type": "string" } },
69+
"relatedTopics": { "type": "array", "items": { "type": "string" } },
70+
"metadata": { "type": "object", "additionalProperties": true }
71+
},
72+
"required": ["topicId","topicName","intro","syntax","sections"]
73+
}
74+
""".trimIndent()
75+
)
76+
77+
private val functionDef = FunctionDefinition(
78+
name = "generate_kotlin_topic_details",
79+
description = "Return a fully-featured Kotlin documentation object for a given topic",
80+
parameters = functionSchema
81+
)
82+
83+
/**
84+
* Calls the OpenAI ChatCompletion with function-calling to get topic details.
85+
* @param topicId the topic identifier, e.g. "variables".
86+
* @param apiKey your OpenAI API key.
87+
*/
88+
suspend fun generateTopicDetails(topicId: String, apiKey: String): KotlinTopicDetails {
89+
// Prepare messages
90+
val messages = listOf(
91+
ChatMessage("system", "You are a Kotlin documentation generator."),
92+
ChatMessage("user", "Generate full Kotlin documentation for topic \"$topicId\".")
93+
)
94+
95+
// Build request body
96+
val request = ChatCompletionRequest(
97+
model = "gpt-4o-mini",
98+
messages = messages,
99+
functions = listOf(functionDef),
100+
functionCall = mapOf("name" to functionDef.name)
101+
)
102+
103+
// Execute HTTP request
104+
val response: HttpResponse = client.post("https://api.openai.com/v1/chat/completions") {
105+
header(HttpHeaders.Authorization, "Bearer $apiKey")
106+
contentType(ContentType.Application.Json)
107+
setBody(json.encodeToString(ChatCompletionRequest.serializer(), request))
108+
}
109+
110+
val text = response.bodyAsText()
111+
println("RAW RESPONSE:\n$text")
112+
113+
// Parse response
114+
val chatResp = json.decodeFromString(ChatCompletionResponse.serializer(), text)
115+
val funcCall = chatResp.choices.first().message.functionCall ?: error("No function call in response")
116+
117+
// The arguments field is a JSON string: parse and decode into our DTO
118+
val argsJson = json.parseToJsonElement(funcCall.arguments)
119+
return json.decodeFromJsonElement(argsJson.jsonObject)
120+
}
121+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.developersbreach.kotlindictionarymultiplatform
2+
3+
const val API_KEY =""
4+
5+
suspend fun main() {
6+
val details = KtorHttpClient.generateTopicDetails("variables", API_KEY)
7+
println(details)
8+
}

gradle/libs.versions.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ compose-multiplatform = "1.7.3"
1515
junit = "4.13.2"
1616
kotlin = "2.1.10"
1717
kotlinx-coroutines = "1.10.1"
18+
ktor-bom = "3.0.1"
1819

1920
[libraries]
2021
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
@@ -30,10 +31,18 @@ androidx-activity-compose = { module = "androidx.activity:activity-compose", ver
3031
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
3132
androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
3233
kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
34+
ktor-bom = { module = "io.ktor:ktor-bom", version.ref = "ktor-bom" }
35+
ktor-client-android = { module = "io.ktor:ktor-client-android" }
36+
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation" }
37+
ktor-client-logging = { module = "io.ktor:ktor-client-logging" }
38+
ktor-client-mock = { module = "io.ktor:ktor-client-mock" }
39+
ktor-client-serialization = { module = "io.ktor:ktor-client-serialization" }
40+
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json" }
3341

3442
[plugins]
3543
androidApplication = { id = "com.android.application", version.ref = "agp" }
3644
androidLibrary = { id = "com.android.library", version.ref = "agp" }
3745
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
3846
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
39-
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
47+
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
48+
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

0 commit comments

Comments
 (0)