fix(goal): give reasoning models enough budget for the evaluator JSON

This commit is contained in:
matevip 2026-05-21 22:27:43 +08:00
parent 2a1b8cbcbf
commit 66af70388b

View File

@ -52,7 +52,15 @@ import java.util.List;
@Service
public class GoalEvaluationService {
private static final int MAX_OUTPUT_TOKENS = 400;
/**
* Token budget for the evaluator response. Reasoning-mode models
* (DeepSeek V4 Pro, Kimi for Coding, GLM-Z1, ) consume a chunk of
* this budget on internal {@code <think>} content before emitting
* the JSON answer; 400 was empirically too tight and produced
* empty responses on every reasoning provider. 2000 leaves comfort
* for ~1500 tokens of reasoning + the small JSON object we need.
*/
private static final int MAX_OUTPUT_TOKENS = 2000;
private static final int MAX_CONVERSATION_CHARS = 6_000;
private static final int MAX_TERMINAL_ANSWER_CHARS = 4_000;
/** Skip-retry template — the goal node has its own try/catch, no need to double-retry. */
@ -209,7 +217,24 @@ public class GoalEvaluationService {
|| response.getResult().getOutput() == null) {
return null;
}
return response.getResult().getOutput().getText();
var output = response.getResult().getOutput();
String text = output.getText();
if (text != null && !text.isBlank()) {
return text;
}
// Fallback for reasoning models: some providers (DeepSeek-style
// OpenAI-compatible streaming, MiMo) emit the entire output as
// `reasoning_content` and leave the regular content field empty
// when the token budget gets eaten by thinking. The JSON object
// we want often appears at the tail of the reasoning trace.
var metadata = output.getMetadata();
if (metadata != null) {
Object rc = metadata.get("reasoningContent");
if (rc instanceof String s && !s.isBlank()) {
return s;
}
}
return text;
}
/**