@metagptx/deepflow-suite-cli 0.2.3 → 0.2.4

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.
@@ -2,13 +2,13 @@
2
2
  "schemaVersion": 1,
3
3
  "distribution": "deepflow-suite",
4
4
  "package": "@metagptx/deepflow-suite-cli",
5
- "version": "0.2.3",
5
+ "version": "0.2.4",
6
6
  "platform": "any",
7
7
  "arch": "any",
8
8
  "cli": {
9
9
  "name": "deepflow-suite",
10
10
  "package": "@metagptx/deepflow-suite-cli",
11
- "version": "0.2.3",
11
+ "version": "0.2.4",
12
12
  "command": "deepflow-suite"
13
13
  },
14
14
  "skills": [
@@ -19,7 +19,7 @@
19
19
  {
20
20
  "path": "manifest.yaml",
21
21
  "size": 362,
22
- "sha256": "dc6578c11a62a29fee194a268ede90d1d8659b0f731787ca3fdab557bc39d51f"
22
+ "sha256": "0c0675ab463b18a05d7903956cbd307a7952d71d0f1c8dfc672b1314c285e991"
23
23
  },
24
24
  {
25
25
  "path": "SKILL.md",
@@ -39,8 +39,8 @@
39
39
  },
40
40
  {
41
41
  "path": "SKILL.md",
42
- "size": 2758,
43
- "sha256": "c86ee01f8b130669f87efc223ffdeff96841a89037c39738eaf8730bdd58091b"
42
+ "size": 3502,
43
+ "sha256": "9a0e81ec5df799b1fa7fb0ed3f7ec1ac97228c34baa8e6b83ea857e30e8aff85"
44
44
  }
45
45
  ]
46
46
  },
@@ -80,8 +80,8 @@
80
80
  },
81
81
  {
82
82
  "path": "references/fact-types.md",
83
- "size": 3353,
84
- "sha256": "37c13c13822734744d9f4a73710e1206009eeb037102620ccdb77af78e1dcb39"
83
+ "size": 3834,
84
+ "sha256": "66382b303f33944939be564722081549a45f1fbf737aa5dfc15d92274823d469"
85
85
  },
86
86
  {
87
87
  "path": "skill_test.go",
@@ -90,8 +90,8 @@
90
90
  },
91
91
  {
92
92
  "path": "SKILL.md",
93
- "size": 12155,
94
- "sha256": "aec1bb832519f6503b9e17cbe34bf4ff39bac451f57912d5cd42de1a3e2e77e2"
93
+ "size": 12929,
94
+ "sha256": "7568468972badececb0a82fd47a90b044da30142ad1df12bcc45f6b8735c0cdb"
95
95
  }
96
96
  ]
97
97
  },
@@ -138,8 +138,8 @@
138
138
  "files": [
139
139
  {
140
140
  "path": "SKILL.md",
141
- "size": 10128,
142
- "sha256": "baa0cac18c1683a0b2e52ab301854d8dc9e907ccd3ae451b2357b1780c2e3f33"
141
+ "size": 10329,
142
+ "sha256": "a18557c3dac45c0ef90eee38c2e31099c5045c9b898c842e5e16cecce8d5452a"
143
143
  }
144
144
  ]
145
145
  },
@@ -1,5 +1,5 @@
1
1
  id: deepflow-suite
2
- version: 0.2.3
2
+ version: 0.2.4
3
3
  kind: composite-skill
4
4
  requires:
5
5
  skills:
@@ -75,11 +75,12 @@ AGENTRT_ADDR=https://deepflowagentruntime.dev.deepwisdomai.com agentrt session l
75
75
  - `repo add` / `repo checkout` 检出的仓库,落在**你当前工作目录的同级**,不在里面。
76
76
  - 目录名取自 URL 的最后一段,**不一定等于应用名**。不要猜,用命令打印出来的绝对路径。
77
77
 
