fix: todos scan task ballooned to 2.5MB and analysis produced no output
The todos pre-scan walked .output/ (Nitro) and .vercel/ (Vercel) build dirs, flagging 119 of 124 candidates inside minified bundles (single lines up to 162KB). buildTodosScanTask embedded full candidate lines in the task prompt, producing a 2.5MB prompt on freno-dev; the analysis agent settled with ok:true + empty text + no findings.md, verify failed, and resume re-ran the same oversized prompt and failed identically. - scope: exclude .output/.vercel/.netlify (shared by all checks) - todos: truncate candidate code at 160 chars in the prompt + fallback - agent-runner: a session settling with no text and no observed message/ tool events now fails the run loudly instead of reporting ok:true - agent prompts: add the three dirs to each skip list - tests: excluded-dir scan, prompt truncation, emptySessionError cases
This commit is contained in:
@@ -256,16 +256,15 @@ async function runSessionToCompletion(
|
||||
unsubscribe();
|
||||
// Surface session errors that didn't throw but left no useful output.
|
||||
// A session ending with stopReason "error" and no text means the model
|
||||
// call failed silently — treat that as a failed run, not ok:true.
|
||||
if (acc.errorMessage) {
|
||||
return { ok: false, text: acc.text, error: acc.errorMessage };
|
||||
}
|
||||
if (!acc.text.trim() && acc.stopReason === "error") {
|
||||
return {
|
||||
ok: false,
|
||||
text: acc.text,
|
||||
error: "sub-agent session ended in error with no output.",
|
||||
};
|
||||
// call failed silently — treat that as a failed run, not ok:true. A
|
||||
// session that settled with NO text and NO observed events means the
|
||||
// model never produced anything at all (dead provider stream, failed
|
||||
// start) — reporting that as a successful analysis would let an empty
|
||||
// scan masquerade as a clean one, and the check's verify hook would
|
||||
// fail only later with a confusing "artifact missing" error.
|
||||
const sessionError = emptySessionError(acc);
|
||||
if (sessionError) {
|
||||
return { ok: false, text: acc.text, error: sessionError };
|
||||
}
|
||||
return { ok: true, text: acc.text };
|
||||
} catch (err) {
|
||||
@@ -287,12 +286,34 @@ async function runSessionToCompletion(
|
||||
export interface SessionEventAccumulator {
|
||||
/** Joined assistant text seen so far (text_delta stream). */
|
||||
text: string;
|
||||
/** Whether any assistant-message or tool event was observed at all. */
|
||||
sawMessage: boolean;
|
||||
/** stopReason of the final assistant message, when reported. */
|
||||
stopReason?: string;
|
||||
/** errorMessage of the final assistant message, when reported. */
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Classify a settled session's capture: `undefined` when the result is a
|
||||
* legitimate (possibly empty-text) outcome, else the error that should fail
|
||||
* the run. Kept pure so the decision is unit-testable without a session.
|
||||
*/
|
||||
export function emptySessionError(
|
||||
acc: SessionEventAccumulator,
|
||||
): string | undefined {
|
||||
if (acc.errorMessage) return acc.errorMessage;
|
||||
if (!acc.text.trim()) {
|
||||
if (acc.stopReason === "error") {
|
||||
return "sub-agent session ended in error with no output.";
|
||||
}
|
||||
if (!acc.sawMessage) {
|
||||
return "sub-agent session settled with no output — no assistant message or tool activity was observed. Check model/provider connectivity, then resume.";
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret one session event into the running accumulator and forward the
|
||||
* stream-driving events to the chat.
|
||||
@@ -313,6 +334,16 @@ export function applySessionEvent(
|
||||
): void {
|
||||
if (!event) return;
|
||||
try {
|
||||
// Any message or tool event means the session actually ran — a settled
|
||||
// capture with none of these is a dead session, not an empty scan.
|
||||
if (
|
||||
event.type === "message_update" ||
|
||||
event.type === "message_end" ||
|
||||
event.type === "tool_execution_start" ||
|
||||
event.type === "tool_execution_end"
|
||||
) {
|
||||
acc.sawMessage = true;
|
||||
}
|
||||
if (
|
||||
event.type === "message_update" &&
|
||||
event.assistantMessageEvent?.type === "text_delta"
|
||||
|
||||
Reference in New Issue
Block a user