fix: workflow inference chain — surface llama-server errors, user-turn-last, bundle-relative prompts

- LlamaCppInferenceProvider: check HTTP status and surface the real error body instead of masking it as a ChatCompletionResponse deserialization failure
- PromptRenderer: render the live conversation layer (L1) last so the user turn is the final message (fixes Qwen 'No user query found' 500 when L3 recall is present)
- TomlWorkflowLoader: resolve stage prompts relative to the workflow file's own dir (bundle), CWD-independent; config-dir fallback for globals
- SessionOrchestrator: hard-fail a stage whose declared prompt can't resolve (was a silent user-less request)
- move healthcheck prompts next to the example workflow (examples/workflows/prompts/)
This commit is contained in:
2026-06-01 23:23:29 +04:00
parent 55a18b4b3a
commit 94f7ad0ee9
6 changed files with 50 additions and 23 deletions
@@ -222,7 +222,7 @@ abstract class SessionOrchestrator(
} ?: emptyList()
val promptEntries = stageConfig.metadata["prompt"]
?.let { path ->
runCatching { promptResolver.resolve(path) }
val resolvedText = runCatching { promptResolver.resolve(path) }
.onFailure {
log.error(
"[SessionOrchestrator] stage=${stageId.value}: " +
@@ -230,9 +230,11 @@ abstract class SessionOrchestrator(
)
}
.getOrNull()
}
?.takeIf { it.isNotBlank() }
?.let { text ->
val text = resolvedText?.takeIf { it.isNotBlank() }
?: error(
"[SessionOrchestrator] stage=${stageId.value}: " +
"declared prompt '$path' could not be resolved",
)
listOf(
ContextEntry(
id = ContextEntryId(UUID.randomUUID().toString()),