78
- ## release 之后工作目录会被回收
78
+ ## release 之后工作目录的生命周期
79
79
 
80
- 会话 release 之后:消息流仍然可读,**工作目录会被删掉**。
80
+ 当前 Runtime 部署中,会话 release 之后消息流仍然可读,且 Worker workspace 会继续保留;
81
+ release 只停止新轮次。归档、对象存储和本地清理属于后续生命周期能力,不能假设已经完成。
81
82
 
82
- 所以**不要把唯一的产出留在磁盘上**。重要的结论、生成的内容、分析结果,都要进消息流。
83
+ 所以**不要把唯一的交付结论留在磁盘上**。重要的结论、生成的内容、分析结果,都要进消息流。
83
84
  磁盘是工作区,不是交付区。
84
85
 
85
86
  ## 取消是协作式的
@@ -169,7 +170,8 @@ key 时每次新建。同 key 只保留首次成功写入的配置,released
169
170
  ### 有三件事不归你做
170
171
 
171
172
  `session release`、`session rm`、`ops orphans --fix` **不要用**。它们都是替别人做决定:
172
- release 会停止会话接收新轮次(第一期不会归档 Worker 工作目录),删会话会抹掉永久可见的消息流,判死滞留轮次动的是别的会话。
173
+ release 会停止会话接收新轮次并改变生命周期状态(当前不会归档或清理 Worker 工作目录),
174
+ 删会话会抹掉永久可见的消息流,判死滞留轮次动的是别的会话。
173
175
  二进制不会拦你——它会照做,所以这条只能靠你守住。
174
176
 
175
177
  发现某个会话像是卡住了、或者某个工作目录该回收了,**在回复里说出来**,
@@ -145,15 +145,17 @@ Task ID 操作,不支持 metadata 过滤参数;事实服务不会根据 meta
145
145
 
146
146
  | 命令 | 落成哪条事实 | 什么时候写 |
147
147
  | --- | --- | --- |
148
- | `df-task dispatch <task-id> --agent <name> --instruction <text>` | `dispatch_intent`(`mode` 为 `new_run`) | 把一块工作派给某个智能体,开一个新 Run |
149
- | `df-task dispatch <task-id> --agent <name> --instruction <text> --run <run-id>` | `dispatch_intent`(`mode` 为 `message`) | 往一个还活着的 Run 投一条消息 |
150
- | `df-task wait <task-id> --on <what> --reason <text>` | `waiting_reason` | 该派的都派了,在等人回话或等一条外部结果 |
148
+ | `df-task dispatch <task-id> --agent <name> --instruction <text>` | `dispatch_intent`(`mode` 为 `new_run`,不带 `target_run_id`) | 把一块工作派给某个智能体,Driver 会派生一个新逻辑 Run |
149
+ | `df-task dispatch <task-id> --agent <name> --instruction <text> --run <run-id>` | `dispatch_intent`(`mode` 为 `message`,带 `target_run_id`) | 往一个已有逻辑 Run 投一条消息 |
150
+ | `df-task wait <task-id> --on <what> --reason <text> [--waiting-run <run-id>]` | `waiting_reason` | 该派的都派了,在等人回话或等一条外部结果 |
151
151
  | `df-task handoff <task-id> --ask <text>` | `handoff_to_human` | 把球交给人。既用于「都做完了请验收」,也用于「这一步我做不了请你做」 |
152
152
  | `df-task append <task-id> --type adjudication --file p.json` | `adjudication` | 对某条事实下裁决,`subject` 是那条事实的序号 |
153
153
  | `df-task append <task-id> --type run_terminated --file p.json` | `run_terminated` | **已经用 `df-agentrt` 停完 Run 之后**,记录这个既成事实 |
154
154
 
155
155
  前四行是语法糖,落库的事实类型见中间那一列 —— 读日志时你看到的是 `dispatch_intent`,不是 `dispatch`。各列字段清单见 `references/fact-types.md`。
156
156
 
