Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions mcp/src/lab/eval/steps/evolve-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ function num(v: unknown): number | undefined {
return typeof v === "number" && Number.isFinite(v) ? v : undefined;
}

/**
* Authors occasionally end schema mode on a bare text turn, echoing filler
* ("placeholder", "") into `summary`. Junk there poisons every later
* briefing — the EXPLORE directive's "pick an approach that is none of the
* above" is only checkable against real summaries — and the report the
* human reads. Replace it with an honest marker instead of passing it
* through. (The version echo has its own fallback in the gen workflows;
* this is the summary-channel counterpart.)
*/
const NO_SUMMARY =
"(no usable approach summary reported by this generation's author — read this version's YAML diff to see what it changed)";
function usableSummary(v: unknown): string | undefined {
if (typeof v !== "string") return undefined;
const t = v.trim();
if (t.length < 8) return undefined;
if (/^(placeholder|todo|tbd|n\/?a|none|null|summary|unknown)[.!]?$/i.test(t)) return undefined;
return t;
}

function indent(s: string, pad: string): string {
return s
.split("\n")
Expand Down Expand Up @@ -266,7 +285,7 @@ export default defineStep({
genRunId: String((journaled["runs"] as AnyRec[] | undefined)?.[0]?.["runId"] ?? ""),
version: typeof journaled["version"] === "string" ? (journaled["version"] as string) : undefined,
fitness,
summary: typeof journaled["summary"] === "string" ? (journaled["summary"] as string) : undefined,
summary: usableSummary(journaled["summary"]) ?? NO_SUMMARY,
digestText: typeof journaled["digestText"] === "string" ? (journaled["digestText"] as string) : undefined,
explore: journaled["directive"] === "explore",
};
Expand Down Expand Up @@ -350,7 +369,7 @@ export default defineStep({
version: typeof out["version"] === "string" ? (out["version"] as string) : undefined,
fitness,
allPassCount: num(digest["allPassCount"]),
summary: typeof out["summary"] === "string" ? (out["summary"] as string) : undefined,
summary: usableSummary(out["summary"]) ?? NO_SUMMARY,
changes: out["changes"],
missingSecrets: out["missingSecrets"],
digestText: typeof digest["text"] === "string" ? (digest["text"] as string) : undefined,
Expand Down
15 changes: 13 additions & 2 deletions mcp/src/lab/gaia/evolve-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ async function main() {
output: {
candidate: input.candidateName,
version: `v${g + 1}`,
summary: `approach ${g}`,
// gen 0 echoes filler (the observed schema-mode failure); the
// loop must replace it with the honest no-summary marker.
summary: g === 0 ? "placeholder" : `approach ${g}`,
authorCost: 1,
digest: { fitness: rates[g], text: `digest ${g}`, results: [{ cost: 2 }] },
},
Expand Down Expand Up @@ -224,7 +226,16 @@ async function main() {
assert.ok(genCalls[1].briefing.includes('the seeded produce workflow "gaia-produce"'));
// margin 0 semantics: a TIE (0.4 vs baseline 0.4) does not become best
assert.ok(genCalls[1].briefing.includes("BEST SO FAR: the baseline itself"));
console.log("✔ eval/evolve-loop: climbs gaia `fitness`, accuracy naming, margin-0 tie handling");
// junk-summary guard: gen 0's "placeholder" echo must NOT reach the next
// briefing or the report — both carry the honest no-summary marker.
assert.ok(!genCalls[1].briefing.includes("placeholder"));
assert.ok(genCalls[1].briefing.includes("no usable approach summary"));
assert.equal(
loopOut.generations[0].summary.includes("no usable approach summary"),
true,
);
assert.equal(loopOut.generations[1].summary, "approach 1");
console.log("✔ eval/evolve-loop: climbs gaia `fitness`, accuracy naming, margin-0 tie handling, junk-summary guard");

console.log("\nALL GAIA EVOLVE VALIDATION CHECKS PASSED");
} finally {
Expand Down
8 changes: 8 additions & 0 deletions mcp/src/lab/gaia/workflows/gaia-evolve-gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,11 @@ params:
final healthy publish, a summary of the APPROACH this generation took
(the next generation reads it to know what has been tried), the list of
changes, and any missing secrets.

Your structured answer is harvested from your FINAL message — the turn
where you stop calling tools. Fill every field with REAL values then:
never filler like "placeholder" or an empty summary. That summary is
the only record of this generation's approach the next generation and
the human report ever see; a generation whose approach is unreadable
gets retried by later generations, wasting their budget. If you run
out of steps, still describe truthfully whatever you actually shipped.
8 changes: 8 additions & 0 deletions mcp/src/lab/harvey/workflows/harvey-evolve-gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,11 @@ params:
final healthy publish, a summary of the APPROACH this generation took
(the next generation reads it to know what has been tried), the list of
changes, and any missing secrets.

Your structured answer is harvested from your FINAL message — the turn
where you stop calling tools. Fill every field with REAL values then:
never filler like "placeholder" or an empty summary. That summary is
the only record of this generation's approach the next generation and
the human report ever see; a generation whose approach is unreadable
gets retried by later generations, wasting their budget. If you run
out of steps, still describe truthfully whatever you actually shipped.
Loading