fix(context): name emit_artifact in the schema instruction (#416)
The pinned schemaInstruction said only "Respond with a single JSON object matching this schema", contradicting every role prompt that says to emit via the emit_artifact tool. Two stated channels for one artifact, and the pinned one won. ResponseFormat.Json is built under exactly the condition that offers the tool (an llmEmitted slot — see emitArtifactTool), so the tool is always available wherever this instruction renders, and the kernel prefers it: tool-calling models are more reliable at it and it sidesteps llama.cpp's grammar+tools incompatibility. The instruction now names it, and keeps raw JSON as what to do when told to stop calling tools — which is what the tools-less final pass demands and what the executor already accepts either way (llmArtifactOverride ?: response.text). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+12
-2
@@ -52,11 +52,21 @@ internal fun SessionOrchestrator.evictArtifactContentCache(sessionId: SessionId)
|
|||||||
internal suspend fun SessionOrchestrator.buildSchemaEntries(
|
internal suspend fun SessionOrchestrator.buildSchemaEntries(
|
||||||
responseFormat: ResponseFormat,
|
responseFormat: ResponseFormat,
|
||||||
stageId: StageId,
|
stageId: StageId,
|
||||||
|
artifactName: String,
|
||||||
): List<ContextEntry> {
|
): List<ContextEntry> {
|
||||||
if (responseFormat !is ResponseFormat.Json) return emptyList()
|
if (responseFormat !is ResponseFormat.Json) return emptyList()
|
||||||
val compactSchema = Json.encodeToString(JsonSchema.serializer(), responseFormat.schema)
|
val compactSchema = Json.encodeToString(JsonSchema.serializer(), responseFormat.schema)
|
||||||
val instruction = "Respond with a single JSON object matching this schema. " +
|
// #416: names emit_artifact as the channel. ResponseFormat.Json is emitted under exactly the
|
||||||
"Do not include markdown, code fences, or commentary outside the JSON. " +
|
// condition that offers the tool (an llmEmitted slot — see emitArtifactTool), so the tool is
|
||||||
|
// always available here, and the kernel prefers it: tool-calling models are more reliable at it
|
||||||
|
// and it sidesteps llama.cpp's grammar+tools incompatibility. The old text said only "respond
|
||||||
|
// with a single JSON object", contradicting every role prompt that says to call emit_artifact.
|
||||||
|
// Raw JSON stays valid as the second sentence describes, since the executor accepts either
|
||||||
|
// (llmArtifactOverride ?: response.text) and the tools-less final pass explicitly demands it.
|
||||||
|
val instruction = "Produce the '$artifactName' artifact by calling the $EMIT_ARTIFACT_TOOL tool " +
|
||||||
|
"with its fields filled in, matching this schema. If you are told to stop calling tools, " +
|
||||||
|
"output the same object as a single JSON object in your final message instead. Either way, " +
|
||||||
|
"no markdown, no code fences, and no commentary outside the JSON. " +
|
||||||
"Schema: $compactSchema"
|
"Schema: $compactSchema"
|
||||||
return listOf(
|
return listOf(
|
||||||
ContextEntry(
|
ContextEntry(
|
||||||
|
|||||||
+5
-1
@@ -152,7 +152,11 @@ internal suspend fun SessionOrchestrator.executeStage(
|
|||||||
?.let { ResponseFormat.Json(it.kind.deriveJsonSchema()) }
|
?.let { ResponseFormat.Json(it.kind.deriveJsonSchema()) }
|
||||||
?: ResponseFormat.Text
|
?: ResponseFormat.Text
|
||||||
|
|
||||||
val schemaEntries = buildSchemaEntries(responseFormat, stageId)
|
val schemaEntries = buildSchemaEntries(
|
||||||
|
responseFormat,
|
||||||
|
stageId,
|
||||||
|
llmEmittedSlots.firstOrNull()?.name?.value ?: "",
|
||||||
|
)
|
||||||
val intentEntries = buildIntentEntry(sessionId)
|
val intentEntries = buildIntentEntry(sessionId)
|
||||||
val steeringEntries = buildSteeringNoteEntries(sessionId)
|
val steeringEntries = buildSteeringNoteEntries(sessionId)
|
||||||
val clarificationEntries = buildClarificationAnswerEntries(sessionId)
|
val clarificationEntries = buildClarificationAnswerEntries(sessionId)
|
||||||
|
|||||||
Reference in New Issue
Block a user