mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 02:11:58 +00:00
2f90f0eb3a
- QueryCore 固定执行(K09):按已发布的不可变口径跑一次,交回类型化标量、发布/manifest 引用与逐查询证据 - 依赖闭包(K08):按选中的指标算出要拷的取数节点、要的入口字段,接进 derive / compose / metrics - SQL 模板参数完整性(K01):试跑、组合问数、派生图、运行时取数共用一套语义,缺参数在渲染前就拒 - 受限字段变更服务(K03)与口径领域边界(K01):改动打在整图深拷贝上,身份与证据归属不可改 - 版本化受控模板绑定(K04):业务口径按显式绑定落到 SQL,对不上就报 unsupported / needs_update - 验证记录(K05)与最小审阅:样例匹配不等于正式批准,审批人只从服务端身份取 - 发布依据清单(K07):发布时按不可变图物化内容寻址清单,正式用途按它判 - 增量重导入(K11)与 B/L/R 三方合并、受限自然语言修改提案(K12):只产候选,落图仍走既有写路径 - 接口与前端:口径草稿页接上字段变更、绑定状态、验证与重导入,新增 caliber-drafts / studio 检查脚本 验证:前端 tsc -b 通过。
69 lines
4.5 KiB
Python
69 lines
4.5 KiB
Python
"""运行来源:这次运行从哪里发起(docs/design/app-platform-and-look.md §2.10 X3)。
|
||
|
||
以前运行表上只有 schedule_id:问数据和画布试跑都是「裸图 + 探索」,分不出来;应用发起的运行更无从说起。
|
||
来源由 launch_run(origin=…) 写进 Run.origin_kind / Run.origin,同时作为 run.origin 事件放进 notes——发起时就定下、
|
||
在封存范围内,事后改不了。
|
||
|
||
客户端(POST /api/runs)只能声明 CLIENT_ORIGINS 里的几种;app_*、hook、schedule 只能由服务端写,客户端声明一律拒绝:
|
||
否则谁都能把一次画布试跑说成「应用入口发起的」。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
#: 全部来源。顺序即界面上筛选的顺序
|
||
ORIGIN_KINDS = (
|
||
"chat", # 问数据
|
||
"canvas", # 画布试跑
|
||
"launcher", # 正式运行(手动,画布或版本页上的「正式运行」)
|
||
"schedule", # 定时任务
|
||
"app_entry", # 应用入口
|
||
"app_view", # 应用视图(按需运行)
|
||
"app_backfill", # 钉住项按 recompute 升版后,按历次触发的输入补算
|
||
"hook", # 外部系统经入站钩子触发
|
||
"api", # 直接调接口,没说是哪
|
||
"trial", # 蓝图的试运行(探索运行,docs/design/normal-user-apps.md N4)
|
||
"personal_app", # 个人应用的刷新(探索运行,N7)
|
||
# 下一轮(docs/design/next-round/00-总方案.md X1):都只能由服务端写
|
||
"eval", # 评测:作答和算期望的运行(探索运行)
|
||
"ledger_issue", # 问数据的答案按已治理口径正式出具(正式运行)
|
||
"reconcile", # 口径对账:这次的取数和口径在同一份数据上各算一次(探索运行)
|
||
"recall", # 口径召回:新旧两版口径在同一份数据上各算一次(探索运行)
|
||
"caliber_trial", # 口径目录里的试跑(探索运行,不是问数回答,也不进统计/召回)
|
||
)
|
||
|
||
#: 进程内 QueryCore 固定执行(K09,app/ledger/querycore.py)用的来源:**沿用口径试跑这一档**——同样是「按一份固定口径跑
|
||
#: 一次取数」的探索运行,不是有人在问数,也不进使用统计与召回比对。这一档的枚举与前端联合类型逐字对齐
|
||
#: (tests/test_frontend_type_unions.py 比对 ORIGIN_KINDS),加一种新来源要同时改前端和 apps/resolve 的分类,这一轮不动它;
|
||
#: QueryCore 自己那几件事(版本、清单、闭包身份、用途、trace)记在 origin 数据的 service/purpose/… 上,不新开一档。
|
||
QUERYCORE_ORIGIN = "caliber_trial"
|
||
|
||
#: 客户端在 POST /api/runs 里能声明的来源
|
||
CLIENT_ORIGINS = ("chat", "canvas", "launcher", "api")
|
||
|
||
#: 系统派生的运行(docs/design/next-round/00-总方案.md X1):评测、口径对账、口径召回都是服务端为了量、为了比替人跑的,
|
||
#: 不是有人在用。它们是完整的运行(证据、封存都在、点得开),但不进使用统计——探索问题聚类、工具白名单衰减、数据目录的
|
||
#: 使用次数和「被哪些运行用过」、审阅队列的使用权重、以后的账本统计——否则一跑评测,治理信号和目录的使用热度就失真了。
|
||
#: 记录页默认也不列(筛选里能选,列表照实写有几次没列出)。ledger_issue 是替用户正式出具,照常计入
|
||
SYSTEM_ORIGINS = ("eval", "reconcile", "recall", "caliber_trial")
|
||
|
||
|
||
def counted_runs() -> Any:
|
||
"""SQL 条件:计入使用统计的运行(排除 SYSTEM_ORIGINS)。所有使用统计都只算它圈进来的运行,别处不另写一份过滤。
|
||
|
||
来源按非空比较(coalesce,同 auth/access.hidden_runs):加来源这一列之前的老运行 origin_kind 为空,NOT IN 碰上 NULL
|
||
会把它们一起筛掉;外连接没对上运行的行(问数据只回了一句、没有运行的那一轮)同理照常计入。"""
|
||
from sqlalchemy import func
|
||
|
||
from app.db.models import Run
|
||
|
||
return func.coalesce(Run.origin_kind, "").not_in(SYSTEM_ORIGINS)
|
||
|
||
|
||
def origin_note(kind: str, **data: Any) -> dict[str, Any]:
|
||
"""run.origin 事件的数据:kind 加上调用方给的字段(app_id、app_version、spec_hash、entry / view、hook、
|
||
actor、actor_verified、auth_mode……),值为 None 的不写。"""
|
||
if kind not in ORIGIN_KINDS:
|
||
raise ValueError(f"不认识的运行来源:{kind}")
|
||
return {"kind": kind, **{k: v for k, v in data.items() if v is not None}}
|