79 lines
4.1 KiB
Python
79 lines
4.1 KiB
Python
"""Retain compact knowledge references through visual pending-state lifecycle."""
|
|
from pathlib import Path
|
|
import shutil
|
|
import json
|
|
|
|
root = Path(__file__).resolve().parent
|
|
records = []
|
|
helper = ''' @staticmethod
|
|
def _knowledge_trace_metadata(value) -> dict:
|
|
"""Keep only bounded reference metadata, never knowledge or source-chat bodies."""
|
|
import math
|
|
|
|
if not isinstance(value, dict) or not value:
|
|
return {}
|
|
trace = {"enabled": bool(value.get("enabled")), "mode": str(value.get("mode") or "")[:64],
|
|
"elapsed_ms": 0, "hits": []}
|
|
try:
|
|
trace["elapsed_ms"] = max(0, min(1000000000, int(value.get("elapsed_ms") or 0)))
|
|
except (ValueError, TypeError, OverflowError):
|
|
pass
|
|
hits = value.get("hits")
|
|
for hit in (hits[:20] if isinstance(hits, list) else []):
|
|
if not isinstance(hit, dict) or not isinstance(hit.get("id"), (str, int)):
|
|
continue
|
|
item = {"id": hit["id"][:128] if isinstance(hit["id"], str) else hit["id"]}
|
|
for key in ("revision", "score"):
|
|
number = hit.get(key)
|
|
if isinstance(number, (int, float)):
|
|
try:
|
|
if math.isfinite(number):
|
|
item[key] = number
|
|
except (ValueError, OverflowError):
|
|
pass
|
|
trace["hits"].append(item)
|
|
return trace
|
|
|
|
'''
|
|
for project in (Path('C:/kefu/wechat_rpa'), Path('C:/wechat_rpa')):
|
|
file = project / 'wechat_bot.py'
|
|
original = file.read_text(encoding='utf-8')
|
|
changed = original.replace(' def _record_model_call(\n', helper + ' def _record_model_call(\n', 1)
|
|
old = ' state["model_chosen"] = str(outcome.get("chosen") or "")\n'
|
|
new = (' state["knowledge_trace"] = self._knowledge_trace_metadata(outcome.get("knowledge"))\n'
|
|
' state["model_task_id"] = str(outcome.get("task_id") or task_id or "")[:128]\n' + old)
|
|
assert changed.count(old) == 1
|
|
changed = changed.replace(old, new, 1)
|
|
old = ' if ai_chat.gateway_provider() is not None:\n reply = self._call_model_with_observer(\n'
|
|
new = (' if ai_chat.gateway_provider() is not None:\n'
|
|
' # A safe fallback may not make a gateway call; discard older UI-guard traces.\n'
|
|
' ai_chat.take_last_gateway_trace()\n'
|
|
' reply = self._call_model_with_observer(\n')
|
|
assert changed.count(old) == 1
|
|
changed = changed.replace(old, new, 1)
|
|
old = ' "task_id": trace.get("task_id") or "",\n'
|
|
new = old + ' "knowledge": trace.get("knowledge") or {},\n'
|
|
assert changed.count(old) == 1
|
|
changed = changed.replace(old, new, 1)
|
|
old = ' "exchange_id": str(value.get("exchange_id") or ""),\n'
|
|
new = (old + ' "knowledge_trace": self._knowledge_trace_metadata(value.get("knowledge_trace")),\n'
|
|
' "model_task_id": str(value.get("model_task_id") or "")[:128],\n')
|
|
assert changed.count(old) == 2
|
|
changed = changed.replace(old, new)
|
|
old = ' state.pop("exchange_id", None)\n'
|
|
new = old + ' state.pop("knowledge_trace", None)\n state.pop("model_task_id", None)\n'
|
|
assert changed.count(old) == 1
|
|
changed = changed.replace(old, new, 1)
|
|
compile(changed, str(file), 'exec')
|
|
backup = project / 'backups' / 'recognition-audit-20260916' / 'visual-trace'
|
|
backup.mkdir(parents=True, exist_ok=True)
|
|
assert not (backup/file.name).exists()
|
|
shutil.copy2(file, backup/file.name)
|
|
file.write_text(changed, encoding='utf-8', newline='\n')
|
|
test = project / 'test_visual_knowledge_trace_audit.py'
|
|
assert not test.exists()
|
|
shutil.copy2(root/test.name, test)
|
|
records.append({'project':str(project), 'file':str(file), 'backup':str(backup/file.name)})
|
|
(root/'visual-trace-changes.json').write_text(json.dumps(records, ensure_ascii=False, indent=2), encoding='utf-8')
|
|
print(json.dumps(records, ensure_ascii=False))
|