prompt_projection.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from __future__ import annotations
  2. from datetime import datetime, timezone
  3. from typing import Any
  4. from .sanitizer import sanitize
  5. _MAX_PROMPT_CHARS = 60_000
  6. def project_prompt(payload: dict[str, Any]) -> dict[str, Any]:
  7. """Build a truthful, lazy prompt view.
  8. Runtime events preserve the exact delegated task, but the application does
  9. not persist a system-prompt snapshot for each invocation. The current
  10. prompt is therefore deliberately labelled as current configuration.
  11. """
  12. task = _text(payload.get("task"))
  13. prompt = _text(payload.get("promptContent"))
  14. truncated = bool(prompt and len(prompt) > _MAX_PROMPT_CHARS)
  15. if truncated:
  16. prompt = prompt[:_MAX_PROMPT_CHARS].rstrip() + "\n\n…(当前规则过长,已截断)"
  17. result: dict[str, Any] = {
  18. "promptRef": str(payload.get("promptRef") or ""),
  19. "actor": payload.get("actor") or {"role": "main", "label": "主 Agent"},
  20. "notices": [
  21. {
  22. "code": "PROMPT_NOT_SNAPSHOTTED",
  23. "message": "系统没有保存这次运行所用提示词的历史快照;下方展示当前提示词。",
  24. }
  25. ],
  26. }
  27. if mode_notice := _text(payload.get("modeNotice")):
  28. result["notices"].append(
  29. {"code": "CURRENT_MODE_CONTEXT", "message": mode_notice}
  30. )
  31. if task:
  32. result["exactTask"] = {
  33. "content": sanitize(task, max_text=_MAX_PROMPT_CHARS),
  34. "accuracy": "run-exact",
  35. }
  36. if prompt:
  37. result["systemPrompt"] = {
  38. "content": sanitize(prompt, max_text=_MAX_PROMPT_CHARS + 200),
  39. "source": payload.get("promptSource") or "current-file",
  40. "version": payload.get("promptVersion"),
  41. "accuracy": "current-not-run-snapshot",
  42. "capturedAt": datetime.now(timezone.utc).isoformat(),
  43. "truncated": truncated,
  44. }
  45. else:
  46. result["notices"].append(
  47. {
  48. "code": "PROMPT_UNAVAILABLE",
  49. "message": "当前提示词暂时不可读取。",
  50. }
  51. )
  52. if truncated:
  53. result["notices"].append(
  54. {"code": "PROMPT_TRUNCATED", "message": "当前提示词已按安全长度截断。"}
  55. )
  56. return sanitize(result, max_text=_MAX_PROMPT_CHARS + 400)
  57. def _text(value: Any) -> str | None:
  58. if not isinstance(value, str):
  59. return None
  60. value = value.strip()
  61. return value or None