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}")
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user