157
+ **先看人话的 `wake_policy`。** 带 `wake_policy: passive` 的人话是同事之间的讨论,不是给你的指令:可以用来理解上下文,但不能因为它去 `dispatch`。passive 消息不算本轮要处理的请求;处理完其他事实后如果没有要做的事,就写 `wait`,说明正在等待有人点名。
158
+
157
159
  **每一轮至少写一条。** 一轮调度什么都不写,这个 Task 就会静默停住 —— 那是最坏的失效模式。无事可做不是理由:无事可做就写 `wait` 或 `handoff`。
158
160
 
159
161
  `dispatch` 写完不等于 Run 起来了。**你写完就该结束**,真正拉起进程的是推进器。
@@ -175,3 +177,5 @@ Task ID 操作,不支持 metadata 过滤参数;事实服务不会根据 meta
175
177
  追加成功返回那条事实,含它的 `seq`。`--idempotency-key` 重复提交同一个键时返回**已存在的那条事实**,HTTP 状态是 `200` 而不是 `201` —— 这不是错误,重试是安全的。
176
178
 
177
179
  各类事实的字段清单见 `references/fact-types.md`,可直接抄改的 payload 样例在 `assets/payload-examples/`。
180
+
181
+ 等待已发起的工作 Run 时,使用 `--waiting-run` 填写 `invocation_started.payload.run_id` 的精确值;不要使用 dispatch 的 `target_run_id`,不要附加角色或 Session 描述。`--on` 仍是自由描述,`--reason` 保留调度依据。需要人采取行动时使用 `handoff`。此关联不改变 Driver 推进语义。
@@ -6,9 +6,11 @@
6
6
 
7
7
  | 类型 | 谁写 | 必填 | 可选 |
8
8
  | --- | --- | --- | --- |
9
- | `user_message` | 人 | `text` | —— |
9
+ | `user_message` | 人 | `text` | `wake_policy`、`agent_ids` |
10
10
  | `external_result` | 外部系统 | `source`、`ref`、`result` | —— |
11
11
 
12
+ `wake_policy` 由产品端写入,缺失时按 `default` 处理。`passive` 表示多人对话里人和人之间的讨论,它**不触发**调度,被别的事件唤醒时也只能当作上下文,不能单独据此派活。`agent_ids` 只是人提到的 Agent,作为提示;派给谁仍由调度根据全局事实决定。
13
+
12
14
  对求助的回答、对产物的意见、对裁决的确认,全都是 `user_message`,没有专门的类型。
13
15
 
14
16
  ## 人工任务管理(不触发调度)
@@ -28,8 +30,8 @@
28
30
 
29
31
  | 类型 | 必填 | 可选 | 说明 |
30
32
  | --- | --- | --- | --- |
31
- | `dispatch_intent` | `target_run_id`、`agent`、`instruction`、`mode` | —— | `mode` 是 `new_run` 或 `message`。用 `df-task dispatch` 更省事,它会替你填这四个字段 |
32
- | `waiting_reason` | `waiting_on`、`reason` | —— | 给人和给下一轮调度的上下文,**不是推进器的门** |
33
+ | `dispatch_intent` | `agent`、`instruction`、`mode`;`mode=message` 时还必须有 `target_run_id` | —— | `new_run` 不带 `target_run_id`,由 Driver 根据 `task_id + intent_seq` 派生逻辑 Run;`message` 只能指向已有逻辑 Run。用 `df-task dispatch` 更省事 |
34
+ | `waiting_reason` | `waiting_on`、`reason` | `waiting_run_id`(实际执行 ID) | 给人和给下一轮调度的上下文,**不是推进器的门** |
33
35
  | `handoff_to_human` | `ask` | `assignee` | 交球和派活是同一条事实,区别只在 `ask` 的内容 |
34
36
  | `adjudication` | `subject`、`verdict` | `reason` | `subject` 是被裁决那条事实的**序号**(数字,不是字符串) |
