mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 04:31:58 +00:00
自动按口径出具只给问数据的答案(复核 M2)
复核发现:自动出具对所有参与比对的探索来源都生效(问数据、画布试运行、蓝图试运行、个人应用刷新),而拍板 L1 和细案 做法 5 说的是「问数据的答案」。画布上反复试跑一份和受管口径等价的草图,每次都是新的来源运行,去重按来源运行算,于是每 试一次就自动发起一次正式运行(含报告撰写的模型费用),直到每日上限;个人应用刷新、蓝图试运行同样。 做法:plan_issue 算 auto_reason 时,设置开着之后先看来源,不是 chat 的写 AUTO_NOT_CHAT(「这次是画布试运行,不是问数据 的答案:自动出具只给问数据的答案,这里只给一键出具」),只给一键,一键照常发起。条件链改成逐条 if/elif,好读。 测试:equivalent_run 缺省改成问数据(origin_kind=chat),原来的自动出具用例照旧过;新加「画布试运行不自动、写明原因、 一键照常」。去掉来源这一条回跑,新用例失败。
This commit is contained in:
@@ -20,9 +20,11 @@
|
||||
- 权限(拍板 L5):搭建者及以上(关登录时同)都可以;使用者只能按他有权使用的应用固定着的这一版出具(复用应用授权,
|
||||
apps/access),别的写「请搭建者出具」;都要读得到这次运行;
|
||||
- 当天没超上限(设置 ledger.issue_daily_limit,自动的、一键的合计)。
|
||||
**自动出具**(auto_issue,拍板 L1)另要:设置里开着、认法是独立等价(how=independent:Agent 自己写的 SQL 被证明等价;
|
||||
「助手选用」的只给一键——选哪份口径是助手凭问法判断的,由人点一下代替证明)、版本是受管级别。只在运行一封存就比完的
|
||||
那一次触发(ledger/match)。不满足的写进 actions 的 auto_reason。
|
||||
**自动出具**(auto_issue,拍板 L1)另要:设置里开着、这次是问数据的答案(origin_kind=chat;画布试运行、蓝图试运行、
|
||||
个人应用刷新也比对,但只给一键——画布上反复试跑一份等价的草图,每次都是新的来源运行,自动的话每试一次就多一次正式运行,
|
||||
含报告撰写的模型费用)、认法是独立等价(how=independent:Agent 自己写的 SQL 被证明等价;「助手选用」的只给一键——选哪份
|
||||
口径是助手凭问法判断的,由人点一下代替证明)、版本是受管级别。只在运行一封存就比完的那一次触发(ledger/match)。不满足的
|
||||
写进 actions 的 auto_reason。
|
||||
|
||||
**同一运行、同一口径、同一组参数只发起一次**:按 input_key(apps/resolve,补算用的同一个指纹)认,已经发起过、没失败的
|
||||
直接交回那一次。进程内按(运行、工作流、版本)串行,自动和一键同时到也只发一次(单进程部署,同 apps/backfill 的锁)。
|
||||
@@ -70,6 +72,9 @@ ASK_BUILDER = "这份口径没有被你能使用的应用固定,不能由你
|
||||
OVER_LIMIT = "今天的按口径出具已达到上限({limit} 次),请明天再试,或请管理员调整上限"
|
||||
#: 不自动出具的原因(能一键出具时写进 actions 的 auto_reason)
|
||||
AUTO_OFF = "设置里关了自动按口径出具"
|
||||
AUTO_NOT_CHAT = "这次是{what},不是问数据的答案:自动出具只给问数据的答案,这里只给一键出具"
|
||||
#: 参与比对、但不是问数据的那几种来源(ledger/match.EXPLORE_ORIGINS)怎么称呼
|
||||
_NOT_CHAT_TEXT = {"canvas": "画布试运行", "trial": "蓝图试运行", "personal_app": "个人应用的刷新"}
|
||||
AUTO_COMPOSED = "数来自助手选用的口径,只给一键出具:选用哪份口径是助手按问法判断的,要由人确认"
|
||||
AUTO_LEVEL = "这一版是已发布级别,自动出具只限受管级别的口径"
|
||||
AUTO_RETRO = "这次比对是事后按现在的口径回看的,不自动出具"
|
||||
@@ -269,8 +274,16 @@ async def plan_issue(session: Any, run: Run | None, content: dict[str, Any] | No
|
||||
settings = await ledger_settings(session)
|
||||
if plan.existing is None and await issued_today(session) >= int(settings["issue_daily_limit"]):
|
||||
return plan.refuse(OVER_LIMIT.format(limit=settings["issue_daily_limit"]), 429, DAILY_LIMIT)
|
||||
plan.auto_reason = (AUTO_OFF if not settings["auto_issue"] else AUTO_COMPOSED if plan.how != "independent"
|
||||
else AUTO_LEVEL if plan.level != "governed" else AUTO_RETRO if retro else None)
|
||||
if not settings["auto_issue"]:
|
||||
plan.auto_reason = AUTO_OFF
|
||||
elif run.origin_kind != "chat":
|
||||
plan.auto_reason = AUTO_NOT_CHAT.format(what=_NOT_CHAT_TEXT.get(run.origin_kind or "", "别处发起的运行"))
|
||||
elif plan.how != "independent":
|
||||
plan.auto_reason = AUTO_COMPOSED
|
||||
elif plan.level != "governed":
|
||||
plan.auto_reason = AUTO_LEVEL
|
||||
elif retro:
|
||||
plan.auto_reason = AUTO_RETRO
|
||||
return plan
|
||||
|
||||
|
||||
@@ -378,5 +391,5 @@ async def auto_issue(run_id: str) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
__all__ = ["DAILY_LIMIT", "FORBIDDEN", "ORIGIN", "REFUSED", "IssueRefused", "Plan", "auto_issue", "issue",
|
||||
"issued_runs", "issued_today", "issued_view", "plan_issue", "plans_for"]
|
||||
__all__ = ["AUTO_NOT_CHAT", "DAILY_LIMIT", "FORBIDDEN", "ORIGIN", "REFUSED", "IssueRefused", "Plan", "auto_issue",
|
||||
"issue", "issued_runs", "issued_today", "issued_view", "plan_issue", "plans_for"]
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"""按口径正式出具(next-round 02 做法 5,拍板 L1、L5,app/ledger/issue.py)。
|
||||
|
||||
真的跑探索运行(虚构店铺库、mock 模型写报告),等后台比对做完,看自动出具、一键出具、拒绝原因、去重:
|
||||
- 整题独立等价于受管口径:比对完自动发起一次正式运行(来源 ledger_issue),origin 记来源运行、口径、绑定哈希,参数是
|
||||
绑定 + 缺省值,按 graph_hash 钉住;GET 账本的 actions 写能自动、issued 列出它;再点一次交回同一次;
|
||||
- 已发布级别、助手选用的:不自动,只给一键(写明为什么),一键照常发起;设置关了自动出具也不自动;
|
||||
- 问数据的答案整题独立等价于受管口径:比对完自动发起一次正式运行(来源 ledger_issue),origin 记来源运行、口径、绑定
|
||||
哈希,参数是绑定 + 缺省值,按 graph_hash 钉住;GET 账本的 actions 写能自动、issued 列出它;再点一次交回同一次;
|
||||
- 已发布级别、助手选用的、不是问数据的(画布试运行等):不自动,只给一键(写明为什么),一键照常发起;设置关了自动出具
|
||||
也不自动;
|
||||
- 拒绝写明原因:整题不等价、点名别的口径、版本退役、图里有人工节点、缺入口字段、超过每日上限、使用者没有应用授权;
|
||||
使用者有授权(应用固定着这一版)就能出具,origin 记靠的是哪个应用;
|
||||
- 设置 ledger 一组:缺省值、写坏了拒收。
|
||||
@@ -98,11 +99,12 @@ def two_writers(monkeypatch, answer: str = "本周销售额 [[v:Q1.r0.销售额]
|
||||
monkeypatch.setattr(mock_model.MockChatModel, "_decide", decide)
|
||||
|
||||
|
||||
async def equivalent_run(monkeypatch):
|
||||
async def equivalent_run(monkeypatch, origin: str = "chat"):
|
||||
"""一次整题独立等价于「周销售」v1 的探索运行(缺省是问数据的答案),等它封存、比对完。"""
|
||||
from app.engine.runner import run_manager as manager
|
||||
|
||||
two_writers(monkeypatch)
|
||||
run = await manager.start(graph=S.explore_graph(S.EQUIVALENT), input_payload={}, origin_kind="canvas")
|
||||
run = await manager.start(graph=S.explore_graph(S.EQUIVALENT), input_payload={}, origin_kind=origin)
|
||||
row = await S.wait(run.id)
|
||||
assert row.status == "succeeded", row.error
|
||||
await ledger_match.drain()
|
||||
@@ -142,6 +144,22 @@ async def test_an_independent_equivalent_answer_to_a_governed_caliber_is_issued_
|
||||
assert len(await issued(row.id)) == 1
|
||||
|
||||
|
||||
async def test_only_answers_in_chat_are_issued_automatically(client, monkeypatch):
|
||||
"""自动出具只给问数据的答案(拍板 L1、做法 5):画布上反复试跑一份和受管口径等价的草图,每次都是新的来源运行,
|
||||
自动的话每试一次就多一次正式运行(含报告撰写的模型费用)。画布试运行只给一键,写明为什么,一键照常发起。"""
|
||||
wf = await S.publish()
|
||||
row = await equivalent_run(monkeypatch, origin="canvas")
|
||||
assert await settle(row.id) == []
|
||||
[action] = [a for a in (await client.get(f"/api/runs/{row.id}/ledger")).json()["actions"] if a["kind"] == "issue"]
|
||||
assert action["available"] is True and action["auto"] is False
|
||||
assert action["auto_reason"] == ledger_issue.AUTO_NOT_CHAT.format(what="画布试运行")
|
||||
assert await ledger_issue.auto_issue(row.id) is None and await issued(row.id) == []
|
||||
res = await client.post(f"/api/ledger/answers/{row.id}/issue", json={"workflow_id": wf, "version": 1})
|
||||
assert res.status_code == 200 and res.json()["created"] is True
|
||||
[formal] = await settle(row.id)
|
||||
assert formal.origin["auto"] is False and formal.status == "succeeded"
|
||||
|
||||
|
||||
async def test_published_level_calibers_only_get_one_click(client, monkeypatch):
|
||||
wf = await S.publish(level="published")
|
||||
row = await equivalent_run(monkeypatch)
|
||||
|
||||
Reference in New Issue
Block a user