dsh-auto-flow 0.1.1 → 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,134 +1,381 @@
1
- import { ExecKillResult, ExecReadResult, ExecRequest, ExecResult, Greeting } from "./types.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
- //#region src/index.d.ts
6
- /** dsh-auto-flow 的插件配置。 */
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
+ }
30
+ /** 插件配置。 */
7
31
  interface Config {
8
- /** 问候前缀。 */
9
- prefix?: string;
10
- /** 单条 `exec` 命令允许的最大 UTF-8 字节长度。 */
11
- maxCommandBytes?: number;
32
+ /**
33
+ * 工作流运行产物根目录。
34
+ *
35
+ * 标了 volatile:它是设置页唯一可写字段,Settings 只允许写 volatile 路径,且
36
+ * `describe()` 只投影 volatile 字段(客户端设置行读的正是它)。Loader 解析后这里
37
+ * 是可读当前值的引用;改设置无需重启,每次读取经 `.get()` 取最新值。
38
+ */
39
+ workspaceDir?: Volatile<string>;
40
+ /** AI 智能体节点的子代理递归深度上限(非负安全整数;0 禁止委托)。 */
41
+ maxAgentDepth?: number;
42
+ /** 运行日志保留天数(正整数)。 */
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;
12
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>;
92
+ //#endregion
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
125
+ /** 一次运行的结算结果(模型工具 workflow_run 消费)。 */
126
+ interface RunOutcome {
127
+ runId: string;
128
+ ok: boolean;
129
+ /** Output 节点的最终值(无 output 节点时为 undefined)。 */
130
+ result?: FlowDataValue | undefined;
131
+ error?: string | undefined;
132
+ steps: RunState['steps'];
133
+ }
134
+ /**
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}。
146
+ */
13
147
  declare module '@deepseek-ai/cordis' {
14
148
  interface Context {
15
- /** 示例服务(Host 提供,浏览器经 @Remote 调用)。 */
149
+ /** Host 提供服务,浏览器经 @Remote 调用。 */
16
150
  autoFlow: AutoFlowService;
17
151
  }
18
- interface Events {
19
- /**
20
- * 一次问候已提交(域事件,跨插件实时通知 seam)。发出方在 `send` 提交后
21
- * emit;其它插件可 `ctx.on('autoFlow/recorded', ...)` 订阅。
22
- * @mode emit
23
- */
24
- 'autoFlow/recorded'(payload: {
25
- readonly greeting: Greeting;
26
- }): void;
27
- }
28
- }
29
- /**
30
- * 消息来源归属(MessageSourceMap)示例:若本插件要让「模型消息」归属到自己
31
- * (如经 `exec.deferContext` 注入的用户消息),在此新增一个 kind 并在
32
- * UserMessage.source 里使用。问候走会话事件而非模型消息,故此处仅声明词汇、
33
- * 不强制接线(参考 @deepseek-ai/dsh-goal 的 goal 来源声明)。
34
- */
35
- declare module '@deepseek-ai/dsh-llm' {
36
- interface MessageSourceMap {}
37
152
  }
153
+ //#endregion
154
+ //#region src/host/service.d.ts
38
155
  /**
39
- * 示例服务:类本身就是插件——static inject / Config 是 Cordis 类插件的约定,
40
- * 构造器里的注册(工具/事件/设置/命令)随插件卸载自动回收。
41
- *
42
- * 平台服务消费方式(跨插件协作走 Cordis 服务、禁止互相 import):
43
- * - 必需依赖用 `static inject`(tools);
44
- * - 可选依赖用 `ctx.inject([...], cb)`(settings / commands / systemPrompt /
45
- * autoFlowFormatter)——服务缺失时插件照常加载;
46
- * - shell / sandboxPolicy 是可选服务:用 `ctx.get(...)` 读取,未组合时
47
- * `exec` 报错、插件其余部分照常工作;
48
- * - 持久层异步打开走 `[Service.init]`(storageDomain 可选:缺省退化为内存态)。
156
+ * 服务类即插件。依赖消费约定:
157
+ * - 可选依赖用 ctx.inject(settings),缺失照常加载;
158
+ * - storageDomain 是硬依赖,[Service.init] 缺失时大声失败(不静默内存态);
159
+ * - ag 用 ctx.get 读取,未组合时 runFlow 报 ag-missing;
160
+ * - 持久层在 [Service.init] 异步打开。
49
161
  */
50
162
  declare class AutoFlowService extends TypertRemoteService {
51
- /** 依赖的服务;缺失时 Loader 会等待其出现。 */
52
- static inject: string[];
53
- /** Config 的 Schema(Cordis 类插件约定:Loader 读类静态 `Config` 校验注入并补齐默认值;
54
- * 模块级同名导出不会被 Loader 识别——生成插件请把 Schema 放在类上)。 */
55
- static Config: z<Config>;
56
- /** 校验后的配置(settings scope 可在运行时覆盖,故非 readonly)。 */
57
- private resolved;
58
- /** 问候的内存视图(domain storage 是持久层)。 */
59
- private readonly greetings;
60
- /** 已打开的持久化领域;无后端时保持 null(内存态兜底)。 */
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;
168
+ /** 已打开的持久化领域;未组合 storageDomain 时保持 null。 */
61
169
  private storage;
62
- /** 第二包提供的格式化服务;未安装第二包时保持 null(可选依赖)。 */
63
- private formatter;
64
- /** 最近一次提交的问候(由 `autoFlow/recorded` 监听器维护,供 @Remote last)。 */
65
- private lastRecorded;
66
- /** 后台进程句柄(@Remote 轻执行自管;不依赖 ctx.jobs,见 exec 说明)。 */
67
- private readonly background;
68
- private nextBgId;
69
- private nextId;
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;
70
186
  constructor(ctx: Context, config?: Config);
71
187
  /**
72
- * 异步初始化钩子(Cordis 类插件约定):构造完成后运行。持久层在这里打开——
73
- * 与 @deepseek-ai/dsh-message-feedback 的 `[Service.init]` 同构;storageDomain
74
- * 是可选服务,缺失时保持内存态兜底。
188
+ * 按当前配置归一化一次。
189
+ *
190
+ * 每次调用都从 volatile 引用取最新值,所以设置页改完立刻生效 —— 调用方不要缓存结果,
191
+ * 需要时现取(各消费点拿到的都是 `() => this.currentResolved()` 这样的取值闭包)。
192
+ */
193
+ private currentResolved;
194
+ /**
195
+ * 解析脚本名 → 具体来源与库内名(限定名优先,其次唯一命中的库内名)。
196
+ * 实现在 features/scripts/catalog.ts;此方法保持公开,因为模型工具与测试都从服务面取它。
75
197
  */
198
+ resolveScript(name: string): Promise<ResolvedScript | undefined>;
199
+ /** 异步初始化:打开持久层。storageDomain 是本插件硬依赖——缺失时大声失败,
200
+ * 不静默退化成内存态(否则 saveFlow 假装成功但重启即丢数据,是数据丢失陷阱)。 */
76
201
  protected [Service.init](): Promise<void>;
77
- /** 模型工具:复用 @Remote send;presentCall + presentResult 双态展示。 */
78
- private registerTool;
79
- /** 设置:同一份 Config schema 注册为可编辑 namespace,入口配置作为 base 层。 */
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
+ */
80
212
  private registerSettings;
81
- /** 从持久化领域恢复内存视图与自增 id。 */
82
- private hydrateFromStorage;
83
- /** 斜杠命令:用户键入 /auto-flow 后直接进 handler(不经过模型)。 */
84
- private registerCommand;
85
- /** 系统提示词:贡献一条模型可见指引(name 唯一、order 升序拼接)。 */
86
- private registerSystemPrompt;
87
- /** 事件:监听自身域事件维护 lastRecorded 缓存(演示 ctx.on —— 监听器随 fiber 回收)。
88
- * 其它插件也可 ctx.on('autoFlow/recorded', ...) 订阅,实现跨插件实时通知。 */
89
- private registerEvents;
90
- /** 卸载时回收所有未结束的后台进程(@Remote 轻执行自管句柄,必须随 fiber 清理)。 */
91
- private registerBackgroundCleanup;
92
- /** 跨插件服务消费:第二包(dsh-auto-flow-core)可选提供 autoFlowFormatter。
93
- * 用 ctx.inject 而非 static inject——第二包未安装时插件照常加载(send 走无格式化兜底)。 */
94
- private registerCore;
95
- /**
96
- * 追加一条问候并返回记录(写透 domain storage;若有第二包则先格式化;提交后发域事件)。
97
- *
98
- * 不追加自定义会话事件:harness 的 session 持久化读路径会拒绝 `KNOWN_SESSION_EVENT_TYPES`
99
- * 之外的事件类型(除非信封标记 `ignorable`,而 `Session.append` 无此参数),把插件
100
- * 自定义事件写进会话日志会导致该会话在重启后无法打开。
101
- */
102
- send(text: string): Promise<Greeting>;
103
- /** 返回全部问候记录(内存视图,已由 domain storage 水合)。 */
104
- list(): Promise<Greeting[]>;
105
- /** 返回最近一次提交的问候(由域事件监听器维护),首次提交前为 null。 */
106
- last(): Promise<Greeting | null>;
107
- /**
108
- * 执行一条命令行(宿主内经 ctx.shell,与 bash 工具同一执行器,绝不经过模型)。
109
- * 输出只回调用方、不进会话日志。@Remote 严格契约保证浏览器端完整类型与校验。
110
- *
111
- * 相比模型工具(@deepseek-ai/dsh-tool-bash)的 shell 面,@Remote 轻执行只能拿到
112
- * 能映射过来的子集:timeoutMs / stdoutMaxBytes / sandboxPolicy / 后台任务 / 结果保真。
113
- * 模型工具专属的 seam(shellEnv.collect 需要 ToolExecution、sandbox 升级需要 approval
114
- * + callId、abort 需要 ToolExecution.signal)不适用于 @Remote,此处不做。
115
- *
116
- * 注意:@Remote 方法不能带 `agent: Agent` 参数——第三方仓库的 typert 生成器无法解析
117
- * `agent` lookup(其 wire 类型 SessionId 是 branded 类型,官方 monorepo 内才可用)。
118
- * 因此沙箱策略退化为「部署默认」(`sandboxPolicy.resolve()` 无 session)。
119
- *
120
- * 后台执行不走 ctx.jobs(那是给模型工具 job_output/job_kill 用的,需要 agent owner +
121
- * dsh-tool-jobs 控制器,@Remote 里拿不到):直接用 `shell.start()` 拿 ShellProcess
122
- * 句柄,自管在 this.background Map 里,execRead/execKill 直接操作句柄;卸载时统一 kill。
123
- *
124
- * shell / sandboxPolicy 是可选依赖:未组合时抛对应 RemoteError,插件其余照常。
125
- */
126
- exec(request: ExecRequest): Promise<ExecResult>;
127
- /** 读后台进程的下一次增量/终态输出(自管 ShellProcess 句柄,不依赖 ctx.jobs)。 */
128
- execRead(jobId: string): Promise<ExecReadResult>;
129
- /** 请求取消后台进程(自管 ShellProcess 句柄,不依赖 ctx.jobs)。 */
130
- execKill(jobId: string): Promise<ExecKillResult>;
213
+ /** 卸载时中止在飞运行并关闭已打开的领域(Domain 句柄由调用方持有并按 effect 回收)。 */
214
+ private registerStorageCleanup;
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>;
252
+ /** 列举全部工作流摘要(id + 名称 + 描述 + 节点数 + 输入键;按 id 升序)。 */
253
+ listFlows(): Promise<FlowSummary[]>;
254
+ /** 列举历史运行摘要(按 updatedAt 倒序,来自插件自持运行日志;支持按会话/工作流过滤,含归属标签)。
255
+ * @param request - 可选过滤:发起会话与工作流(两个条件可同时使用)。 */
256
+ listRuns(request: WorkflowListRunsRequest): Promise<RunSummary[]>;
257
+ /**
258
+ * 按 id 读取工作流文档(不存在或未组合 storageDomain 时返回 null)。
259
+ *
260
+ * 读时会把脚本节点的**库内名**规范化为限定名(见 `canonicalizeScriptNames`)—— 修的是
261
+ * 「同一脚本两个身份」这个病根,而不是在下拉那一个消费点上再打一次补丁。
262
+ */
263
+ loadFlow(flowId: string): Promise<WorkflowDefinition | null>;
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
+ */
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;
307
+ /** 按 id 删除工作流。 */
308
+ deleteFlow(flowId: string): Promise<{
309
+ deleted: boolean;
310
+ }>;
311
+ /**
312
+ * 列出可运行脚本清单(展示名/描述/参数/产物装配规则 + 来源 + 加载诊断)。
313
+ *
314
+ * `name` 是**限定名**(`ag/xhs/collect`、`my-scripts/daily-report`),
315
+ * 来源是身份的一部分 —— 多个脚本库各有同名脚本时不会互相覆盖;`source` 供 UI 做一级分类。
316
+ * 未组合任何脚本来源时返回空(与改造前一致)。
317
+ */
318
+ listScripts(): Promise<ScriptInfo[]>;
319
+ /** 列出实时 LLM 模型路由(llm/agent 节点的 provider 下拉)。 */
320
+ listLlmRoutes(): WorkflowListLlmRoutesResult;
321
+ /** 列出某实时模型路由上的模型目录(llm/agent 节点的 model 下拉)。 */
322
+ listRouteModels(request: WorkflowListRouteModelsRequest): Promise<WorkflowListRouteModelsResult>;
323
+ /**
324
+ * 启动一次工作流运行(@Remote,画布触发):按层级并发执行 表单→脚本→审批,审批经画布 approveRun/cancelRun 放行。
325
+ * 返回 runId 即返回,进度经 runState 轮询;校验失败抛 invalid-flow(含诊断项)。
326
+ * sessionId 用于把产物落到「当前会话工作区」(缺省回退配置 workspaceDir)。
327
+ */
328
+ /** 画布触发运行(实现见 features/runs/coordinator.ts):只等到「运行已启动」即返回 runId。 */
329
+ runFlow(request: {
330
+ flow: FlowGraph;
331
+ workflowId?: string;
332
+ name?: string;
333
+ sessionId?: string;
334
+ }): Promise<{
335
+ runId: string;
336
+ }>;
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)。 */
365
+ runForAgent(flowId: string, args: Record<string, FlowDataValue>, agent: unknown, signal?: AbortSignal): Promise<RunOutcome>;
366
+ /** /workflow 斜杠命令的处理器(实现见 features/runs/coordinator.ts)。 */
367
+ runWorkflowCommand(invocation: {
368
+ agent: unknown;
369
+ rawInput: string;
370
+ signal: AbortSignal;
371
+ }): Promise<{
372
+ kind: 'success';
373
+ text?: string;
374
+ } | {
375
+ kind: 'error';
376
+ text: string;
377
+ }>;
131
378
  }
132
379
  //#endregion
133
- export { AutoFlowService, AutoFlowService as default, Config };
380
+ export { AutoFlowService as default };
134
381
  //# sourceMappingURL=index.d.ts.map