fix(builtin): deadline warning + graceful exit on turn limit
- Inject user message when 3 turns remain, telling agent to wrap up - Prompt tells agent to use status:failed if it can't finish in time - Prevents wasting all turns without producing any frontmatter output - Remove stale test file from dogfood agent run
This commit is contained in:
@@ -48,7 +48,7 @@ async function appendTurn(
|
||||
await appendSessionTurn(storageRoot, sessionId, payload);
|
||||
}
|
||||
|
||||
async function executeTurnTools(
|
||||
export async function executeTurnTools(
|
||||
calls: Array<{ id: string; name: string; arguments: string }>,
|
||||
toolCtx: ToolContext,
|
||||
messages: ChatMessage[],
|
||||
@@ -70,6 +70,17 @@ async function executeTurnTools(
|
||||
return turnCount;
|
||||
}
|
||||
|
||||
export type ShouldNudgeOptions = {
|
||||
noTools: boolean;
|
||||
text: string;
|
||||
turn: number;
|
||||
maxTurns: number;
|
||||
};
|
||||
|
||||
export function shouldNudge({ noTools, text, turn, maxTurns }: ShouldNudgeOptions): boolean {
|
||||
return !noTools && !text.trimStart().startsWith("---") && turn < maxTurns - 1;
|
||||
}
|
||||
|
||||
/** Agent run loop: LLM ↔ tools until no tool_calls or maxTurns. */
|
||||
export async function runBuiltinLoop(
|
||||
options: RunBuiltinLoopOptions,
|
||||
@@ -88,7 +99,6 @@ export async function runBuiltinLoop(
|
||||
);
|
||||
|
||||
// When noTools is set, ignore any tool_calls the LLM might still return
|
||||
// (some providers infer tools from message history even when tools field is omitted)
|
||||
const effectiveToolCalls = options.noTools ? null : (response.toolCalls ?? null);
|
||||
|
||||
const assistantMessage: ChatMessage = {
|
||||
@@ -108,9 +118,7 @@ export async function runBuiltinLoop(
|
||||
});
|
||||
turnCount += 1;
|
||||
|
||||
// If tools are available but LLM stopped calling them without producing
|
||||
// frontmatter, nudge it to continue working or output frontmatter.
|
||||
if (!options.noTools && !text.trimStart().startsWith("---") && turn < options.maxTurns - 1) {
|
||||
if (shouldNudge({ noTools: options.noTools, text, turn, maxTurns: options.maxTurns })) {
|
||||
log("7FXQM2KN", "text-only turn without frontmatter, nudging LLM to continue");
|
||||
const nudge =
|
||||
"You stopped calling tools but your response does not start with the required `---` YAML frontmatter. " +
|
||||
|
||||
@@ -70,6 +70,7 @@ export function buildBuiltinMessages(ctx: AgentContext): ChatMessage[] {
|
||||
"Your task is described in the user message below — do NOT use uwf or workflow CLI commands to discover your task. " +
|
||||
"When you are done, output your final response with the YAML frontmatter block as specified above. " +
|
||||
"Do NOT output the frontmatter until you have completed all necessary work. " +
|
||||
"If you are running low on turns and cannot finish, output the frontmatter with `status: failed` and explain what remains in the body. " +
|
||||
"CRITICAL: Your final output MUST start with the `---` fence on the very first line — " +
|
||||
"no preamble text, no explanation before it. The parser requires `---` at position 0.",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user