fix: rotate Gitea token and prevent empty assistant messages in history
- Empty message fix: skip pushing assistant msg to history when both content and tool_calls are absent (GLM-5 mid-reasoning token exhaustion). Also filter preexisting empty assistant messages from returned history. - System prompt now correctly injects knowledgeContext from opts into the Tier-B system message (was missing in the loop's buildMessages). - GITEA_API_TOKEN updated externally in Coolify (old token was invalid). Made-with: Cursor
This commit is contained in:
@@ -150,10 +150,15 @@ export async function orchestratorChat(
|
|||||||
let finalReasoning: string | null = null;
|
let finalReasoning: string | null = null;
|
||||||
const toolCallNames: string[] = [];
|
const toolCallNames: string[] = [];
|
||||||
|
|
||||||
// Build messages with system prompt prepended
|
// Build system prompt — inject project knowledge if provided
|
||||||
|
const systemContent = opts?.knowledgeContext
|
||||||
|
? `${SYSTEM_PROMPT}\n\n## Project Memory (known facts)\n${opts.knowledgeContext}`
|
||||||
|
: SYSTEM_PROMPT;
|
||||||
|
|
||||||
|
// Build messages with system prompt prepended; keep last 40 for cost control
|
||||||
const buildMessages = (): LLMMessage[] => [
|
const buildMessages = (): LLMMessage[] => [
|
||||||
{ role: 'system', content: SYSTEM_PROMPT },
|
{ role: 'system', content: systemContent },
|
||||||
...session.history
|
...session.history.slice(-40)
|
||||||
];
|
];
|
||||||
|
|
||||||
while (turn < MAX_TURNS) {
|
while (turn < MAX_TURNS) {
|
||||||
@@ -171,16 +176,22 @@ export async function orchestratorChat(
|
|||||||
// Record reasoning for the final turn (informational, not stored in history)
|
// Record reasoning for the final turn (informational, not stored in history)
|
||||||
if (response.reasoning) finalReasoning = response.reasoning;
|
if (response.reasoning) finalReasoning = response.reasoning;
|
||||||
|
|
||||||
// Build assistant message to add to history
|
// Only push assistant message if it has actual content or tool calls;
|
||||||
|
// skip empty turns that result from mid-reasoning token exhaustion.
|
||||||
|
const hasContent = response.content !== null && response.content !== '';
|
||||||
|
const hasToolCalls = response.tool_calls.length > 0;
|
||||||
|
|
||||||
|
if (hasContent || hasToolCalls) {
|
||||||
const assistantMsg: LLMMessage = {
|
const assistantMsg: LLMMessage = {
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: response.content,
|
content: response.content,
|
||||||
tool_calls: response.tool_calls.length > 0 ? response.tool_calls : undefined
|
tool_calls: hasToolCalls ? response.tool_calls : undefined
|
||||||
};
|
};
|
||||||
session.history.push(assistantMsg);
|
session.history.push(assistantMsg);
|
||||||
|
}
|
||||||
|
|
||||||
// No tool calls — we have the final answer
|
// No tool calls — we have the final answer
|
||||||
if (response.tool_calls.length === 0) {
|
if (!hasToolCalls) {
|
||||||
finalReply = response.content ?? '';
|
finalReply = response.content ?? '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -221,7 +232,9 @@ export async function orchestratorChat(
|
|||||||
turns: turn,
|
turns: turn,
|
||||||
toolCalls: toolCallNames,
|
toolCalls: toolCallNames,
|
||||||
model: llm.modelId,
|
model: llm.modelId,
|
||||||
history: session.history.slice(-40),
|
history: session.history
|
||||||
|
.filter(m => m.role !== 'assistant' || m.content || m.tool_calls?.length)
|
||||||
|
.slice(-40),
|
||||||
memoryUpdates: ctx.memoryUpdates
|
memoryUpdates: ctx.memoryUpdates
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user