@sema-agent/core
Version:
Stateless, task-oriented AI agent core
80 lines (79 loc) • 4.77 kB
TypeScript
/**
* design/73 §1 v1 — **TaskOutcome 反馈账本(薄 seam)**。core 的唯一职责 = 在有客观 oracle 的终态发射
* 一条结构化事实;聚合(keyed by `(taskSignature, model)`)、路由/预算策略、bandit 全在 service 侧
* ledger(§7.2)。seam 形态照 `RunnerDeps.tracer` / `RunnerDeps.onError` 先例:fire-and-forget、
* swallow-guarded(throwing sink 绝不影响 run)。
*
* 🔴 红线(design/73 §1.2/§4 + makereal-corpus §4 交叉验证裁决,逐条钉死):
* ① **只发 mechanical tier** — `verificationKind` 被类型钉成字面量 `"mechanical"`,且
* {@link emitTaskOutcome} 对运行时混入的非 mechanical 值 FAIL-CLOSED 丢弃。llm_assisted /
* self-report(reviewer 判定、supervisor approval、模型自报)绝不进 v1 —— 那是 service 侧
* 仪表盘 metadata,绝不等权驱动变更(绝不自评闭环)。
* ② **必须带 `oracleHadRedRun`** — "同一个机械 oracle 曾观察到 RED" 是最强 grounded 信号
* (防 vacuous oracle:一个从来没红过的 oracle 证明不了任何东西)。
* ③ **单发射点** — `runGoal` 终态一次(goal 模式的 `doneCheck` = 天然机械 oracle)+ 有真 oracle 的
* harness/service 显式调 {@link emitTaskOutcome}。替掉散落 console.log 的污染源(console 刮出来的
* 数字 = 内存叙事,零 durable 产物)。
* ④ **core 只发事实** — 本模块无任何聚合/持久化/策略;n=1-per-signature 阶段消费侧只准做只读
* ledger/仪表盘,自动策略变更 flag-off(§7.4 回测门)。
*/
import type { RunnerDeps } from "./types.js";
/**
* One mechanical-tier outcome fact for a finished task/goal run. Real-data shape reference: the nightly
* matrix ledger (60-row summary.jsonl) — `oracle` stays free-form on purpose (each harness has its own
* mechanical fields: behaviorPass/typesClean/…) with `green` as the single required derived bit.
*/
export interface TaskOutcome {
/** Aggregation key — stable across runs of the "same task" (service aggregates by `(taskSignature, model)`). */
taskSignature: string;
/** This run's identity (the taskId of the final task leg, or the goal's sessionId). */
runId: string;
/** Effective model id that served the run (resolved `Model.id`), when known. */
model?: string;
/** 🔴 Red line ①: core emits ONLY the mechanical tier. Literal type — no other value exists in v1. */
verificationKind: "mechanical";
/** Terminal status of the run (e.g. a `GoalStatus` or `TaskStatus` — "achieved"/"completed"/"failed"/…). */
status: string;
/** Machine-readable failure code when the terminal status carried one. */
errorCode?: string;
/**
* The mechanical oracle's result — free-form per harness (pass/fail counts, typesClean, exit codes, …)
* but ALWAYS with the derived `green` bit: did the objective oracle pass at the end?
*/
oracle: {
green: boolean;
[k: string]: unknown;
};
/**
* 🔴 Red line ②: did the SAME mechanical oracle observe a RED (failing) state during this run — the
* strongest grounded signal (an oracle that never ran red proves nothing about its own substance).
* In `runGoal` this is derived: any `doneCheck` verdict with `done:false` before the terminal state.
*/
oracleHadRedRun: boolean;
/** Raw inputs a service-side signature derivation can use (§7.3) — optional in v1. */
signatureInputs?: {
toolset?: string[];
objectiveHash?: string;
targetLang?: string;
moduleCount?: number;
};
/** Total tokens spent (own + nested). */
tokens?: number;
/** Total cost in integer micro-USD (own + nested). */
costMicroUsd?: number;
/** Total model turns (own + nested). */
turns?: number;
/** Wall-clock duration of the whole run, ms. */
wallMs?: number;
/** Harness-specific extras (cacheHitRate, compactions, chaos lane, …). Facts only — never judgments. */
extra?: Record<string, unknown>;
}
/**
* Fire the deployment's `onTaskOutcome` sink with one outcome fact — the SINGLE emission chokepoint
* (red line ③). Fire-and-forget + swallow-guarded (tracer/onError posture): a throwing sink never
* affects the caller. FAIL-CLOSED on tier: anything not `verificationKind:"mechanical"` (runtime cast
* around the literal type) is dropped, never forwarded (red line ①). Exported for harnesses/services
* that have a REAL mechanical oracle outside goal mode; plain `runTask` never auto-emits (no objective
* oracle → nothing to ground a fact in — we do not guess).
*/
export declare function emitTaskOutcome(deps: Pick<RunnerDeps, "onTaskOutcome">, outcome: TaskOutcome): void;