dsh-auto-flow 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1,19 +1,127 @@
1
- import { E as ScriptInfo, F as WorkflowListRouteModelsResult, I as WorkflowListRunsRequest, N as WorkflowListLlmRoutesResult, P as WorkflowListRouteModelsRequest, S as RunState, j as WorkflowDefinition, l as FlowSummary, o as FlowGraph, r as FlowDataValue, w as RunSummary } from "./types-B4zlU2vb.js";
2
- import { Context, Service } from "@deepseek-ai/cordis";
1
+ import { Q as RunSummary, X as RunState, _t as ScriptResult, dt as WorkflowListRouteModelsResult, f as FlowDataValue, ft as WorkflowListRunsRequest, g as FlowGraph, gt as ScriptPayload, lt as WorkflowListLlmRoutesResult, n as UnitEntryResult, rt as ScriptSourceInfo, st as WorkflowDefinition, t as RetryPlanSummary, tt as ScriptInfo, ut as WorkflowListRouteModelsRequest, vt as ScriptRunOptions, y as FlowSummary } from "./types-B5z-T_7S.js";
2
+ import { Context, Service, Volatile } from "@deepseek-ai/cordis";
3
3
  import { TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
4
4
  import z from "@deepseek-ai/schemastery";
5
5
  //#region src/host/config.d.ts
6
+ /** 一个脚本来源(哪个服务提供脚本、以及它在限定名/UI 里叫什么)。 */
7
+ interface ScriptProviderConfig {
8
+ /** 提供脚本的 Cordis 服务名(`ctx.get(<service>)`),如 ag / playwrightBg。 */
9
+ service: string;
10
+ /** 来源 id:限定名的第一段与脚本身份的一部分(稳定、可路由,改它等于改身份)。 */
11
+ id?: string;
12
+ /** 来源展示名(UI 一级分类标题);缺省用 id。 */
13
+ label?: string;
14
+ }
15
+ /**
16
+ * 一个用户脚本目录(外部用户自己写的本地脚本)。
17
+ *
18
+ * 目录里放 `scripts.json` 清单声明**入口**(只有入口是脚本,`lib/*.ts` 等只是被依赖的模块)。
19
+ * 用户脚本以**独立子进程**运行(经 `ctx.shell`,因此自带沙箱/超时/进程树回收),
20
+ * 与宿主内置脚本互不影响;代价是拿不到宿主的浏览器会话与站点凭证。
21
+ */
22
+ interface UserScriptDirConfig {
23
+ /** 目录路径(绝对路径,或相对进程工作目录)。 */
24
+ dir: string;
25
+ /** 来源 id(限定名第一段);缺省由目录名派生(小写、非字母数字转 `-`)。 */
26
+ id?: string;
27
+ /** 来源展示名(UI 一级分类标题);缺省用 id。 */
28
+ label?: string;
29
+ }
6
30
  /** 插件配置。 */
7
31
  interface Config {
8
- /** 工作流运行产物根目录。 */
9
- workspaceDir?: string;
32
+ /**
33
+ * 工作流运行产物根目录。
34
+ *
35
+ * 标了 volatile:它是设置页唯一可写字段,Settings 只允许写 volatile 路径,且
36
+ * `describe()` 只投影 volatile 字段(客户端设置行读的正是它)。Loader 解析后这里
37
+ * 是可读当前值的引用;改设置无需重启,每次读取经 `.get()` 取最新值。
38
+ */
39
+ workspaceDir?: Volatile<string>;
10
40
  /** AI 智能体节点的子代理递归深度上限(非负安全整数;0 禁止委托)。 */
11
41
  maxAgentDepth?: number;
12
42
  /** 运行日志保留天数(正整数)。 */
13
43
  runLogRetentionDays?: number;
44
+ /**
45
+ * 审批等待的**全局**超时(毫秒,不小于 {@link MIN_APPROVAL_TIMEOUT_MS})。
46
+ *
47
+ * 缺省 {@link APPROVAL_GLOBAL_TIMEOUT_MS}。这个值同时决定两件事:宿主计时器何时放弃这次等待,
48
+ * 以及暂停实体上记录的 `globalDeadline`(过期之后任何恢复入口都必须拒绝它)。
49
+ */
50
+ approvalTimeoutMs?: number;
51
+ /**
52
+ * 单次运行最多执行多少个步骤(正整数;缺省 {@link DEFAULT_MAX_RUN_STEPS})。
53
+ *
54
+ * 超出即停止整轮,停止原因写进运行记录(`AUTO_FLOW_LIMIT_EXCEEDED`)。
55
+ */
56
+ maxRunSteps?: number;
57
+ /**
58
+ * 单次运行最长墙钟毫秒(正整数;缺省 {@link DEFAULT_MAX_RUN_WALL_CLOCK_MS})。
59
+ */
60
+ maxRunWallClockMs?: number;
61
+ /**
62
+ * 脚本节点并发上限({@link MIN_RUN_CONCURRENCY}..{@link MAX_RUN_CONCURRENCY};
63
+ * 缺省 = 引擎缺省 {@link MAX_CONCURRENCY})。
64
+ */
65
+ maxRunConcurrency?: number;
66
+ /**
67
+ * 脚本来源清单(顺序 = UI 一级分类顺序)。每个来源经 `ctx.get(service)` 取,
68
+ * 并统一负责「外部用限定名(来源/脚本名)、provider 用库内名」的拆装。
69
+ * 缺省 = 单来源 ag,行为与本次改造前完全一致(脚本名不加前缀地兼容旧写法)。
70
+ */
71
+ scriptProviders?: ScriptProviderConfig[];
72
+ /**
73
+ * 外部用户脚本目录(缺省/空数组 = 关闭该能力)。每个目录成为一个来源分组,
74
+ * 见 {@link UserScriptDirConfig};目录里必须有 `scripts.json` 清单。
75
+ */
76
+ userScriptDirs?: Array<string | UserScriptDirConfig>;
77
+ /** 用户脚本单次运行的超时(毫秒;非正数 → 用默认值)。 */
78
+ userScriptTimeoutMs?: number;
14
79
  }
80
+ /**
81
+ * 配置 schema:Loader 校验的类静态 Config 就是这个值(见 service.ts 的 static Config)。
82
+ *
83
+ * 输入侧泛型只能是 `any`:schemastery 推导出的输入类型是 `ObjectS<…> & Dict`,其中 `Dict` 来自
84
+ * cosmokit,无法在生成的 .d.ts 里被命名(TS2883,tsdown 构建会失败)。输出侧仍由 {@link Config}
85
+ * 精确约束,故插件内所有取值都有类型。上游 agent-default-model 干脆不写注解,本包因要导出
86
+ * schema 而必须写,故退到这一层。
87
+ *
88
+ * `workspaceDir` 的 `.volatile()` 是设置页可写的前提;`.min(1)` 则把「空目录」挡在写入/加载处
89
+ * (原先由 installSection 的 validate 钩子做,该钩子已随 installSection 一起被上游删除)。
90
+ */
91
+ declare const Config: z<any, Config>;
15
92
  //#endregion
16
- //#region src/host/service.d.ts
93
+ //#region src/host/features/scripts/registry.d.ts
94
+ /** 一个来源 + 它的运行面(provider 契约的结构化最小面)。 */
95
+ interface ScriptProvider {
96
+ /** 来源身份:限定名的前缀、UI 一级分类。 */
97
+ source: ScriptSourceInfo;
98
+ /**
99
+ * 本库脚本清单(`name` 是**库内名**,不含来源前缀)。
100
+ *
101
+ * 类型取 `ScriptInfo`(脚本在工作流里的**消费侧视图**)而不是线格式 `ScriptMeta`:
102
+ * 用户脚本清单是**不可信输入**(`userScriptDirs` 下的 JSON 由用户写),
103
+ * `params[].children` 可能缺 —— 消费侧视图里它是可选,线格式里必填。
104
+ * 两侧的分歧已由 `packages/shared/policy.facts.json` 的 `contractDivergence` 登记。
105
+ */
106
+ listScripts(): Promise<ScriptInfo[]>;
107
+ /**
108
+ * 按**库内名**运行。调用方传入的限定名已由本注册表拆掉前缀。
109
+ *
110
+ * 参数用契约真源类型(而不是 `Record<string, unknown>`):两个实现(插件服务、用户脚本目录)
111
+ * 本来就拿得到真类型,中间接口擦成 `unknown` 只会逼调用点在接缝上写 `as`。
112
+ */
113
+ runScript(script: string, payload: ScriptPayload, options?: ScriptRunOptions, signal?: AbortSignal | undefined): Promise<ScriptResult>;
114
+ }
115
+ /** 解析成功:限定名 + 该由谁跑 + 用什么库内名跑。 */
116
+ interface ResolvedScript {
117
+ /** 对外身份(限定名)。 */
118
+ qualified: string;
119
+ provider: ScriptProvider;
120
+ /** provider 内的脚本名(拆掉来源前缀)。 */
121
+ localName: string;
122
+ }
123
+ //#endregion
124
+ //#region src/host/contracts.d.ts
17
125
  /** 一次运行的结算结果(模型工具 workflow_run 消费)。 */
18
126
  interface RunOutcome {
19
127
  runId: string;
@@ -24,110 +132,200 @@ interface RunOutcome {
24
132
  steps: RunState['steps'];
25
133
  }
26
134
  /**
27
- * playwright-ag 的运行时契约(最小面):本插件经 ctx.get('playwrightAg') 消费,不硬依赖其包。
28
- * 这是 playwright-ag host 服务 `run`/`listScripts` 的镜像,真源在其 src/host/service.ts 与
29
- * src/types.ts(ScriptResult/ScriptMeta)——两侧保持结构化同步,改动时须一起改。
135
+ * 【为什么本包**不**声明 `Context.ag` / `Context.playwrightBg`】官方 dsh 的惯例是
136
+ * **每个插件声明自己的槽位**(实测官方包:`Context.agents: AgentRegistry`、
137
+ * `agentLoop: AgentLoop`、`typertGateway: TypertGateway`),**消费方不替供应方声明**。
138
+ *
139
+ * 此前本包写了 `ag?: ScriptProviderContract`,而 `dsh-ag` 自己写的是 `ag: AgService` ——
140
+ * 同一个 key 两处不同类型,实测放进同一个 TS 程序会报 `TS2717` + `TS2687`,
141
+ * 今天不报只是因为业务包互不依赖、永远不在同一个程序里。
142
+ *
143
+ * 删掉本包的声明后:冲突从根上消失(不是「改成一致」,是**根本没有第二处声明**),
144
+ * 而且对**任意数量**的供应方都成立 —— 加一个 `bg` 不需要回来改这里。
145
+ * 读供应方一律走 {@link scriptProviderOf}。
30
146
  */
31
- interface PlaywrightAgContract {
32
- /** 进程内运行(非 @Remote):可带 AbortSignal,取消时穿透关闭浏览器会话。 */
33
- runScript(script: string, payload: Record<string, FlowDataValue>, options?: {
34
- baseDir?: string | undefined;
35
- runId?: string | undefined;
36
- browser?: {
37
- headless?: boolean;
38
- channel?: string;
39
- } | undefined;
40
- timeoutMs?: number | undefined;
41
- }, signal?: AbortSignal | undefined): Promise<ScriptResultWire>;
42
- listScripts(): Promise<ScriptInfo[]>;
43
- }
44
- /** ScriptRunMeta 的镜像(真源 playwright-ag src/types.ts)。 */
45
- type ScriptRunMetaWire = {
46
- startedAt: number;
47
- finishedAt: number;
48
- durationMs: number;
49
- };
50
- /** ScriptResult 的镜像:必须无损——meta(耗时)与 error.code(稳定错误码)不得丢弃。 */
51
- type ScriptResultWire = {
52
- ok: true;
53
- script: string;
54
- data: FlowDataValue;
55
- meta: ScriptRunMetaWire;
56
- } | {
57
- ok: false;
58
- script: string;
59
- error: {
60
- code: string;
61
- message: string;
62
- };
63
- meta: ScriptRunMetaWire;
64
- };
65
147
  declare module '@deepseek-ai/cordis' {
66
148
  interface Context {
67
149
  /** Host 提供服务,浏览器经 @Remote 调用。 */
68
150
  autoFlow: AutoFlowService;
69
- /** 浏览器自动化脚本服务(playwright-ag 插件),缺失时 runFlow 报错。 */
70
- playwrightAg?: PlaywrightAgContract;
71
151
  }
72
152
  }
153
+ //#endregion
154
+ //#region src/host/service.d.ts
73
155
  /**
74
156
  * 服务类即插件。依赖消费约定:
75
157
  * - 可选依赖用 ctx.inject(settings),缺失照常加载;
76
158
  * - storageDomain 是硬依赖,[Service.init] 缺失时大声失败(不静默内存态);
77
- * - playwrightAg 用 ctx.get 读取,未组合时 runFlow 报 playwright-missing;
159
+ * - ag 用 ctx.get 读取,未组合时 runFlow 报 ag-missing;
78
160
  * - 持久层在 [Service.init] 异步打开。
79
161
  */
80
162
  declare class AutoFlowService extends TypertRemoteService {
81
- /** Config 的 Schema。Cordis 约定:Loader 读类静态 Config,请放在类上(模块级同名导出不会被识别)。 */
82
- static Config: z<Config>;
83
- /** 校验后的配置(settings scope 可在运行时覆盖,故非 readonly)。 */
84
- private resolved;
163
+ /** Config 的 Schema。Cordis 约定:Loader 读类静态 Config,请放在类上(模块级同名导出不会被识别)。
164
+ * 输入侧 any 的理由见 config.ts 的 Config 注释(`Dict` 无法在 .d.ts 中命名)。 */
165
+ static Config: z<any, Config>;
166
+ /** Loader 解析后的配置。volatile 字段是运行期可读的引用,故每次用时重新解析。 */
167
+ private readonly config;
85
168
  /** 已打开的持久化领域;未组合 storageDomain 时保持 null。 */
86
169
  private storage;
87
- /** 运行中的工作流运行时(runId → 状态 + 审批放行句柄);终态后回收。 */
88
- private readonly runRuntimes;
89
- /** 进行中运行的中止控制器(runId → AbortController);cancelRun 触发,终态回收。 */
90
- private readonly runControllers;
91
- /** 插件自持的运行日志(追加式按天 JSONL;终态 settled 记录只写一次)。 */
92
- private runStore;
93
- /** 已追加进运行日志的 runId(终态 append 幂等守卫)。 */
94
- private readonly persistedRunIds;
95
- /** 进行中的终态追加(runId → append Promise);结算返回前 await 它保证落盘先于结算。 */
96
- private readonly pendingPersists;
170
+ /** 运行态注册表:运行时句柄 / 取消控制器 / 运行日志 / 终态持久化。 */
171
+ private readonly runs;
172
+ /** 脚本目录与注册表:内置脚本来源 + 用户脚本目录。 */
173
+ private readonly catalog;
174
+ /** 运行编排:起运行 / 审批 / 嵌套 / Agent 委派 / 取消放行。 */
175
+ private readonly coordinator;
176
+ /**
177
+ * 应用单元入口结果(单元名 → 该单元的入口结果);空表 = 宿主没有信任门,根本没有去挂单元。
178
+ *
179
+ * 【为什么存 Promise 而不是地址】地址要等单元服务监听就绪才知道(端口可能来自本地开发配置),而
180
+ * 客户端半边每次打开浮层只问一次、并把"给不出地址"当终态:若把"还没就绪"也写成失败,宿主刚起来那
181
+ * 一下点开就会被永久判成"没有入口"。存 Promise 让那一次询问等到结果(失败折成带原因的结果)。
182
+ */
183
+ private unitEntries;
184
+ /** 「宿主没有信任门」这条 warn 是否已经记过(每次打开浮层都会走到那条分支,故只记一次)。 */
185
+ private warnedNoGate;
97
186
  constructor(ctx: Context, config?: Config);
187
+ /**
188
+ * 按当前配置归一化一次。
189
+ *
190
+ * 每次调用都从 volatile 引用取最新值,所以设置页改完立刻生效 —— 调用方不要缓存结果,
191
+ * 需要时现取(各消费点拿到的都是 `() => this.currentResolved()` 这样的取值闭包)。
192
+ */
193
+ private currentResolved;
194
+ /**
195
+ * 解析脚本名 → 具体来源与库内名(限定名优先,其次唯一命中的库内名)。
196
+ * 实现在 features/scripts/catalog.ts;此方法保持公开,因为模型工具与测试都从服务面取它。
197
+ */
198
+ resolveScript(name: string): Promise<ResolvedScript | undefined>;
98
199
  /** 异步初始化:打开持久层。storageDomain 是本插件硬依赖——缺失时大声失败,
99
200
  * 不静默退化成内存态(否则 saveFlow 假装成功但重启即丢数据,是数据丢失陷阱)。 */
100
201
  protected [Service.init](): Promise<void>;
101
- /** 把同一份 Config schema 注册为可编辑的 settings namespace。 */
202
+ /**
203
+ * 声明本插件的设置展示策略。
204
+ *
205
+ * 上游 0.2.0-rc.2 删掉了 `installSection`:插件的 Config schema 由 Loader 持有,Settings
206
+ * 扫描已装插件自动出表单,插件侧只剩「展示策略」要声明。`auto: false` = 本插件自带设置行
207
+ * (见 src/client/apply.ts 注册的 `settings.general.item`),不要再自动生成一个页面。
208
+ *
209
+ * 配置热生效**不在这里**:靠 Config 上 `workspaceDir` 的 `.volatile()` 与读取时的
210
+ * `.get()`(见 currentResolved),所以本方法不再持有 onChange / readConfig 之类状态。
211
+ */
102
212
  private registerSettings;
103
213
  /** 卸载时中止在飞运行并关闭已打开的领域(Domain 句柄由调用方持有并按 effect 回收)。 */
104
214
  private registerStorageCleanup;
105
- /** 依据当前 resolved 配置重建运行日志(workspaceDir / 保留期变更时随之重建)。 */
106
- private rebuildRunStore;
215
+ /**
216
+ * 挂载本插件的前端应用单元(登记表在 `src/app-units.ts`,装配在 `features/app-unit/mount.ts`)。
217
+ *
218
+ * 【为什么用 `ctx.inject` 而不是硬依赖 connection】单元服务要宿主提供"给入口 HTML 加门"的能力
219
+ * (平台 connection 的进程令牌与签名 cookie);有些宿主组合(例如桌面端走 `file://` + IPC)没有这个
220
+ * 服务 —— 缺失时插件照常加载,只是没有那个整页面板(`unitUrl` 给出原因),其余能力不受影响。
221
+ *
222
+ * 【为什么依赖表逐个列在这里而不是把服务交给 BFF】BFF 走的是进程内直取(不经 `{ ok, value }` 信封
223
+ * 那条通道),它能取到什么**只由这张表决定**;漏接一个编译期就红,不会拖到运行时才发现某个面板
224
+ * 功能是空的。
225
+ *
226
+ * 【为什么不在回调里 await 单元就绪】端口被占用属于环境问题:它不该让整个插件(含模型工具与斜杠
227
+ * 命令)加载失败。故失败只走"这个单元没起来"这一条通道:结果里带原因,宿主日志留一条 warn。
228
+ *
229
+ * 【加一个单元不再需要改这里】这里只有**一次**通用挂载调用:它按登记表把全部单元各挂一份。
230
+ */
231
+ private registerAppUnits;
232
+ /**
233
+ * 某个应用单元的入口结果(带进程令牌的地址,或一条给面板看的原因)。
234
+ *
235
+ * 客户端半边把地址当 iframe 的 `src`:地址里带着进程令牌,单元服务据此换出 HttpOnly cookie
236
+ * (见 `app-unit` 的 README 的门一节)。
237
+ *
238
+ * 【为什么是 async】等单元就绪再回答 —— 见 `unitEntries` 字段的注释:客户端每次打开浮层只问一次,
239
+ * 把"还没就绪"也当成"没有入口"会让宿主刚起来那一下点开被永久判错。
240
+ *
241
+ * 【为什么按单元名问】会话面板里有几个入口就有几个单元(清单见 `src/client/dock-units.ts`):地址只由
242
+ * 询问方决定,宿主不替它挑一个。客户端半那边用的是**单元名的字面量**(它不许 import 登记表),与登记表
243
+ * 的对应由 `tests/client/apply.spec.tsx` 的一条断言守住;这里再判一次"在不在登记表里" —— 那一档的
244
+ * 原因要能让用户自查。
245
+ *
246
+ * @param unit - 单元名(登记表 `APP_UNITS` 的键)。
247
+ * @returns `{ url }` 或 `{ url: null, reason }`(缺前端、端口被占、本地开发配置非法…各自带原因与
248
+ * 处置命令);宿主没有信任门、或这个名字不在登记表里时,各给一条说明。
249
+ * **宿主没有信任门那一条在宿主日志留一条 warn。**
250
+ */
251
+ unitUrl(unit: string): Promise<UnitEntryResult>;
107
252
  /** 列举全部工作流摘要(id + 名称 + 描述 + 节点数 + 输入键;按 id 升序)。 */
108
253
  listFlows(): Promise<FlowSummary[]>;
109
254
  /** 列举历史运行摘要(按 updatedAt 倒序,来自插件自持运行日志;支持按会话/工作流过滤,含归属标签)。
110
255
  * @param request - 可选过滤:发起会话与工作流(两个条件可同时使用)。 */
111
256
  listRuns(request: WorkflowListRunsRequest): Promise<RunSummary[]>;
112
- /** 按 id 读取工作流文档(不存在或未组合 storageDomain 时返回 null)。 */
257
+ /**
258
+ * 按 id 读取工作流文档(不存在或未组合 storageDomain 时返回 null)。
259
+ *
260
+ * 读时会把脚本节点的**库内名**规范化为限定名(见 `canonicalizeScriptNames`)—— 修的是
261
+ * 「同一脚本两个身份」这个病根,而不是在下拉那一个消费点上再打一次补丁。
262
+ */
113
263
  loadFlow(flowId: string): Promise<WorkflowDefinition | null>;
114
- /** 按 id 保存工作流文档(domain 打开时落盘,否则仅返回原样;失败大声抛出)。 */
264
+ /**
265
+ * 按 id 保存工作流文档(domain 打开时落盘,否则仅返回原样;失败大声抛出)。
266
+ *
267
+ * 写时同样规范化:这是**保证不变量成立的那一步** —— 画布新建的工作流以示例种子起步,
268
+ * 而种子按设计存库内名(来源 id 是运行时配置,静态模板不能硬编码它),所以只有在落盘前
269
+ * 改写一次,存档里才会是规范形态。返回值是**实际落盘**的文档(不再是入参原样)。
270
+ *
271
+ * 【为什么这个入口**不**做语义校验】它是画布的自动保存(fire-and-forget):半成品草稿
272
+ * 必须落盘 —— 一旦拦下,用户那次编辑就静默丢了(`useFlowAutosave` 是 `void` 调用,没人接
273
+ * 这个 rejection)。这里曾经调 `assertFlowValid`,于是「把某字段标成必填但还没填」「数值越界」
274
+ * 这类**编辑中的常态**会让整份文档存不进去,而界面上没有任何提示。
275
+ *
276
+ * 判据没有消失,只是换了承载者(同一份 `validateFlow`,强度按阶段分档):
277
+ * - **展示**:画布客户端算同一份诊断并画成节点徽标 / 字段级提示(`useFlowDiagnostics`);
278
+ * - **拒绝**:运行入口(`RunCoordinator`,失败有错误卡片承载)与模型工具 `workflow_save`
279
+ * (错误回到模型手里,它可以改)各自显式调 `assertFlowValid`。
280
+ *
281
+ * @throws {Error} 规范化或存储层失败(domain 不可用、写盘出错)—— 这些是真失败,必须冒泡。
282
+ */
115
283
  saveFlow(flowId: string, flow: WorkflowDefinition): Promise<WorkflowDefinition>;
284
+ /**
285
+ * 语义校验入口:**委托给运行协调器的同一入口**(判据只有一处)。
286
+ *
287
+ * 调用方按阶段自己决定强度:模型工具 `workflow_save` 在写盘前调它(错误回到模型手里),
288
+ * 运行入口调它并带上脚本参数清单与环境能力集(失败有错误卡片承载)。
289
+ * 画布自动保存**不调**它 —— 理由见 `saveFlow` 的文档。
290
+ *
291
+ * @param flow - 待校验的文档(应当已经规范化)。
292
+ * @throws {RemoteError} `autoFlow/invalid-flow`(见 `RunCoordinator.assertFlowValid`)。
293
+ */
294
+ assertFlowValid(flow: WorkflowDefinition): Promise<void>;
295
+ /**
296
+ * 把文档里脚本节点的库内名规范化为限定名。
297
+ *
298
+ * **快路径(不碰脚本目录)**:文档里没有需要解析的库内名时直接返回原文档。判据只用同步可得
299
+ * 的信息(`scriptRegistry().sources()` 来自配置),因此「已经全是限定名」的文档(如 ygs
300
+ * 那几个)零额外开销,也不会因为脚本目录故障而受影响。
301
+ *
302
+ * **兜底必须有主**:脚本目录解析失败(来源服务缺失、`listScripts` 抛错、同来源内重名)时
303
+ * 返回**原文档**并放行。触发条件 = 脚本目录不可用;为什么在这里处理 = 目录的问题不该让
304
+ * 「打开工作流」失败;用户看到 = 工作流正常打开,下拉显示原名(客户端兜底负责)。
305
+ */
306
+ private canonicalize;
116
307
  /** 按 id 删除工作流。 */
117
308
  deleteFlow(flowId: string): Promise<{
118
309
  deleted: boolean;
119
310
  }>;
120
- /** 列出可运行脚本清单(展示名/描述/参数/产物装配规则;playwright-ag 为准,缺失时返回空)。 */
311
+ /**
312
+ * 列出可运行脚本清单(展示名/描述/参数/产物装配规则 + 来源 + 加载诊断)。
313
+ *
314
+ * `name` 是**限定名**(`ag/xhs/collect`、`my-scripts/daily-report`),
315
+ * 来源是身份的一部分 —— 多个脚本库各有同名脚本时不会互相覆盖;`source` 供 UI 做一级分类。
316
+ * 未组合任何脚本来源时返回空(与改造前一致)。
317
+ */
121
318
  listScripts(): Promise<ScriptInfo[]>;
122
- /** 列出实时 LLM 模型路由(llm/vision/agent 节点的 provider 下拉)。 */
319
+ /** 列出实时 LLM 模型路由(llm/agent 节点的 provider 下拉)。 */
123
320
  listLlmRoutes(): WorkflowListLlmRoutesResult;
124
- /** 列出某实时模型路由上的模型目录(llm/vision/agent 节点的 model 下拉)。 */
321
+ /** 列出某实时模型路由上的模型目录(llm/agent 节点的 model 下拉)。 */
125
322
  listRouteModels(request: WorkflowListRouteModelsRequest): Promise<WorkflowListRouteModelsResult>;
126
323
  /**
127
324
  * 启动一次工作流运行(@Remote,画布触发):按层级并发执行 表单→脚本→审批,审批经画布 approveRun/cancelRun 放行。
128
325
  * 返回 runId 即返回,进度经 runState 轮询;校验失败抛 invalid-flow(含诊断项)。
129
326
  * sessionId 用于把产物落到「当前会话工作区」(缺省回退配置 workspaceDir)。
130
327
  */
328
+ /** 画布触发运行(实现见 features/runs/coordinator.ts):只等到「运行已启动」即返回 runId。 */
131
329
  runFlow(request: {
132
330
  flow: FlowGraph;
133
331
  workflowId?: string;
@@ -136,41 +334,36 @@ declare class AutoFlowService extends TypertRemoteService {
136
334
  }): Promise<{
137
335
  runId: string;
138
336
  }>;
139
- /** 解析本次运行应写入的工作区根目录:优先触发会话的 header.cwd,否则配置 workspaceDir 兜底。 */
140
- private resolveWorkspaceRoot;
141
- /**
142
- * 启动一次运行并返回结算句柄(宿主内部,供 @Remote runFlow 与模型工具共用)。
143
- * @param flow 画布(本方法负责校验)。
144
- * @param waitApproval 审批等待器工厂 (runtime, step, options) => Promise<string>(返回选中的选项标签)。
145
- * @param runContext 运行归属与触发方:workflowId/name/sessionId 是运行记录归属标签;
146
- * workspaceRoot 是产物根目录(缺省配置 workspaceDir);有 parent 且部署有 subagents 时
147
- * AI 智能体节点才可用;recordSession 存在时把 auto-flow/* 运行事实追加为会话事件(会话进度);
148
- * depth 是调用工作流节点的嵌套深度。
149
- */
150
- private startRun;
151
- /** 画布审批等待器:挂起直至 approveRun/cancelRun 放行;30 分钟无人处理则自动取消。 */
152
- private canvasWaitApproval;
153
- /** 审批提问等待器:经 userQuestions 交互卡片让用户选择;无交互 UI 时回退画布审批。 */
154
- private chatWaitApproval;
155
- /**
156
- * 调用工作流节点(硬→硬复用)的嵌套运行:加载目标工作流、合并 args、复用本运行的
157
- * parent/session/signal 再跑一次 startRun,并把其 Output 值作为节点结果回灌。
158
- * @param workflowId 目标工作流 id。
159
- * @param args 覆盖目标工作流表单默认值的运行参数。
160
- * @param parent 外层运行的父代理(审批卡片与会话归属用)。
161
- * @param recordSession 外层运行的会话记录目标(嵌套进度追加到同一会话)。
162
- * @param signal 外层运行的取消信号(取消外层即中止嵌套运行)。
163
- * @param depth 当前嵌套深度(0 = 顶层);达到上限即拒绝,防无限递归。
164
- */
165
- private runNestedWorkflow;
166
- /** 画布场景的嵌套审批上抛:把嵌套运行加入根运行的上抛队列,画布经根 runId 即可看到/操作它。 */
167
- private delegatedCanvasWaitApproval;
168
- /** 供模型工具:按 flowId 加载并运行,args 覆盖表单默认值,等待完成返回结算结果。
169
- * 同时把最近一条用户消息的图片/文本补填进缺失的 image/task 输入(会话上下文注入)。 */
337
+ /** 轮询运行状态(内存权威;未在内存中时读运行日志兜底)。 */
338
+ runState(runId: string): Promise<RunState | null>;
339
+ /** 取消运行(协作式;画布根运行会连带取消其审批上抛队列里的嵌套运行)。 */
340
+ cancelRun(runId: string): Promise<RunState>;
341
+ /** 放行/驳回一个等待中的审批(宿主重启后会自动先恢复该运行,再应用这次答复)。 */
342
+ approveRun(runId: string, choice: string): Promise<RunState>;
343
+ /**
344
+ * 恢复一个暂停中的运行(宿主重启 / 进程被杀之后的续跑入口)。
345
+ *
346
+ * @param runId - 目标运行(磁盘上要有中途快照与未答复的暂停实体)。
347
+ * @returns 恢复后的运行状态(已在跑)。
348
+ */
349
+ resumeRun(runId: string): Promise<RunState>;
350
+ /**
351
+ * **重试未成功项**(与「重新运行」并列、行为可区分)。
352
+ *
353
+ * 读该运行的批次台账,算出没成功的业务键,只补做那些;正常执行不读台账。
354
+ * 无业务键的批次被**明确拒绝**(`autoFlow/batch-not-retryable`),不静默退化成按下标跳过。
355
+ *
356
+ * @param runId - 目标运行(终态记录或暂停态现场都行)。
357
+ * @returns 新运行的 runId + 本次计划(待补条数 / 跳过策略)。
358
+ * @throws `autoFlow/run-not-found` / `autoFlow/run-not-retryable` / `autoFlow/batch-not-retryable`。
359
+ */
360
+ retryRun(runId: string): Promise<{
361
+ runId: string;
362
+ plan: RetryPlanSummary;
363
+ }>;
364
+ /** 由模型工具触发一次工作流运行(实现见 features/runs/coordinator.ts)。 */
170
365
  runForAgent(flowId: string, args: Record<string, FlowDataValue>, agent: unknown, signal?: AbortSignal): Promise<RunOutcome>;
171
- /** 把最近一条用户消息的图片/文本补填进运行参数(image/task);无会话或已显式传入时原样返回。 */
172
- private resolveSessionRunArgs;
173
- /** 执行 /workflow 命令:不带参数列出工作流;/workflow <id> [key=value ...] 运行并等待结算。 */
366
+ /** /workflow 斜杠命令的处理器(实现见 features/runs/coordinator.ts)。 */
174
367
  runWorkflowCommand(invocation: {
175
368
  agent: unknown;
176
369
  rawInput: string;
@@ -182,30 +375,6 @@ declare class AutoFlowService extends TypertRemoteService {
182
375
  kind: 'error';
183
376
  text: string;
184
377
  }>;
185
- /** 把 AI 智能体节点的子任务委托给子代理(LLM + 工具循环),返回最终文本。 */
186
- private delegateToAgent;
187
- /** 轮询运行状态(内存权威;未在内存中时读运行日志兜底)。 */
188
- runState(runId: string): Promise<RunState | null>;
189
- /** 取消运行:协作式取消,中止在飞的脚本/LLM/shell/HTTP,引擎在下一个步骤边界停下;若正等待审批则放行让引擎退出。
190
- * 画布面向的根运行取消时会连带取消其整个审批上抛队列中的嵌套运行。 */
191
- cancelRun(runId: string): Promise<RunState>;
192
- /** 审批选择:choice = 审批节点的某个选项标签;画布用根 runId 操作时,自动作用于当前待处理的嵌套审批(队首)。 */
193
- approveRun(runId: string, choice: string): Promise<RunState>;
194
- /**
195
- * 解析运行时的「画布可见运行」:若传入的是画布面向的根 runId 且其审批上抛队列非空,
196
- * 则返回队首待处理的嵌套运行(跳过已不再等待的残留项);否则返回该运行时本身。
197
- */
198
- private resolveRuntime;
199
- /**
200
- * 从审批上抛队列中取出当前应处理的运行时:
201
- * - 若传入的是被上抛的嵌套运行时(有反向指针),从根的队列里移除自身并返回自身;
202
- * - 若传入的是根运行,取出并返回队首嵌套运行,队列为空时返回根自身。
203
- */
204
- private takePendingApproval;
205
- /** 清除审批等待超时定时器(放行/驳回/终态时调用)。 */
206
- private clearApprovalTimer;
207
- private failRun;
208
- private persistRun;
209
378
  }
210
379
  //#endregion
211
380
  export { AutoFlowService as default };