feat(loop-engine): 配方执行器 —— project / prune / say,每一笔之前刷读数

三条硬规矩:每一笔之前刷读数(后一笔要数前一笔刚写下的行,不刷新就恒为 0);
值没变的写静默跳过(配方不是模型,原地打转不必被看见);
出错交人不重试不退回模型(配方抛错是包的 bug,退回模型就是让它去凑)。
主键算不出来的那一行先不写 —— 空主键写下去是一行永远对不上的垃圾。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
xcs
2026-08-29 03:41:34 +08:00
co-authored by Claude Opus 5
parent 58ff4f1b90
commit b0a3cc3a55
8 changed files with 375 additions and 1 deletions
+21
View File
@@ -314,3 +314,24 @@ export type TaskContext = {
*/
machineCriteria(taskId: TaskId): Promise<ReadonlySet<string>>;
};
/**
* **一次结构化 AI 调用** —— 配方的 `analyze` 动词(spec §5.2)。
*
* 与 `AgentPort` 的分工是死的:`AgentPort` 是「问它下一步干什么」,它能调工具、能写台账;
* 这一件**只是一个纯函数**:系统组装好入参,它出一份结构化判断,系统把结果落表。
* **不给工具、不给记忆、不多轮。** 出参不合 schema 由实现方就地重问一次,再不成就抛。
*/
export type AnalyzeGateway = {
run(input: {
readonly taskId: TaskId;
/** 活动声明过的模型名 */
readonly model: string;
readonly instruction: string;
/** 系统组装好的入参 —— 一行一条 */
readonly payload: readonly unknown[];
readonly outputSchema: Readonly<Record<string, unknown>>;
/** 归因:`<步名>#<第几笔>` */
readonly label: string;
}): Promise<{ readonly object: Readonly<Record<string, unknown>> }>;
};