mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 00:11:59 +00:00
7739340607
- 问数据和个人应用的图放行绑定只读查询等合规工具的调用工具节点,只读和遮罩在这条路径上生效;被治理成写入的工具在只读运行里直接拒;知识库范围在工具层固定(图级默认值、参数名纠错、Agent 都改不了) - 个人应用的刷新和个人蓝图的试运行只有拥有者能读:运行、事件、证据、工件、文件、运行与审批列表、对比、可验证报告、质询、假设分析、提取工作流一并收紧;个人蓝图的试运行不论谁发起都按个人应用约束 - 共享蓝图只给拥有者、对应应用的管理者、管理员,看不到的一律 404;审核副本归审核人;管理员看别人的个人应用只有元数据、可以归档 - 记录表跨版本汇总(只读挂载旧版本、按当前列 UNION ALL、各版本各自固定高水位,缺的版本照实写进印章);停用前发起的运行可以继续写旧版本;更正沿用原提交人、更正人记审计 - 约定收口:待办种类 review、事件 file.extracted、表单错误 file、模板定义带示例与预置;前端类型一次补齐、去掉临时的局部类型;审核待办卡不再给打不开的链接;读附件事件有中文说法;检查脚本补断言
74 lines
3.0 KiB
Python
74 lines
3.0 KiB
Python
"""场景模板实例化出来的图真的能运行(docs/design/normal-user-apps.md §3.3「实例化 + 检查 + 运行」):周期看板按示例蓝图
|
||
实例化、生成关节填上之后,在一个小库上跑一次,口径卡用 cell() 取到格,成果按指标完整出具。库和数字都是编的。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import asyncio
|
||
import sqlite3
|
||
import uuid
|
||
|
||
import pytest
|
||
|
||
from app.blueprints.instantiate import instantiate
|
||
from app.blueprints.templates import get_template
|
||
from app.data.engine import engines
|
||
from app.db.base import SessionLocal
|
||
from app.db.models import DataSource, Run
|
||
from app.engine.runner import run_manager
|
||
|
||
|
||
@pytest.fixture(autouse=True)
|
||
async def engine_up():
|
||
await run_manager.setup()
|
||
yield
|
||
await run_manager.shutdown()
|
||
|
||
|
||
@pytest.fixture
|
||
async def shop(tmp_path):
|
||
path = tmp_path / "shop.db"
|
||
with sqlite3.connect(path) as db:
|
||
db.executescript("CREATE TABLE orders (id INTEGER PRIMARY KEY, amount REAL, paid_at TEXT, refunded INTEGER);")
|
||
db.executemany("INSERT INTO orders VALUES (?, ?, ?, ?)", [
|
||
(1, 100.0, "2026-10-05", 0), (2, 300.0, "2026-10-08", 1), (3, 600.0, "2026-10-11", 0),
|
||
(4, 999.0, "2026-10-12", 0)]) # 统计期外
|
||
name = f"bprun_{uuid.uuid4().hex[:6]}"
|
||
async with SessionLocal() as session:
|
||
row = DataSource(name=name, kind="sqlite", database=str(path), readonly=True, enabled=True)
|
||
session.add(row)
|
||
await session.commit()
|
||
source_id = row.id
|
||
yield name
|
||
async with SessionLocal() as session:
|
||
await session.delete(await session.get(DataSource, source_id))
|
||
await session.commit()
|
||
await engines.invalidate(source_id)
|
||
|
||
|
||
async def test_the_board_template_runs_and_issues_by_metrics(shop):
|
||
from app.blueprints.templates._common import safe_id
|
||
|
||
extras = get_template("periodic_board")
|
||
spec = extras.example()
|
||
for item in spec["data"]:
|
||
item["table"]["value"]["source"] = shop
|
||
node = f"fetch_{safe_id(shop)}"
|
||
fill = {k.replace("fetch_shop", node): v.replace("fetch_shop", node) for k, v in extras.example_fill().items()}
|
||
inst = instantiate(spec, filled=fill)
|
||
assert inst.problems == []
|
||
run = await run_manager.start(graph=inst.graph, input_payload={
|
||
"period": "2026-W41", "period_start": "2026-10-05", "period_end": "2026-10-11"})
|
||
for _ in range(400):
|
||
await asyncio.sleep(0.05)
|
||
async with SessionLocal() as session:
|
||
row = await session.get(Run, run.id)
|
||
if row.status in ("succeeded", "failed") and row.manifest_seq is not None:
|
||
break
|
||
assert row.status == "succeeded", row.error
|
||
output = row.output or {}
|
||
issuance = output["_issuance"]
|
||
assert (issuance["tier"], issuance["mode"]) == ("formal", "metrics"), issuance
|
||
# 销售额不含已退款的那一单;订单数、退款率按全部订单
|
||
assert output["销售额(元)"] == "700.0" and output["订单数(单)"] == "3"
|
||
assert output["退款率(%)"] == "33.33"
|