feat: deepseek summary agent + clean old memory logs + merge prep
This commit is contained in:
+87
-12
@@ -1,10 +1,10 @@
|
||||
#!/home/xzq/miniconda3/envs/test4py311/bin/python
|
||||
"""Scope-aware whole-job summary stage.
|
||||
"""Scope-aware whole-job summary and DeepSeek report stage.
|
||||
|
||||
Summary is an objective result index and quality-control layer. It reads all
|
||||
stage manifests in a job, groups them by scope_id, extracts key metrics and
|
||||
artifacts, and writes machine-readable and human-readable summaries. It does
|
||||
not perform deep biological interpretation.
|
||||
The deterministic layer first builds a traceable manifest/artifact index. By
|
||||
default that evidence is then passed to DeepSeek to produce the human-readable
|
||||
Chinese report. The evidence index remains a separate artifact so generated
|
||||
prose can always be audited against local results.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -16,6 +16,10 @@ from pathlib import Path
|
||||
from typing import Any, Dict, Iterable, List, Optional, Tuple
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
CONDA_BIN = "/home/xzq/miniconda3/envs/test4py311/bin"
|
||||
if CONDA_BIN not in os.environ.get("PATH", ""):
|
||||
os.environ["PATH"] = CONDA_BIN + ":" + os.environ.get("PATH", "")
|
||||
@@ -256,6 +260,10 @@ def main():
|
||||
parser.add_argument("--scope-id", help="optional explicit scope_id filter")
|
||||
parser.add_argument("--force", action="store_true", help="overwrite existing results")
|
||||
parser.add_argument("--log-file", help="log file path")
|
||||
parser.add_argument("--no-deepseek", action="store_true", help="write only the deterministic evidence index")
|
||||
parser.add_argument("--framework", help="optional Markdown framework for the DeepSeek report")
|
||||
parser.add_argument("--deepseek-model", default="", help="optional DeepSeek model override")
|
||||
parser.add_argument("--deepseek-max-tokens", type=int, default=16000)
|
||||
args = parser.parse_args()
|
||||
|
||||
manifest_path = Path(args.manifest).expanduser().resolve() if args.manifest else None
|
||||
@@ -284,11 +292,11 @@ def main():
|
||||
artifact_rows = [row for item in summaries for row in item["artifact_rows"]]
|
||||
checks = build_checks(summaries)
|
||||
|
||||
report = final_dir / f"{prefix}.summary_report.md"
|
||||
evidence_index = final_dir / f"{prefix}.summary_evidence_index.md"
|
||||
files_tsv = final_dir / f"{prefix}.summary.files.tsv"
|
||||
manifest_out = final_dir / f"{prefix}.summary.manifest.json"
|
||||
write_files_tsv(files_tsv, artifact_rows)
|
||||
write_report(report, prefix, summaries, checks, files_tsv)
|
||||
write_report(evidence_index, prefix, summaries, checks, files_tsv)
|
||||
|
||||
manifest_data = {
|
||||
"manifest_version": "1.0",
|
||||
@@ -306,22 +314,24 @@ def main():
|
||||
"summaries": summaries,
|
||||
"checks": checks,
|
||||
"artifacts": {
|
||||
"summary_report": {"path": f"final/{report.name}", "type": "markdown", "size": report.stat().st_size},
|
||||
"summary_evidence_index": {"path": f"final/{evidence_index.name}", "type": "markdown", "size": evidence_index.stat().st_size},
|
||||
"files_tsv": {"path": f"final/{files_tsv.name}", "type": "tsv", "size": files_tsv.stat().st_size},
|
||||
},
|
||||
}
|
||||
manifest_out.write_text(json.dumps(manifest_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
|
||||
scoped_manifest = None
|
||||
scoped_data = None
|
||||
if scope_id:
|
||||
scoped_items = [x for x in summaries if x["scope_id"] == scope_id]
|
||||
scoped_rows = [row for x in scoped_items for row in x["artifact_rows"]]
|
||||
scoped_checks = [x for x in checks if x["scope_id"] in {scope_id, "all"}]
|
||||
token = sanitize_token(scope_id)
|
||||
scoped_report = final_dir / f"{prefix}.{token}.summary_report.md"
|
||||
scoped_evidence_index = final_dir / f"{prefix}.{token}.summary_evidence_index.md"
|
||||
scoped_files = final_dir / f"{prefix}.{token}.summary.files.tsv"
|
||||
scoped_manifest = final_dir / f"{prefix}.{token}.summary.manifest.json"
|
||||
write_files_tsv(scoped_files, scoped_rows)
|
||||
write_report(scoped_report, prefix, scoped_items, scoped_checks, scoped_files)
|
||||
write_report(scoped_evidence_index, prefix, scoped_items, scoped_checks, scoped_files)
|
||||
scoped_data = dict(manifest_data)
|
||||
scoped_data.update({
|
||||
"scope_id": scope_id,
|
||||
@@ -334,14 +344,79 @@ def main():
|
||||
"summaries": scoped_items,
|
||||
"checks": scoped_checks,
|
||||
"artifacts": {
|
||||
"summary_report": {"path": f"final/{scoped_report.name}", "type": "markdown", "size": scoped_report.stat().st_size},
|
||||
"summary_evidence_index": {"path": f"final/{scoped_evidence_index.name}", "type": "markdown", "size": scoped_evidence_index.stat().st_size},
|
||||
"files_tsv": {"path": f"final/{scoped_files.name}", "type": "tsv", "size": scoped_files.stat().st_size},
|
||||
},
|
||||
})
|
||||
scoped_manifest.write_text(json.dumps(scoped_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
|
||||
if args.no_deepseek:
|
||||
fallback_report = final_dir / (
|
||||
f"{prefix}.{sanitize_token(scope_id)}.summary_report.md" if scope_id else f"{prefix}.summary_report.md"
|
||||
)
|
||||
source_index = scoped_evidence_index if scope_id else evidence_index
|
||||
fallback_report.write_text(source_index.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
target_manifest = scoped_manifest if scope_id and scoped_manifest else manifest_out
|
||||
target_data = read_json(target_manifest) or manifest_data
|
||||
target_data.setdefault("artifacts", {})["summary_report"] = {
|
||||
"path": f"final/{fallback_report.name}",
|
||||
"type": "markdown",
|
||||
"size": fallback_report.stat().st_size,
|
||||
"generation": "deterministic_no_deepseek",
|
||||
}
|
||||
target_data["deepseek_generation"] = {"status": "skipped", "reason": "--no-deepseek"}
|
||||
target_manifest.write_text(json.dumps(target_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
else:
|
||||
try:
|
||||
from gfa_core.mas.agents.deepseek_summary import generate_deepseek_summary
|
||||
|
||||
result = generate_deepseek_summary(
|
||||
final_dir=final_dir,
|
||||
prefix=prefix,
|
||||
job_id=workspace.name,
|
||||
summaries=summaries,
|
||||
scope_id=scope_id,
|
||||
framework_path=Path(args.framework).expanduser() if args.framework else None,
|
||||
model=args.deepseek_model,
|
||||
max_tokens=max(4096, int(args.deepseek_max_tokens)),
|
||||
)
|
||||
effective_scope = str(result.get("scope_id") or "")
|
||||
target_manifest = scoped_manifest if scope_id and scoped_manifest else manifest_out
|
||||
target_data = read_json(target_manifest) or manifest_data
|
||||
report_path = Path(result["report_path"])
|
||||
evidence_path = Path(result["evidence_path"])
|
||||
metadata_path = Path(result["metadata_path"])
|
||||
target_data.setdefault("artifacts", {}).update({
|
||||
"summary_report": {
|
||||
"path": f"final/{report_path.name}", "type": "markdown", "size": report_path.stat().st_size,
|
||||
"generation": "deepseek_api",
|
||||
},
|
||||
"summary_evidence": {
|
||||
"path": f"final/{evidence_path.name}", "type": "json", "size": evidence_path.stat().st_size,
|
||||
},
|
||||
"deepseek_metadata": {
|
||||
"path": f"final/{metadata_path.name}", "type": "json", "size": metadata_path.stat().st_size,
|
||||
},
|
||||
})
|
||||
target_data["deepseek_generation"] = {
|
||||
"status": "success",
|
||||
"scope_id": effective_scope,
|
||||
"provider": result["metadata"].get("provider"),
|
||||
"model": result["metadata"].get("model"),
|
||||
"validation": result["metadata"].get("validation"),
|
||||
}
|
||||
target_manifest.write_text(json.dumps(target_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
except Exception as exc:
|
||||
target_manifest = scoped_manifest if scope_id and scoped_manifest else manifest_out
|
||||
target_data = read_json(target_manifest) or manifest_data
|
||||
target_data["status"] = "failed"
|
||||
target_data["deepseek_generation"] = {"status": "failed", "error": str(exc)[:2000]}
|
||||
target_manifest.write_text(json.dumps(target_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
||||
print(f"Error: DeepSeek summary generation failed: {exc}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
print("Summary complete")
|
||||
print(f" - {report}")
|
||||
print(f" - {evidence_index}")
|
||||
print(f" - {files_tsv}")
|
||||
print(f" - {manifest_out}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user