fix(coding-agent/session): skipped empty thinking entries when formatting session dumps

- Updated `formatSessionDumpText` to skip `thinking` entries with empty or whitespace-only content.
- Prevented empty `<thinking>` sections from being emitted in session dump output.
This commit is contained in:
can1357
2026-04-29 20:25:33 +02:00
parent 6924cf67b8
commit a188651f63
3 changed files with 65 additions and 22 deletions
@@ -91,4 +91,7 @@ $
- This is **NOT** unified diff. Never send `@@`, `-OLD` / `+NEW` pairs, or unchanged context.
- Never split `Lid=TEXT` across two physical lines.
- Never stack `Lid=X` over a contiguous range. Use `-Lid`+`+TEXT` for block rewrites.
- `@Lid` only positions the insert cursor for subsequent `+TEXT` ops. It does **NOT** scope, contextualize, or make later `-` / `Lid=` ops relative.
- There are no counts, ranges, or relative offsets. Every `-` and `Lid=` op carries its own absolute Lid that **MUST** appear verbatim in the most recent read of that exact file. Tokens like `-1`, `-1xx`, or fabricated 2-letter hashes are invalid.
- To replace a single line, use `Lid=NEWTEXT`. Do **NOT** emit a diff-shaped `@Lid` / `-TOKEN` / `+TEXT` triple — that pattern is unified-diff, not this language.
</critical>
@@ -114,6 +114,7 @@ export function formatSessionDumpText(options: FormatSessionDumpTextOptions): st
if (c.type === "text") {
lines.push(c.text);
} else if (c.type === "thinking") {
if (c.thinking.trim().length === 0) continue;
lines.push("<thinking>");
lines.push(c.thinking);
lines.push("</thinking>\n");
+61 -22
View File
@@ -51,9 +51,8 @@ from omp_rpc import ( # noqa: E402
MODELS = [
"openrouter/moonshotai/kimi-k2.5",
"openrouter/anthropic/claude-haiku-4.5",
"openrouter/anthropic/claude-sonnet-4.6",
"openrouter/z-ai/glm-5-turbo",
"openrouter/minimax/minimax-m2.7",
"openrouter/z-ai/glm-4.7",
"openai-codex/gpt-5.4"
]
ORACLE_MODEL = "openrouter/anthropic/claude-opus-4.6"
@@ -1825,6 +1824,18 @@ def oracle_sources_from_dir(results_dir: Path) -> list[tuple[str, str, str]]:
return sources
def format_combined_reviews(sources: list[tuple[str, str, str]]) -> str:
sections: list[str] = []
for model, _fixture, review_path in sorted(sources):
review_text = Path(review_path).read_text(encoding="utf-8").strip()
if not review_text:
continue
bar = "=" * 13
header = f"{bar} {model} {bar}"
sections.append(f"{header}\n\n{review_text}")
return "\n\n".join(sections)
def run_oracle_review_sync(
*,
model: str,
@@ -1883,19 +1894,30 @@ def parse_args() -> argparse.Namespace:
default=ORACLE_MODEL,
help="Model used to synthesize findings across all reviews.",
)
parser.add_argument(
"--oracle",
action="store_true",
help="Synthesize findings across reviews using --oracle-model (default: skip synthesis and emit combined reviews).",
)
parser.add_argument(
"--rerun-oracle",
dest="rerun_oracle",
help="Skip fixture runs and only synthesize against review_*.md files in this existing results dir.",
)
parser.add_argument(
"--rerun",
dest="rerun",
help="Skip fixture runs and emit combined reviews from review_*.md files in this existing results dir.",
)
return parser.parse_args()
async def run_all(args: argparse.Namespace) -> int:
omp_bin = resolve_omp_bin(args.omp_bin)
if args.rerun_oracle:
results_dir = Path(args.rerun_oracle).expanduser()
if args.rerun or args.rerun_oracle:
rerun_path = args.rerun_oracle or args.rerun
results_dir = Path(rerun_path).expanduser()
if not results_dir.is_dir():
print(f"Results dir not found: {results_dir}", file=sys.stderr)
return 1
@@ -1903,22 +1925,27 @@ async def run_all(args: argparse.Namespace) -> int:
if not sources:
print(f"No review_*.md files found in {results_dir}", file=sys.stderr)
return 1
try:
synthesis = await asyncio.to_thread(
run_oracle_review_sync,
model=args.oracle_model,
omp_bin=omp_bin,
sources=sources,
results_dir=results_dir,
timeout=args.timeout,
)
except (RpcError, RpcProcessExitError) as exc:
err = f"{type(exc).__name__}: {exc}"
(results_dir / "oracle_error.txt").write_text(err + "\n", encoding="utf-8")
print(f"Oracle synthesis FAILED: {err}", file=sys.stderr)
print(f"Saved error to {results_dir}/oracle_error.txt", file=sys.stderr)
return 2
print(synthesis)
if args.rerun_oracle:
try:
synthesis = await asyncio.to_thread(
run_oracle_review_sync,
model=args.oracle_model,
omp_bin=omp_bin,
sources=sources,
results_dir=results_dir,
timeout=args.timeout,
)
except (RpcError, RpcProcessExitError) as exc:
err = f"{type(exc).__name__}: {exc}"
(results_dir / "oracle_error.txt").write_text(err + "\n", encoding="utf-8")
print(f"Oracle synthesis FAILED: {err}", file=sys.stderr)
print(f"Saved error to {results_dir}/oracle_error.txt", file=sys.stderr)
return 2
print(synthesis)
return 0
combined = format_combined_reviews(sources)
(results_dir / "combined_reviews.md").write_text(combined + "\n", encoding="utf-8")
print(combined)
return 0
fixtures_dir = Path(args.fixtures_dir).expanduser()
@@ -1959,12 +1986,24 @@ async def run_all(args: argparse.Namespace) -> int:
printer.finish(f"{failures}/{len(results)} run(s) failed")
return 1
sources = oracle_sources_from_results(results)
combined = format_combined_reviews(sources)
(results_dir / "combined_reviews.md").write_text(combined + "\n", encoding="utf-8")
if not args.oracle:
printer.finish(
f"{len(results)} review file(s) saved to {results_dir}.\n"
f"Combined reviews saved to {results_dir}/combined_reviews.md."
)
print(combined)
return 0
try:
oracle_synthesis = await asyncio.to_thread(
run_oracle_review_sync,
model=args.oracle_model,
omp_bin=omp_bin,
sources=oracle_sources_from_results(results),
sources=sources,
results_dir=results_dir,
timeout=args.timeout,
)