35
37
  | `run_terminated` | `run_id`、`confirmed_status` | —— | 已经停完并确认之后记录的既成事实 |
@@ -49,8 +49,18 @@ df-workbench task send <task-id> --message '补充检查 Safari 浏览器' --jso
49
49
  ```bash
50
50
  df-workbench task get <task-id> --json
51
51
  df-workbench task facts <task-id> --json
52
+ df-workbench task list [--scope <mine|workspace>] [--limit <n>] --json
52
53
  ```
53
54
 
55
+ `task list` 默认读取当前用户可以参与的任务;需要发现工作区内的其他任务时使用
56
+ `--scope workspace`。未参与的任务只提供安全概览,可能带有 `access: "overview"` 和
57
+ `overviewState`,不会暴露目标正文、讨论、成员或成果内容。
58
+
59
+ 只有任务所有者或已获批准的参与者才能读取完整事实、发送消息和读取成果。对未获准
60
+ 参与的任务,`task facts` 或 `task send` 会返回 `task_participation_required`(HTTP 403)。
61
+ 此时应引导用户在 Workbench 界面申请加入并等待负责人批准,而不是重试或把它当成
62
+ Token、工作区或服务地址配置错误。
63
+
54
64
  创建和发送必须使用稳定的 `--idempotency-key`。如果请求超时或返回未知结果,不要换一个 key 盲目重试;沿用原 key 核对结果。
55
65
 
56
66
  ## 用户反馈边界
