fix(定时任务): 抽取开关只控制模板HTML数据,不再影响Markdown等正常操作
- 之前关闭抽取会整段跳过 gather/agent,连带把 Markdown 生成也跳过了 - 改为:抽取开关只决定 HTML 用「抽取数据」还是「模板默认数据」;require_markdown 独立—— 需要时照常跑 gather 产出 .md 并校验/带出,与开关无关 - gather 仅在 do_extract(开关开+有描述+可转换) 或 require_markdown 时跑一次,两者复用同一次 - 只展示模板恒不抽取,但仍尊重 require_markdown;_finalize_template_html 支持 extra_files 带出 .md - 测试:关闭抽取+必须Markdown → 仍产出.md/不转换/HTML用默认数据 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
6673121f3f
commit
089d3e171f
2 files changed
+53
-52
No files matched your search
+52
-51
@@ -1496,13 +1496,17 @@ class ScheduledTaskService:
|
||||
content: str,
|
||||
source_chars: int,
|
||||
used_default: bool,
|
||||
extra_files: list[dict[str, Any]] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""归档 index.html + 持久化 scheduled_html_pages + 构造 format=html 结果。"""
|
||||
"""归档 index.html + 持久化 scheduled_html_pages + 构造 format=html 结果。
|
||||
|
||||
``extra_files`` 会排在 index.html 之前一并带上(如必须生成 Markdown 时的 .md)。
|
||||
"""
|
||||
task_tz = ZoneInfo(task.get("timezone") or "UTC")
|
||||
local_time = scheduled_for.astimezone(task_tz)
|
||||
archive_path = self._archive_html_index(run_id, html)
|
||||
title = str(task.get("name") or spec.name).strip()
|
||||
files: list[dict[str, Any]] = []
|
||||
files: list[dict[str, Any]] = list(extra_files or [])
|
||||
if archive_path is not None:
|
||||
files.append(
|
||||
{
|
||||
@@ -1569,8 +1573,40 @@ class ScheduledTaskService:
|
||||
raise HtmlGenerationError(f"未知的 HTML 模板:{tpl_id}")
|
||||
cfg = self._html_config(task)
|
||||
model_name = str(cfg.get("model_name") or "").strip() or None
|
||||
# 「执行数据抽取」开关**只**控制 HTML 用「抽取数据」还是「模板默认数据」,
|
||||
# 不影响 Markdown 生成等其它正常操作。
|
||||
extract = bool(cfg.get("template_extract"))
|
||||
also_markdown = _task_requires_markdown(task)
|
||||
prompt = str(task.get("prompt") or "").strip()
|
||||
description = str(task.get("description") or "").strip()
|
||||
# 真正抽取 HTML 数据:开关开 且 有描述/任务 prompt 且 模板可转换(只展示模板恒不抽取)。
|
||||
do_extract = extract and bool(prompt or description) and spec.convertible
|
||||
task_tz = ZoneInfo(task.get("timezone") or "UTC")
|
||||
local_time = scheduled_for.astimezone(task_tz)
|
||||
|
||||
# 只展示模板:原样输出(含全部子页面)。
|
||||
def _pick_md(gathered: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
return [
|
||||
item
|
||||
for item in (gathered or [])
|
||||
if isinstance(item, dict) and str(item.get("name") or "").lower().endswith((".md", ".markdown"))
|
||||
]
|
||||
|
||||
# gather:HTML 要抽取 或 需要 Markdown 时才跑(同一次 agent 运行可兼顾两者);
|
||||
# 都不需要则完全不跑 agent。Markdown 校验独立于抽取开关。
|
||||
data_text = ""
|
||||
md_files: list[dict[str, Any]] = []
|
||||
if do_extract or also_markdown:
|
||||
data_text, gathered = await self._gather_html_data(
|
||||
task, runtime_thread_id=runtime_thread_id, scheduled_for=scheduled_for, run_id=run_id
|
||||
)
|
||||
if also_markdown:
|
||||
if not _has_valid_markdown_file(gathered):
|
||||
raise MarkdownRequirementError(
|
||||
f"未满足输出要求:需生成 Markdown(.md) 文件,且文件正文不少于 {_MARKDOWN_MIN_CHARS} 字"
|
||||
)
|
||||
md_files = _pick_md(gathered)
|
||||
|
||||
# 只展示模板:HTML 原样输出(含全部子页面);Markdown 已按需独立生成。
|
||||
if not spec.convertible:
|
||||
html = template_fill.read_template_text(tpl_id)
|
||||
return await self._finalize_template_html(
|
||||
@@ -1583,54 +1619,13 @@ class ScheduledTaskService:
|
||||
content=f"已套用模板「{spec.name}」(含全部子页面)",
|
||||
source_chars=0,
|
||||
used_default=True,
|
||||
extra_files=md_files,
|
||||
)
|
||||
|
||||
# 数据抽取开关(html_config.template_extract):关闭 → 直接用模板默认数据,不检索/
|
||||
# 不转换;开启 → 才执行下面的检索+转换抽取。
|
||||
if not bool(cfg.get("template_extract")):
|
||||
data_obj = template_fill.reference_data(tpl_id)
|
||||
return await self._finalize_template_html(
|
||||
task,
|
||||
spec=spec,
|
||||
template_id=tpl_id,
|
||||
html=template_fill.fill_template(
|
||||
tpl_id, data_obj, update_date=scheduled_for.astimezone(ZoneInfo(task.get("timezone") or "UTC")).date()
|
||||
),
|
||||
run_id=run_id,
|
||||
scheduled_for=scheduled_for,
|
||||
content=f"未开启数据抽取,已用模板「{spec.name}」默认数据(含全部子页面)",
|
||||
source_chars=0,
|
||||
used_default=True,
|
||||
)
|
||||
|
||||
# 用户的描述与任务 prompt 都为空 → 不检索/不转换,直接用模板原有数据。
|
||||
prompt = str(task.get("prompt") or "").strip()
|
||||
description = str(task.get("description") or "").strip()
|
||||
if not prompt and not description:
|
||||
data_obj = template_fill.reference_data(tpl_id)
|
||||
return await self._finalize_template_html(
|
||||
task,
|
||||
spec=spec,
|
||||
template_id=tpl_id,
|
||||
html=template_fill.fill_template(tpl_id, data_obj, update_date=scheduled_for.astimezone(ZoneInfo(task.get("timezone") or "UTC")).date()),
|
||||
run_id=run_id,
|
||||
scheduled_for=scheduled_for,
|
||||
content=f"未提供描述,已用模板「{spec.name}」原有数据(含全部子页面)",
|
||||
source_chars=0,
|
||||
used_default=True,
|
||||
)
|
||||
|
||||
# 可转换模板:检索真实数据(复用 gather) → 转换成模板 DATA → 填进真模板。
|
||||
data_text, _files = await self._gather_html_data(
|
||||
task, runtime_thread_id=runtime_thread_id, scheduled_for=scheduled_for, run_id=run_id
|
||||
)
|
||||
# HTML 数据来源:抽取(开关开 + 有数据)→ 转换填充;否则用模板默认数据(子页面齐全)。
|
||||
source = (data_text or "").strip()
|
||||
used_default = False
|
||||
if not source:
|
||||
data_obj = template_fill.reference_data(tpl_id)
|
||||
content = f"未获取到数据,已用模板「{spec.name}」默认数据生成(含全部子页面)"
|
||||
used_default = True
|
||||
else:
|
||||
used_default = True
|
||||
if do_extract and source:
|
||||
try:
|
||||
converted = await self._convert_to_template_data(
|
||||
tpl_id, source, model_name=model_name, soul=None, run_id=run_id
|
||||
@@ -1638,14 +1633,19 @@ class ScheduledTaskService:
|
||||
# 子页面没抽到有效内容的,回退模板原有数据,避免子页面空白。
|
||||
data_obj = template_fill.merge_with_reference(tpl_id, converted)
|
||||
content = f"已检索数据并套用模板「{spec.name}」(空子页面回退原数据,含全部子页面)"
|
||||
used_default = False
|
||||
except TemplateFillError:
|
||||
logger.warning("模板参考转换失败,回退默认数据 run=%s tpl=%s", run_id, tpl_id, exc_info=True)
|
||||
data_obj = template_fill.reference_data(tpl_id)
|
||||
content = f"数据转换未通过,已回退模板「{spec.name}」默认数据(含全部子页面)"
|
||||
used_default = True
|
||||
else:
|
||||
data_obj = template_fill.reference_data(tpl_id)
|
||||
content = (
|
||||
f"未开启数据抽取,已用模板「{spec.name}」默认数据(含全部子页面)"
|
||||
if not extract
|
||||
else f"未提供描述/未获取到数据,已用模板「{spec.name}」默认数据(含全部子页面)"
|
||||
)
|
||||
|
||||
task_tz = ZoneInfo(task.get("timezone") or "UTC")
|
||||
local_time = scheduled_for.astimezone(task_tz)
|
||||
try:
|
||||
html = template_fill.fill_template(tpl_id, data_obj, update_date=local_time.date())
|
||||
except template_fill.TemplateError as exc:
|
||||
@@ -1660,6 +1660,7 @@ class ScheduledTaskService:
|
||||
content=content,
|
||||
source_chars=len(source),
|
||||
used_default=used_default,
|
||||
extra_files=md_files,
|
||||
)
|
||||
|
||||
async def _run_template_fill_attempt(
|
||||
|
||||
Reference in new issue
Block a user