feat(inference): capture reasoning_content on responses (WIP, provider side)
Adds a nullable `reasoning` field to InferenceResponse and maps the llama.cpp / OpenAI-compat `reasoning_content` field into it, so local models that emit their chain-of-thought have it captured. Provider/model side only — the emit-site event field (reasoningArtifactId) + CAS storage in the orchestrator are still pending (tracked in Vikunja Correx #4).
This commit is contained in:
@@ -11,4 +11,8 @@ data class InferenceResponse(
|
|||||||
val tokensUsed: TokenUsage,
|
val tokensUsed: TokenUsage,
|
||||||
val latencyMs: Long,
|
val latencyMs: Long,
|
||||||
val toolCalls: List<ToolCallRequest> = emptyList(),
|
val toolCalls: List<ToolCallRequest> = emptyList(),
|
||||||
|
// The model's chain-of-thought, when the provider exposes it separately (llama.cpp / OpenAI-compat
|
||||||
|
// `reasoning_content`). Captured for observability/audit — many local models emit their whole plan
|
||||||
|
// here and leave `text` empty, so dropping it hid why a stage behaved as it did (2026-07-05).
|
||||||
|
val reasoning: String? = null,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
@@ -24,6 +24,7 @@ data class ChatCompletionRequest(
|
|||||||
data class LlamaCppChatMessage(
|
data class LlamaCppChatMessage(
|
||||||
val role: String,
|
val role: String,
|
||||||
val content: String?,
|
val content: String?,
|
||||||
|
@SerialName("reasoning_content") val reasoningContent: String? = null,
|
||||||
@SerialName("tool_calls") val toolCalls: List<ToolCallRequest> = emptyList(),
|
@SerialName("tool_calls") val toolCalls: List<ToolCallRequest> = emptyList(),
|
||||||
@SerialName("tool_call_id") val toolCallId: String? = null,
|
@SerialName("tool_call_id") val toolCallId: String? = null,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
@@ -215,6 +215,7 @@ class LlamaCppInferenceProvider(
|
|||||||
),
|
),
|
||||||
latencyMs = System.currentTimeMillis() - startTime,
|
latencyMs = System.currentTimeMillis() - startTime,
|
||||||
toolCalls = toolCalls,
|
toolCalls = toolCalls,
|
||||||
|
reasoning = message.reasoningContent?.takeIf { it.isNotBlank() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -28,6 +28,7 @@ data class OpenAiChatCompletionRequest(
|
|||||||
data class OpenAiChatMessage(
|
data class OpenAiChatMessage(
|
||||||
val role: String,
|
val role: String,
|
||||||
val content: String? = null,
|
val content: String? = null,
|
||||||
|
@SerialName("reasoning_content") val reasoningContent: String? = null,
|
||||||
@SerialName("tool_calls") val toolCalls: List<ToolCallRequest> = emptyList(),
|
@SerialName("tool_calls") val toolCalls: List<ToolCallRequest> = emptyList(),
|
||||||
@SerialName("tool_call_id") val toolCallId: String? = null,
|
@SerialName("tool_call_id") val toolCallId: String? = null,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user