/** * **一条 durable run 的「建行 + 驱动」单一属主**(S-218 提取;此前整段住在 `routes/runs.ts` 的 * `createDurableRun` 里,只服务 HTTP/A2A 两条提交门)。 * * 🔴 为什么提成模块:`/decide` 的 workflow 第三条车道在**宿主不在 park 上**时,同样要在宿主会话上起 * 一跑新 turn 把决定交给宿主的模型(S-218)。这条链上挂着 `createRun` 的会话 claim(以及它唯一诚实的 * 409 出路)、checkpoint ctx 落库、fleet 行发布、resume/rewind 两族锚点捕获、审批 ALS、通告投递…… * 手抄第二份 = 把这十来件事复制成两份会漂的实现,而漂开的那天没有任何东西会说话(`createDurableRun` * 当年从路由体里提取出来时,头注写的就是同一条判词)。方向:`routes/runs.ts` 与 `http/server.ts` * 都 import 本模块,本模块谁都不 import —— 与 `http/run-meta.ts` 同一条「两个域共用一件 ⇒ 单独成文件」。 * * 边界(本腿**不**含的东西,留给各自的门):`body.taskId` 幂等重放、`Idempotency-Key` 内存去重、 * lease / 治理窗 pre-admission、属主门。它们是**提交面**的判据(读请求、写响应),而本腿只吃已经备好的 * `PreparedTaskSubmission` 并交回一份收据 —— 这正是它能被一条没有 `ServerResponse` 的内部车道复用的原因。 */ import { type RunInternals } from "@sema-agent/core"; import type { RunStore } from "../plugins/store-backend.js"; import type { PreparedTaskSubmission, RouteCtxBase } from "./route-ctx.js"; /** * 🔴 **TRUSTED run internals** —— 由**部署方**(不是模型、不是请求体、不是工具参数)铸给这一跑的 * core 内部席位。今天唯一成员 `workflowParkedResume` = 人对一条 parked workflow 子代的决定 * (语义属主 = core `RunInternals.workflowParkedResume` 的 d.ts 顶注:「A host that decided a workflow * child's parked checkpoint launches the run that re-invokes `Workflow({resumeFromRunId})` with the * decision here」)。 * * 为什么单独命名而不是直接摊 `RunInternals`:`RunInternals` 里绝大多数席位是**执行腿自己**铸的 * (onForwardEvent / onTaskNotification / onActivity …),把整只类型开给调用方等于邀请第二个写者; * 本类型只开「部署方可以决定的那一格」,新增一格时**必须**在这里显式点名,编译期看得见。 * 缺席 ⇒ 对两条腿都是完整 no-op。 */ export type TrustedRunInternals = Pick; export interface DurableRunLegArgs { /** `prepareSpec` 的产物,或内部车道按同一条 `resolveSpec` 装配出来的等价形。 */ prepared: PreparedTaskSubmission; /** 调用方自带的 taskId(`POST /v1/runs` 的 `body.taskId` 幂等键);缺席 ⇒ 本腿铸 uuidv7。 */ clientTaskId?: string; /** 🔒 这条 run 的 **fleet 行 scope** —— 必须与 `GET /v1/fleet/stream` 过滤用的是同一个身份,且绝不是 * 自报的 `x-agent-principal` 头(自报头会把行打到受害者的 scope 上,或打到 `default` 而真属主的流把它 * 过滤掉)。提交门传 `gatedPrincipal(req) ?? "default"`;`/decide` 的第三条车道传 resume 家族的 * `resumeFleetScope(req, auth)`(同一条 wire 上两条腿因此同答)。 */ fleetScope: string; /** 🔒 这条 run 的 **elicit / question 应答方**(E23:与 respond 门读的是同一个已验身份,不是自报头)。 * 提交门传 `gatedPrincipal(req) ?? null` = 提交者本人;`/decide` 的第三条车道传**卡属主**(= 原提交者, * 不是代为按下按钮的 operator —— 与 resume 腿那条成文口径逐字同源)。`null` = 匿名/开放部署。 */ elicitOwner: string | null; /** run 行元数据的 `source` 列(调用方的系统身份;内部车道传自己的车道名)。 */ source: string | null; /** 见 {@link TrustedRunInternals}。缺席 ⇒ 与本位存在之前逐字相同。 */ trustedInternals?: TrustedRunInternals; } /** * 建行 + 驱动。返回 `202` = 新行已建并在跑(体带 `taskId`/`sessionId`);`409` = 会话被别的 run 占着, * **没有**建行(体 = `buildActiveRunConflict` 的既有形,含 `errorCode: "conflict.session_active_run"`)。 * 协议渲染归调用方(HTTP `sendJson` / A2A 协议对象 / `/decide` 的受理体)。 */ export declare function mintAndDriveDurableRun(ctx: RouteCtxBase, runStore: RunStore, args: DurableRunLegArgs): Promise<{ status: number; body: { taskId: string; sessionId: string; status: string; } | object; }>; //# sourceMappingURL=durable-run-leg.d.ts.map