fix: store actual rendered prompt artifact instead of contextpack.toString()
Extract message-rendering logic from LlamaCppInferenceProvider into a provider-agnostic PromptRenderer in core:inference. SessionOrchestrator now serializes the rendered ChatMessage list as JSON for the prompt artifact, so the audit trail reflects what the LLM actually saw. Resolves the TODO at SessionOrchestrator.kt:691.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package com.correx.core.inference
|
||||
|
||||
import com.correx.core.context.model.ContextLayer
|
||||
import com.correx.core.context.model.ContextPack
|
||||
import com.correx.core.context.model.EntryRole
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ChatMessage(
|
||||
val role: String,
|
||||
val content: String,
|
||||
)
|
||||
|
||||
object PromptRenderer {
|
||||
fun render(contextPack: ContextPack): List<ChatMessage> {
|
||||
val sorted = contextPack.layers.entries.sortedBy { it.key.ordinal }
|
||||
val systemContent = sorted
|
||||
.filter { it.key == ContextLayer.L0 }
|
||||
.flatMap { it.value }
|
||||
.joinToString("\n\n") { it.content }
|
||||
.takeIf { it.isNotBlank() }
|
||||
val conversationMessages = sorted.filter { it.key != ContextLayer.L0 }.flatMap { (_, entries) ->
|
||||
entries.map { entry ->
|
||||
ChatMessage(
|
||||
role = when (entry.role) {
|
||||
EntryRole.SYSTEM -> "system"
|
||||
EntryRole.ASSISTANT -> "assistant"
|
||||
EntryRole.TOOL -> "tool"
|
||||
EntryRole.USER -> "user"
|
||||
},
|
||||
content = entry.content,
|
||||
)
|
||||
}
|
||||
}
|
||||
val messages = buildList {
|
||||
systemContent?.let { add(ChatMessage("system", it)) }
|
||||
addAll(conversationMessages)
|
||||
}
|
||||
return messages.ifEmpty { listOf(ChatMessage("user", "")) }
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -61,6 +61,7 @@ import com.correx.core.inference.InferenceRepository
|
||||
import com.correx.core.inference.InferenceRequest
|
||||
import com.correx.core.inference.InferenceResponse
|
||||
import com.correx.core.inference.InferenceRouter
|
||||
import com.correx.core.inference.PromptRenderer
|
||||
import com.correx.core.inference.ResponseFormat
|
||||
import com.correx.core.inference.Tokenizer
|
||||
import com.correx.core.inference.ToolCallRequest
|
||||
@@ -91,6 +92,7 @@ import kotlinx.coroutines.TimeoutCancellationException
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import org.slf4j.LoggerFactory
|
||||
@@ -688,8 +690,8 @@ abstract class SessionOrchestrator(
|
||||
),
|
||||
)
|
||||
|
||||
// TODO: capture rendered prompt; currently contextpack.toString()
|
||||
val promptArtifactId = artifactStore.put(contextPack.toString().toByteArray())
|
||||
val renderedMessages = PromptRenderer.render(contextPack)
|
||||
val promptArtifactId = artifactStore.put(Json.encodeToString(renderedMessages).toByteArray())
|
||||
emit(sessionId, InferenceStartedEvent(requestId, sessionId, stageId, provider.id, promptArtifactId))
|
||||
|
||||
if (isCancelled(sessionId)) return InferenceResult.Cancelled
|
||||
|
||||
Reference in New Issue
Block a user