package/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "distribution": "deepflow-suite",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "skills": [
5
5
  {
6
6
  "name": "deepflow-suite",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metagptx/deepflow-suite-cli",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Agent-friendly installer and distribution CLI for the DeepFlow suite.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -26,11 +26,11 @@
26
26
  "access": "public"
27
27
  },
28
28
  "optionalDependencies": {
29
- "@metagptx/deepflow-suite-cli-darwin-arm64": "0.2.3",
30
- "@metagptx/deepflow-suite-cli-darwin-x64": "0.2.3",
31
- "@metagptx/deepflow-suite-cli-linux-arm64": "0.2.3",
32
- "@metagptx/deepflow-suite-cli-linux-x64": "0.2.3",
33
- "@metagptx/deepflow-suite-cli-win32-x64": "0.2.3"
29
+ "@metagptx/deepflow-suite-cli-darwin-arm64": "0.2.4",
30
+ "@metagptx/deepflow-suite-cli-darwin-x64": "0.2.4",
31
+ "@metagptx/deepflow-suite-cli-linux-arm64": "0.2.4",
32
+ "@metagptx/deepflow-suite-cli-linux-x64": "0.2.4",
33
+ "@metagptx/deepflow-suite-cli-win32-x64": "0.2.4"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=22.13.0"
@@ -43,6 +43,7 @@ export function parseArgs(argv, env = process.env) {
43
43
  title: "",
44
44
  after: "",
45
45
  limit: "",
46
+ scope: "mine",
46
47
  };
47
48
  const positionals = [];
48
49
  for (let index = 0; index < argv.length; index += 1) {
@@ -67,6 +68,7 @@ export function parseArgs(argv, env = process.env) {
67
68
  "--title",
68
69
  "--after",
69
70
  "--limit",
71
+ "--scope",
70
72
  ].includes(name)
71
73
  ) {
72
74
  const parsed =
@@ -79,6 +81,7 @@ export function parseArgs(argv, env = process.env) {
79
81
  if (name === "--title") options.title = parsed;
80
82
  if (name === "--after") options.after = parsed;
81
83
  if (name === "--limit") options.limit = parsed;
84
+ if (name === "--scope") options.scope = parsed;
82
85
  continue;
83
86
  }
84
87
  if (argument.startsWith("--"))
@@ -264,11 +267,25 @@ function taskSummary(value) {
264
267
  `Task: ${task.id || "未知"}`,
265
268
  task.title ? `标题: ${task.title}` : "",
266
269
  task.workspaceId ? `工作区: ${task.workspaceId}` : "",
270
+ task.access === "overview"
271
+ ? "访问: 仅概览(请先申请加入并等待批准后读取完整内容)"
272
+ : "",
273
+ task.overviewState?.status ? `状态: ${task.overviewState.status}` : "",
267
274
  ]
268
275
  .filter(Boolean)
269
276
  .join("\n");
270
277
  }
271
278
 
279
+ export function requestFailureHint(error) {
280
+ if (error?.code === "task_participation_required")
281
+ return "当前任务仅可查看概览;请先在 Workbench 中申请加入并等待批准。";
282
+ if (error?.code === "task_access_denied")
283
+ return "当前身份没有读取任务内容的权限,请先确认任务参与资格。";
284
+ if (error?.status === 401 || error?.status === 403)
285
+ return "请检查 DF_WORKBENCH_TOKEN、工作区和目标环境配置。";
286
+ return "";
287
+ }
288
+
272
289
  function factsSummary(value) {
273
290
  const facts = Array.isArray(value.facts) ? value.facts : [];
274
291
  const lines = [`事实数量: ${facts.length}`];
@@ -293,7 +310,7 @@ function help() {
293
310
  df-workbench task send <task-id> --message <消息> [--idempotency-key <key>]
294
311
  df-workbench task get <task-id> [--json]
295
312
  df-workbench task facts <task-id> [--after <seq>] [--limit <n>] [--json]
296
- df-workbench task list [--limit <n>] [--json]
313
+ df-workbench task list [--scope <mine|workspace>] [--limit <n>] [--json]
297
314
 
298
315
  全局配置:
299
316
  DF_WORKBENCH_BASE_URL Workbench 根地址,默认 http://127.0.0.1:8793
@@ -410,10 +427,16 @@ async function run(options) {
410
427
  }
411
428
  if (subject === "list") {
412
429
  const context = await currentContext(options);
430
+ if (!["mine", "workspace"].includes(options.scope))
431
+ throw new UsageError("--scope 必须是 mine 或 workspace。");
413
432
  const limit = integerOption(options.limit, "--limit", 50, 1, 200);
414
433
  const value = await request(
415
434
  options,
416
- `/api/v1/tasks?scope=mine&limit=${limit}`,
435
+ `/api/v1/tasks?${new URLSearchParams({
436
+ scope: options.scope,
437
+ limit: String(limit),
438
+ include_state: "1",
439
+ })}`,
417
440
  {},
418
441
  context,
419
442
  );
@@ -422,7 +445,9 @@ async function run(options) {
422
445
  options,
423
446
  (value) =>
424
447
  (value.tasks || [])
425
- .map((task) => `${task.id} ${task.title || ""}`.trim())
448
+ .map((task) =>
449
+ `${task.id} ${task.title || ""}${task.access === "overview" ? "(仅概览)" : ""}`.trim(),
450
+ )
426
451
  .join("\n") || "没有任务。",
427
452
  );
428
453
  return;
@@ -449,10 +474,8 @@ if (
449
474
  ? ` [${error.code}]`
450
475
  : "";
451
476
  process.stderr.write(`请求失败${suffix}:${error.message}\n`);
452
- if (error.details?.status === 401 || error.details?.status === 403)
453
- process.stderr.write(
454
- "请检查 DF_WORKBENCH_TOKEN、工作区和目标环境配置。\n",
455
- );
477
+ const hint = requestFailureHint(error);
478
+ if (hint) process.stderr.write(`${hint}\n`);
456
479
  } else {
457
480
  process.stderr.write(
458
481
  `失败:${error instanceof Error ? error.message : String(error)}\n`,
@@ -1,5 +1,5 @@
1
1
  id: deepflow-suite
2
- version: 0.2.3
2
+ version: 0.2.4
3
3
  kind: composite-skill
4
4
  requires:
5
5
  skills: