Files
mini-openclaw/scripts/test_aliyun_deepseek_business_loop.py
T
2026-09-28 16:34:10 +08:00

116 lines
4.4 KiB
Python

"""Run a non-persistent Agent Loop test with synthetic business data."""
from __future__ import annotations
import shlex
from pathlib import Path
import paramiko
ROOT = Path(__file__).resolve().parents[1]
def config() -> dict[str, str]:
result: dict[str, str] = {}
for raw in (ROOT / "server-deploy.conf").read_text(encoding="utf-8-sig").splitlines():
line = raw.strip()
if line and not line.startswith("#") and "=" in line:
key, value = line.split("=", 1)
result[key.strip()] = value.strip()
return result
def main() -> int:
settings = config()
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
options = {
"hostname": settings["SERVER_HOST"],
"port": int(settings.get("SERVER_PORT", "22")),
"username": settings["SERVER_USER"],
"timeout": 20,
"banner_timeout": 20,
"auth_timeout": 20,
}
if settings.get("SERVER_KEYFILE"):
options["key_filename"] = settings["SERVER_KEYFILE"]
else:
options["password"] = settings["SERVER_PASSWORD"]
client.connect(**options)
synthetic_test = r'''
import json
from services import assistant_model
model = assistant_model.configuration()
skill = {
"instructions": "对虚构测试项目执行证据约束核查,只验证工具调用链。",
"methods": {
"synthetic-financial-leasing/SKILL.md": "读取数据卡证据,检查负债口径、现金流是否齐备及租赁物覆盖率;不得作审批决定。"
},
"allowed_tools": ["read_project_snapshot", "read_checks", "read_method"],
}
snapshot = {
"id": "snapshot-synthetic-safe",
"project_id": "SAFE-SYNTHETIC-TEST",
"values": {
"financial.total_liabilities": 100,
"due_diligence.liabilities": 90,
"lease.total_value": 120,
"facility.amount": 100,
"cashflow.net_operating": None,
},
"sources": {
"financial.total_liabilities": [{"id": "ev-safe-1", "source": "synthetic_finance", "value": 100}],
"due_diligence.liabilities": [{"id": "ev-safe-2", "source": "synthetic_due_diligence", "value": 90}],
"lease.total_value": [{"id": "ev-safe-3", "source": "synthetic_asset", "value": 120}],
"facility.amount": [{"id": "ev-safe-4", "source": "synthetic_facility", "value": 100}],
"cashflow.net_operating": [{"id": "ev-safe-5", "source": "synthetic_cashflow", "value": None}],
},
"documents": [],
}
checks = [
{"code": "synthetic.liability.consistency", "title": "负债口径差异", "result": "issue", "evidence_ids": ["ev-safe-1", "ev-safe-2"], "fields": ["financial.total_liabilities", "due_diligence.liabilities"], "suggested_action": "核实负债差异"},
{"code": "synthetic.cashflow.missing", "title": "现金流缺失", "result": "unknown", "evidence_ids": ["ev-safe-5"], "fields": ["cashflow.net_operating"], "suggested_action": "补充现金流数据"},
]
rules = [{"id": "rule-synthetic", "name": "虚构测试规则", "version": "1.0.0", "natural_language": "现金流缺失时提示补充,不作审批结论"}]
result, trace = assistant_model.invoke(
skill,
snapshot,
checks,
rules,
"读取全部授权事实、检查与方法,返回可追溯建议。",
[],
model,
{"timeout_seconds": 120, "max_tool_calls": 12},
)
print(json.dumps({
"status": "passed",
"endpoint": model["endpoint"],
"model": trace["model"],
"engine": trace["engine"],
"tool_calls": trace["tool_calls"],
"tools_read": trace["tools_read"],
"finding_count": len(result["findings"]),
"evidence_bound": all(item["evidence_ids"] for item in result["findings"] if item["result"] in ("pass", "issue")),
"requirement_response_present": bool(result["requirement_response"]),
}, ensure_ascii=True))
'''
encoded = synthetic_test.encode("utf-8").hex()
code = "exec(bytes.fromhex(" + repr(encoded) + ").decode('utf-8'))"
command = "docker exec mini-openclaw python -c " + shlex.quote(code)
_, stdout, stderr = client.exec_command(command, timeout=180)
output = stdout.read().decode("utf-8", errors="replace")
error = stderr.read().decode("utf-8", errors="replace")
status = stdout.channel.recv_exit_status()
client.close()
if status:
raise RuntimeError(error.strip() or output.strip() or f"remote exit {status}")
print(output.strip())
return 0
if __name__ == "__main__":
raise SystemExit(main())