Cut WA alarm re-query loops, auto-deliver xlsx, and add ops schedule templates.

TTL-cache UME alarm/diagnostics MCP calls, mark write_xlsx deliverable on WhatsApp unless explicitly false, and expose built-in recipe_template_id playbooks for daily tally / critical xlsx / license checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-08-10 23:08:05 +08:00
parent 7373e516f0
commit d2693d1c63
9 changed files with 431 additions and 5 deletions

View file

@ -7,12 +7,14 @@ from pathlib import Path
from runtime.scheduler.recipe import (
compile_playbook_instruction,
list_ops_recipe_templates,
looks_like_complex_schedule_prompt,
normalize_recipe,
preview_markdown,
prompt_summary_from_recipe,
recipe_has_playbook,
recipe_missing_fields,
resolve_ops_recipe_template,
)
from runtime.scheduler.turn_text import build_scheduled_turn_instruction, scheduled_turn_system_suffix
from runtime.tools.experts.productivity.schedule_tools import (
@ -67,6 +69,18 @@ class RecipeHelpersTests(unittest.TestCase):
self.assertTrue(looks_like_complex_schedule_prompt("继续刚才那个生成 PDF 流程"))
self.assertFalse(looks_like_complex_schedule_prompt("提醒喝水"))
def test_ops_recipe_templates(self) -> None:
items = list_ops_recipe_templates()
ids = {str(x.get("id") or "") for x in items}
self.assertIn("ume_alarm_tally_daily", ids)
self.assertIn("ume_critical_xlsx_daily", ids)
self.assertIn("ne_license_check_weekly", ids)
tmpl = resolve_ops_recipe_template("alarm_tally")
assert tmpl is not None
self.assertTrue(recipe_has_playbook(tmpl))
self.assertEqual((tmpl.get("source") or {}).get("template_id"), "ume_alarm_tally_daily")
self.assertIsNone(resolve_ops_recipe_template("nope"))
def test_turn_instruction_modes(self) -> None:
reminder = build_scheduled_turn_instruction(prompt_text="喝水", mode="scheduled", lang="zh")
self.assertIn("提醒意图", reminder)
@ -183,6 +197,25 @@ class ScheduleRecipeToolTests(unittest.TestCase):
self.assertFalse(out.get("ok"))
self.assertEqual(out.get("error"), "recipe_required")
def test_create_from_ops_recipe_template(self) -> None:
out = schedule_create_tool().handler(
{
"tenant_id": self.tenant_id,
"owner_user_id": self.user_id,
"name": "Daily tally",
"recipe_template_id": "ume_alarm_tally_daily",
"schedule_kind": "cron",
"schedule_expr": "0 8 * * *",
"lang": "en",
}
)
self.assertTrue(out.get("ok"), out)
job = out.get("job") or {}
recipe = job.get("recipe") or {}
self.assertTrue(recipe_has_playbook(recipe))
self.assertEqual((recipe.get("source") or {}).get("template_id"), "ume_alarm_tally_daily")
self.assertIn("UME", str(job.get("prompt_text") or ""))
def test_simple_reminder_still_works(self) -> None:
out = schedule_create_tool().handler(
{