@wubaoqi/guancopilot 0.0.0-stage → 0.2.0
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/NOTICE.md +17 -0
- package/README.md +146 -2
- package/assets/coreutils.wasm +0 -0
- package/assets/find.wasm +0 -0
- package/assets/guanbi.wasm +4 -0
- package/assets/guancli.wasm +0 -0
- package/assets/guanhelm.wasm +0 -0
- package/assets/jq.wasm +0 -0
- package/assets/openskills.wasm +0 -0
- package/assets/rg.wasm +0 -0
- package/assets/sed.wasm +0 -0
- package/bin/guancopilot +0 -0
- package/bin/guanvm +0 -0
- package/bin/platforms.cjs +6 -0
- package/bin/run.cjs +39 -0
- package/bin/runtime.cjs +44 -0
- package/licenses/Go-LICENSE +27 -0
- package/licenses/browser-_speed-highlight_core-LICENSE +121 -0
- package/licenses/browser-_speed-highlight_core-package.json +14 -0
- package/licenses/browser-dompurify-LICENSE +202 -0
- package/licenses/browser-dompurify-LICENSE-MPL +373 -0
- package/licenses/browser-dompurify-package.json +10 -0
- package/licenses/browser-marked-LICENSE +44 -0
- package/licenses/browser-marked-package.json +10 -0
- package/licenses/coreutils-LICENSE +18 -0
- package/licenses/findutils-LICENSE +18 -0
- package/licenses/github.com_BurntSushi_toml_v1.6.0-COPYING +21 -0
- package/licenses/github.com_dustin_go-humanize_v1.0.1-LICENSE +21 -0
- package/licenses/github.com_google_jsonschema-go_v0.4.3-LICENSE +21 -0
- package/licenses/github.com_google_uuid_v1.6.0-LICENSE +27 -0
- package/licenses/github.com_jackc_pgpassfile_v1.0.0-LICENSE +22 -0
- package/licenses/github.com_jackc_pgservicefile_v0.0.0-20240606120523-5a60cdf6a761-LICENSE +22 -0
- package/licenses/github.com_jackc_pgx_v5_v5.11.0-LICENSE +22 -0
- package/licenses/github.com_jackc_puddle_v2_v2.2.2-LICENSE +22 -0
- package/licenses/github.com_mattn_go-isatty_v0.0.20-LICENSE +9 -0
- package/licenses/github.com_modelcontextprotocol_go-sdk_v1.8.0-LICENSE +216 -0
- package/licenses/github.com_ncruces_go-strftime_v1.0.0-LICENSE +21 -0
- package/licenses/github.com_remyoudompheng_bigfft_v0.0.0-20230129092748-24d4a6f8daec-LICENSE +27 -0
- package/licenses/github.com_santhosh-tekuri_jsonschema_v6_v6.0.3-LICENSE +175 -0
- package/licenses/github.com_segmentio_asm_v1.1.3-LICENSE +21 -0
- package/licenses/github.com_segmentio_encoding_v0.5.4-LICENSE +21 -0
- package/licenses/github.com_tetratelabs_wazero_v1.12.0-LICENSE +201 -0
- package/licenses/github.com_tetratelabs_wazero_v1.12.0-NOTICE +2 -0
- package/licenses/github.com_yosida95_uritemplate_v3_v3.0.2-LICENSE +25 -0
- package/licenses/golang.org_x_image_v0.44.0-LICENSE +27 -0
- package/licenses/golang.org_x_net_v0.58.0-LICENSE +27 -0
- package/licenses/golang.org_x_oauth2_v0.36.0-LICENSE +27 -0
- package/licenses/golang.org_x_sync_v0.22.0-LICENSE +27 -0
- package/licenses/golang.org_x_sys_v0.47.0-LICENSE +27 -0
- package/licenses/golang.org_x_text_v0.41.0-LICENSE +27 -0
- package/licenses/golang.org_x_time_v0.15.0-LICENSE +27 -0
- package/licenses/guanbi-skills-LICENSE +133 -0
- package/licenses/guanbi-skills-LICENSE.README.md +28 -0
- package/licenses/guanbi-skills-LICENSE.zh-CN +82 -0
- package/licenses/jq-COPYING +176 -0
- package/licenses/modernc.org_libc_v1.73.4-LICENSE +27 -0
- package/licenses/modernc.org_libc_v1.73.4-LICENSE-3RD-PARTY.md +305 -0
- package/licenses/modernc.org_mathutil_v1.7.1-LICENSE +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-GO +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-LOGO +1 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-MMAP-GO +25 -0
- package/licenses/modernc.org_sqlite_v1.53.0-LICENSE +26 -0
- package/licenses/mvdan.cc_sh_v3_v3.13.1-LICENSE +27 -0
- package/licenses/ripgrep-COPYING +3 -0
- package/licenses/ripgrep-LICENSE-MIT +21 -0
- package/licenses/sed-LICENSE +21 -0
- package/manifest.json +972 -0
- package/package.json +30 -4
- package/plugin/guancopilot.js +193 -0
- package/skills-bundle/.guanvm-skills-bundle +0 -0
- package/skills-bundle/_recipes/dashboard/gates/page_check.js +16 -0
- package/skills-bundle/_recipes/dashboard/gates/report_check.js +4 -0
- package/skills-bundle/_recipes/dashboard/knowledge/01.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/02.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/03.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/04.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/05.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/06.md +1 -0
- package/skills-bundle/_recipes/dashboard/template.json +41 -0
- package/skills-bundle/_recipes/etl/gates/etl_live_check.js +10 -0
- package/skills-bundle/_recipes/etl/gates/etl_report_check.js +3 -0
- package/skills-bundle/_recipes/etl/knowledge/01.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/02.md +9 -0
- package/skills-bundle/_recipes/etl/knowledge/03.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/04.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/05.md +1 -0
- package/skills-bundle/_recipes/etl/template.json +39 -0
- package/skills-bundle/_recipes/hints.json +46 -0
- package/skills-bundle/guancli/.commandface.json +155 -0
- package/skills-bundle/guancli/SKILL.md +342 -0
- package/skills-bundle/guancli/evals/evals.json +156 -0
- package/skills-bundle/guancli/evals/fixtures/metric-candidate-empty-search.json +13 -0
- package/skills-bundle/guancli/evals/fixtures/metric-candidate-prior-request.json +13 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-columns.json +46 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-metadata.json +36 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-query.json +18 -0
- package/skills-bundle/guancli/references/analysis-primitives.md +95 -0
- package/skills-bundle/guancli/references/auth-and-config.md +131 -0
- package/skills-bundle/guancli/references/examples/metric-date-in.json +7 -0
- package/skills-bundle/guancli/references/examples/metric-query-rows.py +83 -0
- package/skills-bundle/guancli/references/examples/metric-query.sh +6 -0
- package/skills-bundle/guancli/references/form-chatbi.md +199 -0
- package/skills-bundle/guancli/references/gateway.md +148 -0
- package/skills-bundle/guancli/references/metric-batch-query.md +82 -0
- package/skills-bundle/guancli/references/metric-commands.md +562 -0
- package/skills-bundle/guancli/references/metric-generic-query.md +215 -0
- package/skills-bundle/guancli/references/metric-json-migration.md +18 -0
- package/skills-bundle/guancli/references/metric-query-recipes.md +358 -0
- package/skills-bundle/guancli/references/preview-and-output.md +192 -0
- package/skills-bundle/guancli/references/resource-query.md +101 -0
- package/skills-bundle/guands/SKILL.md +281 -0
- package/skills-bundle/guands/references/calc-fields-boundaries-and-pitfalls.md +160 -0
- package/skills-bundle/guands/references/command-reference.md +267 -0
- package/skills-bundle/guands/references/incremental-and-schedule.md +157 -0
- package/skills-bundle/guands/references/workflows.md +256 -0
- package/skills-bundle/guanetl/SKILL.md +391 -0
- package/skills-bundle/guanetl/evals/evals.json +41 -0
- package/skills-bundle/guanetl/references/ETL_AI_DEVELOP.md +456 -0
- package/skills-bundle/guanmetric/SKILL.md +144 -0
- package/skills-bundle/guanmetric/evals/evals.json +117 -0
- package/skills-bundle/guanmetric/evals/fixtures/atomic-detail-read-model.json +18 -0
- package/skills-bundle/guanmetric/evals/fixtures/confirmed-template-summary.json +12 -0
- package/skills-bundle/guanmetric/evals/fixtures/create-result-unknown-state.json +13 -0
- package/skills-bundle/guanmetric/evals/forward-eval-2026-09-21.json +62 -0
- package/skills-bundle/guanmetric/references/metric-api-contract-examples.json +690 -0
- package/skills-bundle/guanmetric/references/metric-api-contract.schema.json +349 -0
- package/skills-bundle/guanmetric/references/metric-api-contracts.md +436 -0
- package/skills-bundle/guanmetric/references/metric-atomic-mutation.md +238 -0
- package/skills-bundle/guanmetric/references/metric-batch-status.md +71 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract-examples.json +53 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract.schema.json +26 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary.md +76 -0
- package/skills-bundle/guanmetric/references/metric-common-fields.md +246 -0
- package/skills-bundle/guanmetric/references/metric-composite-mutation.md +165 -0
- package/skills-bundle/guanmetric/references/metric-delete-mutation.md +70 -0
- package/skills-bundle/guanmetric/references/metric-derived-mutation.md +453 -0
- package/skills-bundle/guanmetric/references/metric-excel-template.md +365 -0
- package/skills-bundle/guanmetric/references/metric-expression-rules.md +146 -0
- package/skills-bundle/guanmetric/references/metric-flow-generate-example.json +79 -0
- package/skills-bundle/guanmetric/references/metric-flow-generate.schema.json +93 -0
- package/skills-bundle/guanmetric/references/metric-flow.md +218 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract-examples.json +171 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract.schema.json +167 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contracts.md +193 -0
- package/skills-bundle/guanmetric/references/metric-mutation.md +155 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract-examples.json +62 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract.schema.json +47 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension.md +155 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contract-examples.json +277 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contract.schema.json +263 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contracts.md +53 -0
- package/skills-bundle/guanmetric/references/metric-tree-mutation.md +500 -0
- package/skills-bundle/guanmetric/references/metric-validation-ownership.md +74 -0
- package/skills-bundle/guanvis/SKILL.md +333 -0
- package/skills-bundle/guanvis/evals/china_map/card_01_basic_map.js +13 -0
- package/skills-bundle/guanvis/evals/china_map/card_02_world_map.js +10 -0
- package/skills-bundle/guanvis/evals/china_map/card_03_point_map.js +12 -0
- package/skills-bundle/guanvis/evals/china_map/page.js +10 -0
- package/skills-bundle/guanvis/evals/china_map/schema.js +10 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/README.md +30 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/card_01_comparative_mvp.js +72 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/verify_default_roundtrip.sh +92 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/card_01_monthly.js +63 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/page.js +6 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/schema.js +6 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/card_01_bar.js +13 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/card_02_pie.js +13 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/bar.js +11 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/pie.js +15 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/page.js +5 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/schema.js +9 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/card_01_level_nodes.js +19 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.css +51 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.html +1 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.js +28 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/page.js +5 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/schema.js +7 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/card_01_dynamic_dataset.js +20 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/card_02_dynamic_metric_chart.js +16 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/metrics.js +19 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/page.js +9 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/schema.js +7 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/verify_default_roundtrip.sh +137 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/README.md +26 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_01_percentage_advcalc.js +44 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_02_scroll_percentage.js +12 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/README.md +28 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/card_01_rank_advcalc.js +59 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/verify_default_roundtrip.sh +135 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/README.md +15 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/card_01_running_total_advcalc.js +74 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_01_revenue_column.js +10 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_02_trend_line.js +9 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_03_kpi.js +6 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_04_pie.js +9 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_05_calc_field_test.js +12 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/page.js +11 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/schema.js +14 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/selector_01_region.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_01_column_split.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_02_line_split.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_03_combo_split.js +11 -0
- package/skills-bundle/guanvis/evals/split_charts/page.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/schema.js +14 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_00_total_revenue.js +6 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_01_revenue.js +10 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_02_trend.js +9 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_03_story.js +11 -0
- package/skills-bundle/guanvis/evals/tab_layout/page.js +23 -0
- package/skills-bundle/guanvis/evals/tab_layout/schema.js +11 -0
- package/skills-bundle/guanvis/evals/tab_layout/selector_01_region.js +8 -0
- package/skills-bundle/guanvis/references/api-reference.md +476 -0
- package/skills-bundle/guanvis/references/builder-reference.md +1676 -0
- package/skills-bundle/guanvis/references/chart-properties.md +2101 -0
- package/skills-bundle/guanvis/references/checkout-editing.md +53 -0
- package/skills-bundle/guanvis/references/complex-report-pro-patterns.md +398 -0
- package/skills-bundle/guanvis/references/dir-and-page-management.md +48 -0
- package/skills-bundle/guanvis/references/metric-chart-reference.md +258 -0
- package/skills-bundle/guanvis/references/publish-and-constraints.md +60 -0
- package/skills-bundle/guanvis/references/selector-reference.md +431 -0
- package/skills-bundle/guanvis/references/tableau-migration.md +73 -0
- package/skills-bundle/guanvis/references/theme.md +123 -0
- package/skills-bundle/guanvis/references/troubleshooting.md +25 -0
- package/skills-bundle/guanvis/references/validation-and-chart-patterns.md +205 -0
- package/skills-bundle/guanwf/SKILL.md +543 -0
- package/skills-bundle/guanwf/references/ETL_AI_DEVELOP.md +456 -0
- package/skills-bundle/guanwf/references/TASK_NODE_CONTRACTS.md +64 -0
- package/skills-bundle/guanwf/references/WORKFLOW_DSL.md +536 -0
- package/skills-bundle/guanwf/references/WORKFLOW_NODES.md +166 -0
- package/skills-bundle/js/SKILL.md +145 -0
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: guanwf
|
|
3
|
+
description: 当用户要创建、编辑、保存工作流引擎中的工作流(含数据流节点、Python 节点、子工作流编排、参数赋值等多节点 DAG),或需要预览数据流节点、校验/试运行 Python 脚本、运行工作流、配置定时调度、从失败处恢复续跑,或需要查询工作流/数据流列表和详情时使用。也适用于把一批已有作业工作流按依赖串成统一调度的主工作流(编排):从血缘自动推导依赖生成编排(deps plan)、对账编排依赖与血缘是否一致(deps verify)、配置 cron 调度上下线(schedule)、失败后增量恢复(run --recover)。数据流是 BI ETL 的扩展,运行在独立的工作流引擎中。适用于用户说"创建一个数据流""创建一个带 Python 节点的工作流""编辑这个工作流""保存数据流""预览数据流节点""运行工作流""验证这个 Python 脚本能不能跑""列出所有数据流""查看这个工作流的定义""把这批作业串起来统一调度""按血缘生成调度依赖""给工作流配个每天凌晨的调度""调度先下线""编排里有作业挂了修好后接着跑"等场景。
|
|
4
|
+
compatibility: "Requires Node.js 14+. Install via npm link --foreground-scripts (local) or npm install -g --foreground-scripts @guandata/guanwf (from internal Nexus registry) so the AI skill refresh result is visible. CLI command: guanwf."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# guanwf
|
|
8
|
+
|
|
9
|
+
工作流引擎工作流(ProcessDefinition)的编辑闭环工具。一个工作流是一个节点 DAG,
|
|
10
|
+
节点可以是数据流(Dataflow)、Python 脚本、参数赋值等类型。
|
|
11
|
+
|
|
12
|
+
这是一个执行型 skill,不是只读分析 skill。
|
|
13
|
+
|
|
14
|
+
- `guancli workflow` 负责通用工作流、数据流、目录和线上结构查询;v0.1.820(8.2.0 兼容线)实例诊断使用
|
|
15
|
+
`guanwf instance list/tasks/logs/latest`,可直接解析 `--dir` 工作区。
|
|
16
|
+
- `guanwf` 负责把目标工作流拉到本地工作目录,修改事实源,再完成 `export -> preview/validate -> save-draft/save -> run`。
|
|
17
|
+
|
|
18
|
+
## 核心概念
|
|
19
|
+
|
|
20
|
+
- **工作流 (Workflow / PROCESS)**: 顶层容器,包含任务节点 DAG
|
|
21
|
+
- **数据流 (Dataflow / DATAFLOW)**: 嵌入在工作流中的 ETL 流程,actions 结构与 BI ETL 相同
|
|
22
|
+
- **数据库数据流 (DB_DATAFLOW)**: 数据流的变体,支持 SQL 下推
|
|
23
|
+
- **Python 节点 (SECURE_PYTHON)**: 工作流级 Python 任务,沙箱内运行脚本,可读输入数据集并创建输出数据集
|
|
24
|
+
- **子工作流节点 (SUB_PROCESS + PROCESS)**: 引用另一个已存在的工作流作为节点,用于把一批作业编排成统一调度的主工作流
|
|
25
|
+
- **节点依赖**: 节点间用 `After`(成功后)/ `AfterFailure`(失败后)/ `AfterAny`(完成后)声明执行顺序
|
|
26
|
+
- **工作流参数**: `Workflow.Params` 声明,使用 `ParamRef` / `DynamicParamRef` / `DataDrivenParamRef` 引用
|
|
27
|
+
- **结构化任务节点**: DATASET、HTTP、SQL、PARAMETER_ASSIGNMENT、SWITCH 均有 8.2.0 可执行的强类型 DSL,未知字段由 `task.json` 保留;SHELL/LOOP 仅保留导入模型,8.2.0 不可创建、导出、保存或运行
|
|
28
|
+
|
|
29
|
+
### 8.2.0 兼容边界
|
|
30
|
+
|
|
31
|
+
- 8.2.0 后端没有注册 `SHELL`、`LOOP` TaskParameters,CLI 会在脚手架、导出、保存前明确拒绝。
|
|
32
|
+
- `DatasetNode` 可刷新数据库抽取/直连数据集;不能刷新 `DATA_SET_OFFLINE_DEV`,该路径在 8.2.0 会把 BI 文本响应误当 JSON。需要更新离线开发产出时,使用 `SubWorkflowNode` 调用产出工作流。
|
|
33
|
+
- `ParameterAssignmentNode` 的 `DATASET` 来源不能选数据库直连数据集(BI 返回 60006);三张 StarRocks 表应使用 `DataSourceType: "DATABASE"` 和数据账户。抽取/产出数据集可使用 `DATASET` 来源及 `input1` 查询。
|
|
34
|
+
|
|
35
|
+
## 关键不变式
|
|
36
|
+
|
|
37
|
+
**保存工作流时,必须携带完整的工作流上下文(所有 tasks + 所有 dataflowJson)。**
|
|
38
|
+
`guanwf save` 内部会以服务端最新版本为基底做字段级合并,AI 不需要也不应该手拼保存 payload。
|
|
39
|
+
|
|
40
|
+
**编辑 ≠ 删除重建。** 编辑已有工作流永远走 `edit → export → save` 原地保存(保留 workflowId),
|
|
41
|
+
改名直接修改 `workflow.go` 中 `Workflow.Name` 后正常 save。guanwf 没有提供工作流删除命令;
|
|
42
|
+
用户要求删除时直接说明 CLI 暂不支持。**禁止**用"新建一个工作流替代旧工作流"来模拟编辑或
|
|
43
|
+
改名——workflowId 变化会丢失定时/事件调度配置、权限与协作者设置、运行实例历史,且所有通过
|
|
44
|
+
`SubWorkflowNode` 引用它的编排工作流会断链。只有用户明确指示"新建替代、再废弃旧的"时才允许,
|
|
45
|
+
且执行前必须列出上述影响并获得确认。
|
|
46
|
+
|
|
47
|
+
## Harness 工作法:源文件驱动,不手写最终 JSON
|
|
48
|
+
|
|
49
|
+
先改可读、可复现的源文件,再用明确命令重新生成派生产物。不要为了让保存请求看起来正确而直接改最终 JSON。
|
|
50
|
+
|
|
51
|
+
**如果任务是生成或修改工作流,但本轮没有修改下面任一事实源,不要汇报完成,也不要直接 save:**
|
|
52
|
+
|
|
53
|
+
- `workflow.go`(工作流结构:节点 + 依赖)
|
|
54
|
+
- `nodes/<节点ID>/etl.go`、`nodes/<节点ID>/*.sql`(数据流节点)
|
|
55
|
+
- `nodes/<节点ID>/script.py`(Python 节点脚本)
|
|
56
|
+
- `nodes/<节点ID>/task.json`(RAW 透传节点)
|
|
57
|
+
- `nodes/<节点ID>/node_*.json`(被 etl.go 里 `LoadNodeFromFile(...)` 引用的透传节点)
|
|
58
|
+
|
|
59
|
+
查询、预览、运行、排查已有导出结果时可以不修改源文件;但只要目标是"生成/调整工作流逻辑",最终变更必须落在上述事实源中。
|
|
60
|
+
|
|
61
|
+
### 工作目录结构(Artifact contract)
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
<workdir>/
|
|
65
|
+
workflow.go # 可编辑事实源;含凭据时 export 自动收紧为 0600/当前用户 ACL 并加入 .gitignore
|
|
66
|
+
nodes/<节点ID>/
|
|
67
|
+
etl.go # 可编辑事实源:DATAFLOW/DB_DATAFLOW 节点(guanetl DSL)
|
|
68
|
+
*.sql # 可编辑事实源:SQL 节点外置文件(ReadSQLFile 引用)
|
|
69
|
+
node_*.json # 可编辑事实源:LoadNodeFromFile 透传节点配置
|
|
70
|
+
script.py # 可编辑事实源:PYTHON 节点脚本正文
|
|
71
|
+
python.json # 服务端字段透传(edit 生成,勿手改;改配置去 workflow.go 的 PythonConfig)
|
|
72
|
+
task.json # 0600/当前用户 ACL;RAW 节点为完整事实源,结构化节点保留未知字段
|
|
73
|
+
script.sh # SHELL 节点脚本
|
|
74
|
+
query.sql # SQL / PARAMETER_ASSIGNMENT 节点 SQL
|
|
75
|
+
body.json/body.txt # HTTP 请求体
|
|
76
|
+
_input.json / meta.json # 导入快照/派生产物,不手改
|
|
77
|
+
_layout.json # 画布坐标(edit 保留线上坐标;新节点自动布局补位)
|
|
78
|
+
_python_runtime_context.json # Python Runtime 结构化上下文(命令生成,只读)
|
|
79
|
+
_wf_state.json # 系统状态,不手改
|
|
80
|
+
_parent_snapshot.json # 脱敏服务端快照,不手改
|
|
81
|
+
_parent_merge_snapshot.json # 受限权限的精确三方合并基线,不手改
|
|
82
|
+
.gitignore # 自动忽略含原始凭据的精确合并基线
|
|
83
|
+
_exported_workflow.json # 派生产物,不手改;由 export 重新生成
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 禁止的偷懒路径
|
|
87
|
+
|
|
88
|
+
- 不要直接编辑 `_exported_workflow.json` 来"修好"预览或保存。
|
|
89
|
+
- 不要直接编辑 `_parent_snapshot.json` 或 `_parent_merge_snapshot.json` 来拼保存 payload。
|
|
90
|
+
- 不要手改 `python.json`;输入/输出/资源配置改 `workflow.go` 的 `PythonConfig`。
|
|
91
|
+
- 不要跳过 `export`,拿上一次的导出结果去 `preview` 或 `save`。
|
|
92
|
+
|
|
93
|
+
如果 `export`、`preview`、`save` 或 `run` 失败,修复顺序固定为:读失败输出 -> 判断是
|
|
94
|
+
`workflow.go`、节点源文件、认证/网络还是线上任务问题 -> 修改最小责任源文件 -> 从失败步骤往后重跑。
|
|
95
|
+
|
|
96
|
+
## 认证
|
|
97
|
+
|
|
98
|
+
复用 guancli 的认证链路:
|
|
99
|
+
```bash
|
|
100
|
+
guancli auth login # 先确保已登录
|
|
101
|
+
guancli auth status # 检查连接状态
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
若由上游托管 OIDC Token,当前进程同时设置 `GUANCLI_OIDC_BASE_URL` 和 `GUANCLI_OIDC_ACCESS_TOKEN` 后直接运行 `guancli auth status`,无需本地 profile,也不执行浏览器登录或自动刷新。
|
|
105
|
+
|
|
106
|
+
## 固定工作方式
|
|
107
|
+
|
|
108
|
+
### 0. 先分场景
|
|
109
|
+
|
|
110
|
+
- `只读查询`: 用 `guancli workflow`,不要创建工作目录。
|
|
111
|
+
- `新建工作流`: `guanwf create --name ... --parent-dir ...`(8.2.0 支持 `--type DATAFLOW/DB_DATAFLOW/PYTHON/HTTP/SQL/ORCHESTRATION`),然后编辑 `workflow.go` 和 `nodes/`。
|
|
112
|
+
- `编辑已有工作流`: `guanwf edit <workflowId>` 导入整个工作流(数据流节点 → etl.go,Python 节点 → script.py)。
|
|
113
|
+
- `编排一批作业`: `guanwf create --type ORCHESTRATION` + `guanwf deps plan` 从血缘自动生成依赖,见「编排工作流」一节。
|
|
114
|
+
- `修复失败`: 先定位失败发生在 `export`、`preview`、`save` 还是 `run`,只修最小责任源文件。
|
|
115
|
+
|
|
116
|
+
### v0.1.820 参数、节点和实例命令
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
guanwf node add http --id http_1 --name "通知下游" --dir <workdir>
|
|
120
|
+
guanwf node add sql --id sql_1 --name "执行SQL" --dir <workdir>
|
|
121
|
+
|
|
122
|
+
guanwf run --dir <workdir> --param biz_date=2026-07-14 --confirm
|
|
123
|
+
guanwf instance list --dir <workdir> --state FAILURE -f json
|
|
124
|
+
guanwf instance tasks <instanceId> --dir <workdir> -f json
|
|
125
|
+
guanwf instance logs <instanceId> --dir <workdir> --node "<节点名>" --full --log-type ALL -f json
|
|
126
|
+
guanwf instance latest --dir <workdir> --logs -f json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`node add` 只生成节点目录和可粘贴 DSL 片段,不自动修改 `workflow.go` AST。节点真实字段、
|
|
130
|
+
参数类型兼容和外置文件约定见 `references/TASK_NODE_CONTRACTS.md`。
|
|
131
|
+
`instance logs --full -f json` 固定返回 `complete/attemptsExpected/attemptsReturned/missingAttempts/fallbackUrl`,
|
|
132
|
+
无法证明重跑/恢复历史完整时明确 `complete=false` 并非零退出;诊断同时返回
|
|
133
|
+
`firstFailure/rootCause/secondaryErrors` 及 task/log evidence refs。实例和任务 ID 全程按不透明字符串
|
|
134
|
+
处理,状态统一输出 canonical `RUNNING_EXECUTION`,后端历史拼写仅保留在 `backendState`。
|
|
135
|
+
|
|
136
|
+
### 1. 缺上下文先查,不要猜
|
|
137
|
+
|
|
138
|
+
查询工作流和数据流定义时使用 `guancli workflow`。工作流/数据流由独立的 workflow 引擎管理。
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
guancli workflow tree # 工作流目录树
|
|
142
|
+
guancli workflow list # 列出工作流 + 内嵌数据流(默认)
|
|
143
|
+
guancli workflow list --show-embedded=false # 只列工作流,不展示内嵌数据流
|
|
144
|
+
guancli workflow list 销售 # 按关键词搜索
|
|
145
|
+
guancli workflow list --page-size 50 # 调整每页条数
|
|
146
|
+
guancli workflow list --parent-dir <dirId> # 指定父目录
|
|
147
|
+
guancli workflow get <processDefinitionId> # 查看工作流详情(含数据流节点详情)
|
|
148
|
+
guancli workflow get <id> --raw # 输出原始 JSON
|
|
149
|
+
guancli workflow get <id> -f json # JSON 格式输出
|
|
150
|
+
guanwf get <id> -f json # 原始定义 + dataflow sidecar 可达性
|
|
151
|
+
guanwf status <id> -f json # 轻量状态 + raw/reachable/orphan 分类
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`workflow tree` 调用 `/api/directory/MASTER_FLOW/authorized-tree` 获取工作流目录树。
|
|
155
|
+
|
|
156
|
+
数据流以 SUB_PROCESS 节点形式内嵌在工作流中(`dataFlowNode=true`),不作为独立记录存在。
|
|
157
|
+
`list` 默认展示内嵌数据流(遍历每个工作流并汇总),使用 `--show-embedded=false` 可关闭。
|
|
158
|
+
顶层 `dataflowJson` 只是 raw sidecar 容器,不能用其 length 判断可执行节点数。只把当前
|
|
159
|
+
SUB_PROCESS task 引用的条目视为 `reachableDataflows`;其余为 `orphanSidecars`,get/edit/status
|
|
160
|
+
会显式列出。保存会原样保留孤儿 sidecar 及未知扩展字段,但不会把它们放入执行拓扑,也不会默认清理。
|
|
161
|
+
|
|
162
|
+
涉及 Python 节点时,在编写或修改 `script.py` **之前**查询目标环境的真实 Runtime:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
guanwf python-runtime --dir <workdir> --format json
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
命令返回默认 Runtime、完整镜像目录和工作区各 Python 节点使用的 `runtimeMode`、`pythonVersion`、
|
|
169
|
+
`pythonVersionSource`、`imageId` 及解析状态,并写入 `<workdir>/_python_runtime_context.json`。`guanwf edit` 检测到
|
|
170
|
+
Python 节点时也会自动获取并返回同一结构化上下文。生成代码时只以其中的
|
|
171
|
+
`pythonRuntime.nodes[].runtime.pythonVersion`(或 `pythonRuntime.selected`)为兼容目标;
|
|
172
|
+
CLI 优先通过 `/api/python-images/list` 读取 `pythonVersion`;旧接口不可用时降级到
|
|
173
|
+
`/api/system-images/list?type=PYTHON` 并解析 `runtimeEnv`。两类结构化版本字段均缺失或无法识别时,
|
|
174
|
+
使用产品兼容契约 Python 3.8,并明确标记
|
|
175
|
+
`pythonVersionSource: "compatibility_fallback"`;**禁止从镜像描述、名称或 URL 推断版本**。
|
|
176
|
+
结构化上下文中的 `imageUrl` 会移除 userinfo、fragment 和敏感 query;落盘文件使用 0600 并自动忽略。
|
|
177
|
+
固定 Runtime 输出 `runtimeMode: "FIXED_RUNTIME"`,配置镜像的动态 Pod 输出 `runtimeMode: "DYNAMIC_POD"`;
|
|
178
|
+
目录接口不可用或镜像/版本字段缺失时仍保守生成 Python 3.8 兼容代码,同时保留 warning 和 fallback 来源。
|
|
179
|
+
Python 3.8 fallback 下禁止直接生成 `zoneinfo`、`dict[str, ...]` / `list[...]`、`X | None` 等
|
|
180
|
+
3.9/3.10+ 写法;分别使用经验证可用的时区依赖、`typing.Dict` / `typing.List`、`typing.Optional`。
|
|
181
|
+
不得用固定 `/tmp/...` 路径在 Python 节点之间交换中间结果:不同节点/并发实例可能运行在不同
|
|
182
|
+
UID、进程或 Pod。跨节点数据必须通过 `save_outputN` + 下游 `load_inputN` 的正式数据集/DAG 传递;
|
|
183
|
+
单节点临时文件使用 `tempfile.TemporaryDirectory()` 并在上下文退出时自动清理。
|
|
184
|
+
|
|
185
|
+
### 2. 真正改文件前先读这些
|
|
186
|
+
|
|
187
|
+
至少先读:
|
|
188
|
+
|
|
189
|
+
- `workflow.go`
|
|
190
|
+
- 目标节点的源文件(`nodes/<节点ID>/etl.go` / `script.py` / `task.json`)
|
|
191
|
+
- `references/WORKFLOW_DSL.md`(workflow.go 写法、PythonConfig、依赖声明)
|
|
192
|
+
- `references/ETL_AI_DEVELOP.md`(数据流节点 etl.go 写法)
|
|
193
|
+
- `references/WORKFLOW_NODES.md`(数据流扩展节点)
|
|
194
|
+
|
|
195
|
+
必要时再读:
|
|
196
|
+
|
|
197
|
+
- `nodes/<节点ID>/_input.json`(只读,排查导入前结构)
|
|
198
|
+
- `_exported_workflow.json`(只读,对比导出结果)
|
|
199
|
+
- `guancli workflow get <workflowId> -f json` 的线上结构
|
|
200
|
+
|
|
201
|
+
### 3. 改完永远按这个顺序
|
|
202
|
+
|
|
203
|
+
1. `guanwf export --dir <workdir>`
|
|
204
|
+
2. 数据流节点要看数据结果时 `guanwf preview --dir <workdir>`;Python 节点要校验时
|
|
205
|
+
`guanwf run --node "<节点名>" --validate --dir <workdir> --dry-run`,确认计划后追加 `--confirm`(需先保存草稿)
|
|
206
|
+
3. 先用 `guanwf save-draft --dir <workdir> --dry-run` 或 `guanwf save --dir <workdir> --dry-run` 查看计划,确认后追加 `--confirm`
|
|
207
|
+
4. 需要执行时先运行 `guanwf run --wait --dir <workdir> --dry-run`,确认后追加 `--confirm`
|
|
208
|
+
|
|
209
|
+
如果 `export` 没过,不要直接 `preview` 或 `save`。
|
|
210
|
+
|
|
211
|
+
## 默认流程
|
|
212
|
+
|
|
213
|
+
### 新建工作流
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
guanwf create --name "我的工作流" --parent-dir <dirId> --dir <workdir> # 数据流节点骨架(默认)
|
|
217
|
+
guanwf create --name "Python清洗" --type PYTHON --parent-dir <dirId> --dir <workdir> # Python 节点骨架
|
|
218
|
+
guanwf python-runtime --dir <workdir> --format json # 写 Python 前读取目标环境 Runtime
|
|
219
|
+
|
|
220
|
+
# 编辑 workflow.go(节点 + 依赖)和 nodes/ 下源文件后:
|
|
221
|
+
guanwf export --dir <workdir>
|
|
222
|
+
guanwf save-draft --dir <workdir> --dry-run
|
|
223
|
+
guanwf save-draft --dir <workdir> --confirm
|
|
224
|
+
guanwf preview --dir <workdir> # 数据流节点:预览数据
|
|
225
|
+
guanwf run --node "<节点名>" --validate --dir <workdir> --confirm # Python 节点:校验(不创建输出数据集)
|
|
226
|
+
guanwf save --dir <workdir> --confirm # 正式发布
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 编辑已有工作流
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
guanwf edit <workflowId> --dir <workdir>
|
|
233
|
+
# 生成 workflow.go + nodes/<节点ID>/;含 Python 节点时同时生成 _python_runtime_context.json
|
|
234
|
+
|
|
235
|
+
# 修改源文件后与新建流程相同:export → preview/validate → save-draft/save
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
`edit` 会把数据流节点的线上 actions 经 guanetl json2go 导入为 `etl.go`(SQL 外置为 `*.sql`,
|
|
239
|
+
复杂节点外置为 `node_*.json` + `LoadNodeFromFile(...)`),这些都是可编辑源文件。
|
|
240
|
+
|
|
241
|
+
### 修复失败
|
|
242
|
+
|
|
243
|
+
1. 先确认失败发生在 `export`、`preview`、`save` 还是 `run`。
|
|
244
|
+
2. 如果失败来自 `export`,只改 `workflow.go` 或节点源文件。
|
|
245
|
+
3. 如果失败来自 `preview`,先确认 `_exported_workflow.json` 是否由最新源文件生成;必要时先重跑 `export`。
|
|
246
|
+
4. 如果失败来自 `save`,不要手写保存 payload;检查工作流是否能重新拉取、本地导出是否来自最新源文件。
|
|
247
|
+
5. 从失败步骤往后重跑,不要把整个工作目录推倒重来。
|
|
248
|
+
|
|
249
|
+
### 运行工作流
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
guanwf run --dir <workdir> --confirm # 触发运行(已发布版本)
|
|
253
|
+
guanwf run --wait --dir <workdir> --dry-run # 查看执行计划
|
|
254
|
+
guanwf run --wait --dir <workdir> --confirm # 确认并等待完成
|
|
255
|
+
guanwf run --wait --timeout 600 --dir <workdir> --confirm # 自定义超时
|
|
256
|
+
guanwf run --wait --output-timeout 120 --dir <workdir> --confirm # 输出注册/更新独立超时
|
|
257
|
+
guanwf run --wait --logs --dir <workdir> --confirm # 完成后输出任务日志
|
|
258
|
+
guanwf run --node "<节点名>" --validate --dir <workdir> --confirm # 校验 Python 脚本(不创建输出数据集)
|
|
259
|
+
guanwf run --node "<节点名>" --draft --wait --logs --dir <workdir> --confirm # 单节点真实运行草稿
|
|
260
|
+
guanwf run --recover --wait --dir <workdir> --confirm # 从最近失败实例的失败节点续跑
|
|
261
|
+
guanwf instance resume-failed <instanceId> --dom-id <domId> --wait --timeout 900 --confirm
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
`--node` 按节点显示名只运行指定节点(TASK_ONLY);`--draft` 运行 save-draft 的草稿版本;
|
|
265
|
+
`--logs` 输出任务实例日志(失败时自动拉取,失败的子工作流节点自动下钻子实例日志);
|
|
266
|
+
`--recover` 从失败处续跑(见「失败恢复」一节)。
|
|
267
|
+
普通 `run` 会在提交前执行 Python 输入规模/内存预检并返回 `PASS/NO_GO/UNKNOWN`;`NO_GO`
|
|
268
|
+
默认阻断,`UNKNOWN` 只有在阅读 dry-run 缺失证据后显式追加 `--allow-unknown-memory` 才继续。
|
|
269
|
+
预检只读取数据集元数据,不触发 preview 或全量物化。TASK_ONLY + CREATE_NEW 依据版本化能力矩阵
|
|
270
|
+
fail closed;用 `guanwf output capabilities` 查询当前矩阵。
|
|
271
|
+
启动实例前会从同一份最终执行快照重新解析 `--param`、输出后置条件与 Python 内存门禁;
|
|
272
|
+
确认期间发生参数、Python 节点或输出槽位漂移时会在 `start-process-instance` 前失败关闭。
|
|
273
|
+
`run --recover` 和 `instance resume-failed` 的最外层实例只有传 `--wait` 才等待完成;嵌套
|
|
274
|
+
PROCESS 子实例始终等待成功后才恢复父实例。长任务用 `--timeout` 调整等待上限。
|
|
275
|
+
|
|
276
|
+
**`--validate` 是验证 Python 脚本的默认方法**:工作流必须先有草稿。CLI 先对最终完整源码
|
|
277
|
+
执行 WORKFLOW_PARAMS 唯一入口、类型、引号上下文和残留检查(dry-run 只显示类型/来源,不显示
|
|
278
|
+
值),再在临时定义中清空目标 Python 节点的输出注册配置,并把 `save_outputN` 替换为 serializer
|
|
279
|
+
stub。stub 会在任务唯一临时目录中用真实 PyArrow/Parquet 完成 `Table.from_pandas` 和
|
|
280
|
+
`write_table`,随后清理目录且不注册数据集;结束后自动恢复原始草稿。发布态工作流必须先执行
|
|
281
|
+
`save-draft --confirm`,CLI 不会为了校验擅自创建无法废弃的临时草稿。日志中可看到 dtype、
|
|
282
|
+
head、Arrow schema 和 `serializer=SUCCESS`。详见 `references/WORKFLOW_DSL.md`。
|
|
283
|
+
|
|
284
|
+
### 预览数据流节点
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
guanwf preview --dir <workdir> # 只有一个数据流节点时自动选中,预览其终端 action
|
|
288
|
+
guanwf preview <actionId> --dir <workdir> # 多个数据流节点时按 action id 定位
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
`preview` 基于 export 的本地定义直接发起预览,无需先 save。Python 节点没有 preview API,
|
|
292
|
+
校验用 `run --node "<节点名>" --validate`。
|
|
293
|
+
|
|
294
|
+
## 编排工作流(把一批作业统一调度)
|
|
295
|
+
|
|
296
|
+
场景:已有一批作业工作流(每个作业产出数据集),要按依赖串成一个主工作流统一调度。
|
|
297
|
+
|
|
298
|
+
用户可能这样下达任务(自然语言 → 执行路径映射):
|
|
299
|
+
|
|
300
|
+
| 用户说 | Agent 执行 |
|
|
301
|
+
|---|---|
|
|
302
|
+
| "把 xslh 开头的这批作业串成一个统一调度,每天凌晨 2 点跑" | create ORCHESTRATION → deps plan --search "xslh" → verify → save → schedule set --cron "0 0 2 * * ?" |
|
|
303
|
+
| "这三个作业 A、B、C 编排起来,A 必须在 B 之前" | deps plan --jobs <idA>,<idB>,<idC> + hints.json 里 before:[{first:A,then:B}] |
|
|
304
|
+
| "作业C 是读昨天的快照,别给它连边" | hints.json 里 cross_batch:[{consumer:C,dataset:<dsId>}] |
|
|
305
|
+
| "统一调度里有个作业挂了,帮我修好后接着跑,成功的别重跑" | 下钻日志定位失败作业 → 回作业目录修复+save → 编排目录 run --recover --wait |
|
|
306
|
+
| "调度先别上线/先停掉" | schedule set ... --offline / schedule disable |
|
|
307
|
+
| "看下现在的调度配置" | schedule info |
|
|
308
|
+
|
|
309
|
+
**依赖的事实源是平台血缘**(作业定义中的输入/输出数据集),不是文档/Excel 的口头描述。
|
|
310
|
+
用 `deps plan` 从血缘自动推导,用 `deps verify` 对账,人工只补血缘表达不了的提示
|
|
311
|
+
(先后顺序 hint、跨批次 CrossBatch、剔除 exclude)。
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# 1. 建编排工作区(无初始节点)
|
|
315
|
+
guanwf create --name "统一调度" --type ORCHESTRATION --parent-dir <dirId> --dir <workdir>
|
|
316
|
+
|
|
317
|
+
# 2. 从血缘自动生成 workflow.go(SubWorkflowNode + After 边,每条边注释依据)
|
|
318
|
+
guanwf deps plan --search "<作业名模式>" --yes --dir <workdir> # 或 --jobs <id1>,<id2>,...
|
|
319
|
+
guanwf deps plan ... --hints hints.json # 人工提示(before/cross_batch/exclude)
|
|
320
|
+
|
|
321
|
+
# 3. 人工微调后对账(ERROR 必须修复;有 ERROR 时 exit 1)
|
|
322
|
+
guanwf export --dir <workdir>
|
|
323
|
+
guanwf deps verify --dir <workdir>
|
|
324
|
+
|
|
325
|
+
# 4. 保存并运行
|
|
326
|
+
guanwf save --dir <workdir> --confirm
|
|
327
|
+
guanwf run --wait --dir <workdir> --confirm
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# 5. 配置定时调度并上线
|
|
332
|
+
guanwf schedule set --cron "0 0 2 * * ?" --dir <workdir> --confirm
|
|
333
|
+
guanwf schedule set --cron "0 0 2 * * ?" --param biz_date=2026-07-14 --dir <workdir> --confirm
|
|
334
|
+
guanwf schedule event set --rule <datasetId>:<taskName> --param biz_date=2026-07-14 --dir <workdir> --confirm
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
规则要点:
|
|
338
|
+
|
|
339
|
+
- 一个数据集只能有一个产出作业(DUP_PRODUCER 是 ERROR)。
|
|
340
|
+
- A 读 B 的产出则编排中必须有 B→A 路径,否则 verify 报 MISSING_EDGE;
|
|
341
|
+
刻意读上一批(T-1)产物时在 `Workflow.CrossBatch` 中声明,verify 降级为 INFO。
|
|
342
|
+
- 子作业失败 → 主实例失败,下游不执行;失败日志会自动下钻到子实例定位真实报错。
|
|
343
|
+
- **失败恢复**:修复失败作业并 `guanwf save --confirm` 后,在编排目录执行
|
|
344
|
+
`guanwf run --recover --wait --confirm`——自底向上恢复失败的子实例和主实例,
|
|
345
|
+
成功祖先和无关分支不重跑;恢复节点的全部 DAG 后继会重跑(包括先前为 SUCCESS 的后继)。
|
|
346
|
+
例如 job_a/job_b 是 job_c 的成功祖先、job_c 失败时只从 job_c 及其后继开始重跑。
|
|
347
|
+
- 修改编排结构改 `workflow.go`(`SubWorkflowNode` / `After` / `CrossBatch`),
|
|
348
|
+
不要去改被引用作业的内容;作业内容问题回作业自己的工作目录修。
|
|
349
|
+
|
|
350
|
+
`SubWorkflowNode` DSL、hints.json 结构、verify 全部检查项见 `references/WORKFLOW_DSL.md`
|
|
351
|
+
「编排工作流」一节。
|
|
352
|
+
|
|
353
|
+
## 定时调度
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
guanwf schedule info --dir <workdir> # 查看当前调度
|
|
357
|
+
guanwf schedule set --cron "0 0 2 * * ?" --dir <workdir> --confirm # 创建/更新并上线
|
|
358
|
+
guanwf schedule set --cron "0 0 2 * * ?" --offline --dir <workdir> --confirm # 只保存不上线
|
|
359
|
+
guanwf schedule enable --dir <workdir> --confirm # 上线
|
|
360
|
+
guanwf schedule disable --dir <workdir> --confirm # 下线
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
- crontab 是 Quartz 6/7 段表达式(秒 分 时 日 月 周 [年]),如 `0 30 6 * * ?` 每天 06:30。
|
|
364
|
+
- `--failure-strategy` 是已废弃的兼容参数,仅接受 `CONTINUE`;新离线开发固定提交 `CONTINUE`,失败后的调度行为由节点间 `FAILURE` / `ALL` 连线配置。
|
|
365
|
+
- `set` 可选 `--warning NONE|SUCCESS|FAILURE|ALL`(默认 FAILURE)、`--start/--end` 生效区间、
|
|
366
|
+
`--auto-cancel-queued`(上一批未跑完时自动取消堆积实例)。
|
|
367
|
+
- 已有调度时未指定的参数保留现状;事件调度使用 `guanwf schedule event get/set/disable`。
|
|
368
|
+
|
|
369
|
+
## 失败恢复(run --recover)
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
guanwf run --recover --wait --dir <workdir> --confirm
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
找到最近一次 FAILURE 实例,从恢复节点处续跑;成功祖先和无关分支不重跑,恢复节点的
|
|
376
|
+
全部 DAG 后继会重跑。8.2.0 的恢复种子状态包括 FAILURE、STOP、KILL、
|
|
377
|
+
NEED_FAULT_TOLERANCE。适用于长链路编排中
|
|
378
|
+
个别作业失败:先回失败作业的工作目录修复并 `guanwf save --confirm`,再回编排目录 `--recover --confirm`。
|
|
379
|
+
|
|
380
|
+
平台语义(已实测):失败的子工作流节点会复用原子实例,且子实例持有失败时的旧定义快照。
|
|
381
|
+
`--recover` 已处理这一点——自底向上先恢复失败子实例(`update=true` 吸收失败节点及后继
|
|
382
|
+
的最新发布定义),并对恢复范围内已成功的 PROCESS 后继显式执行 `REPEAT_RUNNING`,再恢复
|
|
383
|
+
父实例。若子工作流引用已切换、编排 DAG 结构已变更(加减节点/改依赖),CLI/平台会拒绝
|
|
384
|
+
恢复,此时直接
|
|
385
|
+
`guanwf run --confirm` 重跑整链。
|
|
386
|
+
|
|
387
|
+
## save 的工作机制
|
|
388
|
+
|
|
389
|
+
`save` / `save-draft` 不是简单把本地 JSON 上传。内部流程是:
|
|
390
|
+
|
|
391
|
+
1. 读取本地 `_exported_workflow.json`(必须由 `export` 重新生成)
|
|
392
|
+
2. 从服务端重新拉取工作流最新版本作为基底
|
|
393
|
+
3. tasks 按节点 id 做字段级合并:本地定义的字段覆盖,服务端独有字段(dsId、运行时注册信息等)保留
|
|
394
|
+
;Python 输出顶层 `dsId` 与 `dataSource.dsId` 同时存在时必须一致,冲突会在写请求前失败
|
|
395
|
+
;本地显式绑定已有 dsId 的 Python 输出会 fresh 查询数据集并补齐 `parentDirId`、`parentDirName`、
|
|
396
|
+
`dirPath`,同时校验物理对象存在性、`DATA_SET_OFFLINE_DEV/MASTER_FLOW` 类型、producer
|
|
397
|
+
lineage 与输出槽身份;不存在、无权限、类型/血缘/目录/槽位冲突均在写请求前按维度失败。
|
|
398
|
+
仅当 `_wf_state.json` 已记录同一 task/slot 的可信 placeholder lineage,或该 slot 是本次保存
|
|
399
|
+
明确新增的输出时,服务端回填、`created=false` 且物理对象尚不存在的临时 dsId 才继续按
|
|
400
|
+
“待首次运行物化”处理。fresh `edit` 无法仅凭 404 区分 placeholder 与已删除的显式外部绑定,
|
|
401
|
+
因而按显式绑定 fail closed;用户改绑后的新 ID 也不会继承旧 pending 来源
|
|
402
|
+
4. 节点成员按三方判断(服务端最新 + 本地 `_parent_merge_snapshot.json` + 本地导出):
|
|
403
|
+
本地快照里有、导出里删了的节点 → 删除;服务端有、本地快照不知道的节点(他人并发新增)→
|
|
404
|
+
保留并打印提示
|
|
405
|
+
5. dataflowJson 按 dataflow id 经 etlmerge 做 actions 字段级合并(成员判断同上)
|
|
406
|
+
6. dry-run 固定输出 `baseVersion/currentVersion/changedFields/noOp/conflicts`;可用
|
|
407
|
+
`--require-change` 阻断静默 no-op,用 `--expected-base-version` 做 optimistic CAS。调用
|
|
408
|
+
`/process/save-draft` 或 `/process/save` 后必须 fresh readback 所有目标字段,否则命令非零退出;
|
|
409
|
+
随后把**本次提交的定义**刷新为本地快照
|
|
410
|
+
并同步进 `python.json`(不是服务端回写值——服务端在保存/运行后对输出 dataSource/dsId
|
|
411
|
+
等字段的回写需要重新 `guanwf edit` 才能拿到),随后回读服务端做输出落位诊断:
|
|
412
|
+
目录被纠正时提示 `save.output_dir_rectified`,输出尚未物化时提示
|
|
413
|
+
`save.output_pending_materialization`(此时 dsId 是临时值,首次成功运行前每次保存都会
|
|
414
|
+
重新生成,勿用于下游引用)。`run` 等待成功后会校验所有输出的数据集实体线上存在
|
|
415
|
+
(`created=true` 直接通过;`created=false` 会查询数据集本身——绑定其他流程创建的
|
|
416
|
+
已有数据集时 DSL 要求保持 `Created=false`,该状态合法)。`run --wait` 会冻结每个 slot 的
|
|
417
|
+
CREATE_NEW/UPDATE_EXISTING 后置条件,逐项返回 compute/file/discovery/registerOrUpdate/readback;
|
|
418
|
+
CREATE_NEW 要求唯一 dsId、lineage 和可读实体,UPDATE_EXISTING 还要求版本/commit token/摘要
|
|
419
|
+
发生变化。确认后、启动 POST 前的最后执行快照会重新生成输出和内存契约;并发新增/删除
|
|
420
|
+
task、slot 或资源漂移不会绕过 preflight。任一失败时 `businessResult != SUCCESS` 且命令非零退出。
|
|
421
|
+
|
|
422
|
+
因此用户和 AI 都不需要手写服务端保存 payload。多人/多端并发修改同一工作流时,以服务端
|
|
423
|
+
最新版本为基底合并,不会把别人新加的节点冲掉;但同一节点的并发修改仍是后保存者覆盖。
|
|
424
|
+
|
|
425
|
+
只修改一个 Python 输出绑定时,不要编辑完整 DSL;先确保当前版本已有草稿,再使用精确命令:
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
guanwf output bind <workflowId> --task-id <taskId> --slot-id <outputId> --dataset-id <dsId> --dry-run
|
|
429
|
+
guanwf output bind <workflowId> --task-id <taskId> --slot-id <outputId> --dataset-id <dsId> --confirm
|
|
430
|
+
guanwf output rebind <workflowId> --task-id <taskId> --slot-id <outputId> --expected-old <oldDsId> --dataset-id <newDsId> --confirm
|
|
431
|
+
guanwf output unbind <workflowId> --task-id <taskId> --slot-id <outputId> --expected-old <oldDsId> --confirm
|
|
432
|
+
guanwf output bind-registered-outputs <instanceId> --workflow-id <workflowId> --dom-id <domId> --dry-run
|
|
433
|
+
guanwf output bind-registered-outputs <instanceId> --workflow-id <workflowId> --dom-id <domId> --confirm
|
|
434
|
+
guanwf output capabilities -f json
|
|
435
|
+
guanwf output bootstrap-plan <workflowId> --task-id <taskId> --slot-id <outputId> --update-mode APPEND --primary-key id -f json
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
命令以 task id + output slot id 精确定位,只保存草稿;确认前再次 fresh read 并执行 optimistic
|
|
439
|
+
CAS,`expected-old` 不一致或在确认窗口中已检测到定义变化时不会发起写入。后端当前没有暴露原子
|
|
440
|
+
条件写接口,最后一次 fresh read 到整份 `save-draft` POST 之间仍遵循上文的同节点后写覆盖语义;
|
|
441
|
+
并发编辑同一工作流时应串行执行精确绑定命令。`unbind` 只清除定义中的绑定,不删除物理数据集。
|
|
442
|
+
`bind-registered-outputs` 只接受实例中带 `taskId + slotId + dsId` 的精确映射,拒绝按 `dsIds`
|
|
443
|
+
数组顺序猜测;`processInstanceJson` 只用于识别 task/slot 定义形状,每个回写还必须有当前实例运行结果中同
|
|
444
|
+
task/slot/dsId 的成功状态或与 fresh 数据集精确一致的 commit token,但显式 `FAILURE` 终态永远优先于 token。
|
|
445
|
+
所有 slot 先校验后用一份
|
|
446
|
+
save-draft 提交,缺失/重复/冲突时零写入,重复执行幂等。
|
|
447
|
+
首次 `CREATE_NEW` 运行成功后,CLI 会把精确实例输出标记为“等待绑定发布”;在执行
|
|
448
|
+
`bind-registered-outputs` 并通过 `save --confirm` 完成发布前,后续 `run`(包括 dry-run)会以
|
|
449
|
+
`output_binding.publish_required` 失败关闭,避免运行时回写的 dsId 被误判为已进入发布版本。
|
|
450
|
+
未绑定输出不能一步直接 APPEND/PK;先按 bootstrap plan 以 OVERWRITE 创建,fresh 取得并绑定唯一
|
|
451
|
+
dsId,再用 expected-old 切换增量模式和主键。
|
|
452
|
+
|
|
453
|
+
若他人并发新增的节点依赖了本地这次删除/改名的节点,保存会检测到断链冲突并中止,
|
|
454
|
+
此时按提示重新 `guanwf edit <工作流ID>` 同步最新版本后再修改。
|
|
455
|
+
|
|
456
|
+
## API 路由
|
|
457
|
+
|
|
458
|
+
所有 API 通过 `/api/offline-dev/*` 前缀走 BFF 代理到工作流引擎。
|
|
459
|
+
|
|
460
|
+
| 操作 | 方法 | 路径 |
|
|
461
|
+
|------|------|------|
|
|
462
|
+
| 分页查询 | POST | `/api/offline-dev/process/list-paging` |
|
|
463
|
+
| 查询详情 | GET | `/api/offline-dev/process/{id}/select-by-id` |
|
|
464
|
+
| 保存草稿 | POST | `/api/offline-dev/process/save-draft` |
|
|
465
|
+
| 保存发布 | POST | `/api/offline-dev/process/save` |
|
|
466
|
+
| 预览普通数据流 | POST | `/api/offline-dev/dataflow/preview-async` |
|
|
467
|
+
| 查询/取消普通预览 | GET/POST | `/api/offline-dev/dataflow/task/{taskId}`、`/cancel` |
|
|
468
|
+
| 预览 DB Dataflow | POST | `/api/offline-dev/dataflow/v2/preview-async` |
|
|
469
|
+
| 查询/取消 DB Dataflow 预览 | GET/POST | `/api/task/{taskId}`、`/cancel` |
|
|
470
|
+
| 运行工作流 | POST | `/api/offline-dev/process/{id}/start-process-instance` |
|
|
471
|
+
| 查询运行实例 | GET | `/api/offline-dev/process/instance/{id}/select-by-id?domId=<domId>` |
|
|
472
|
+
| 实例任务列表 | GET | `/api/offline-dev/process/instance/{id}/task-list-by-process-id?domId=<domId>` |
|
|
473
|
+
| 任务日志 | GET | `/api/offline-dev/log/detail?taskInstId=<id>&logType=UI&domId=<domId>` |
|
|
474
|
+
| 实例列表分页 | GET | `/api/offline-dev/instance/list-paging?processDefinitionId=<id>&domId=<domId>` |
|
|
475
|
+
| 恢复/停止实例 | POST | `/api/offline-dev/process/{id}/instance/{instId}/execute` |
|
|
476
|
+
| 子实例定位 | GET | `/api/offline-dev/process/instance/{instId}/task/{taskInstId}/select-sub-process?domId=<domId>` |
|
|
477
|
+
| 调度查询 | GET | `/api/offline-dev/process/{id}/schedule/info?domId=<domId>` |
|
|
478
|
+
| 调度创建/更新 | POST | `/api/offline-dev/process/{id}/schedule/create`、`/schedule/{scheduleId}/update` |
|
|
479
|
+
|
|
480
|
+
实例/日志查询接口要求 `domId` 参数(工作流详情 `select-by-id` 响应中的 `domId` 字段),
|
|
481
|
+
`guanwf run` 内部自动处理。`list-paging` 请求体的搜索字段是 `searchVal`。
|
|
482
|
+
|
|
483
|
+
## 与其他 skill 的关系
|
|
484
|
+
|
|
485
|
+
| 任务 | 工具 |
|
|
486
|
+
|------|------|
|
|
487
|
+
| BI ETL 编辑 | guanetl |
|
|
488
|
+
| 工作流/数据流只读查询 | guancli workflow(隐藏子命令,需手动输入) |
|
|
489
|
+
| 工作流编辑闭环 | guanwf(本工具) |
|
|
490
|
+
| 数据集管理 | guands |
|
|
491
|
+
| workflow.go DSL / Python 节点参考 | guanwf/references/WORKFLOW_DSL.md |
|
|
492
|
+
| 通用 ETL 节点函数参考 | guanwf/references/ETL_AI_DEVELOP.md(symlink → guanetl) |
|
|
493
|
+
| 工作流扩展节点参考 | guanwf/references/WORKFLOW_NODES.md |
|
|
494
|
+
|
|
495
|
+
## 工作流特有节点(数据流节点内部)
|
|
496
|
+
|
|
497
|
+
工作流数据流是 BI ETL 的超集,额外支持以下节点类型:
|
|
498
|
+
|
|
499
|
+
| 节点类型 | 函数 | 说明 |
|
|
500
|
+
|---|---|---|
|
|
501
|
+
| `INPUT_DATASOURCE` | `LoadNodeFromFile` / `BasicInputDatasource` | 数据库直连输入(无上游) |
|
|
502
|
+
| `OUTPUT_DATASOURCE` | `LoadNodeFromFile` / `BasicOutputDatasource` | 数据回写到数据库 |
|
|
503
|
+
| `INCREMENT_OUTPUT_DATASET` | `LoadNodeFromFile` / `BasicIncrementOutputDataset` | 增量输出数据集 |
|
|
504
|
+
| `TRIM_COLUMNS` | `BasicTrimColumns` | 去空格 |
|
|
505
|
+
| `VALUE_MAPPER` | `LoadNodeFromFile` | 值映射/替换 |
|
|
506
|
+
| `SINGLE_VALUE_MAPPER` | `LoadNodeFromFile` | Null 值替换 |
|
|
507
|
+
| `COMBINE_COLUMNS` | `BasicCombineColumns` | 合并列 |
|
|
508
|
+
|
|
509
|
+
`guanwf edit` 导入时:
|
|
510
|
+
- INPUT_DATASOURCE / OUTPUT_DATASOURCE / INCREMENT_OUTPUT_DATASET / VALUE_MAPPER / SINGLE_VALUE_MAPPER → 保存为 `node_<id>.json` + `LoadNodeFromFile("node_<id>.json")`
|
|
511
|
+
- TRIM_COLUMNS / COMBINE_COLUMNS → 直接生成结构化 Go DSL 代码
|
|
512
|
+
|
|
513
|
+
详细配置参数见 `references/WORKFLOW_NODES.md`。
|
|
514
|
+
|
|
515
|
+
## 注意事项
|
|
516
|
+
|
|
517
|
+
- 编辑时自动获取并保存工作流 snapshot,save 时从服务端重新获取最新版本合并
|
|
518
|
+
- 数据流 actions 结构与 BI ETL 相同,节点函数和约束复用 guanetl 的 framework
|
|
519
|
+
- 节点显示名在工作流内必须唯一(依赖声明与 `run --node` 都按名字引用)
|
|
520
|
+
- DB_DATAFLOW 涉及 SQL 下推和单账号约束,后续可能需要额外处理
|
|
521
|
+
- `guancli workflow` 子命令在 `guancli --help` 中不显示(隐藏命令),但手动输入可正常使用
|
|
522
|
+
- 旧版(单数据流 `etl/` 格式)工作目录已不支持,遇到时用 `guanwf edit` 在新目录重新拉取
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## VM 环境差异(观远 BI 工作站)
|
|
528
|
+
|
|
529
|
+
本技能在 MCP 虚拟工作站中运行,与本地 CLI 有以下差异:
|
|
530
|
+
|
|
531
|
+
- 命令名直接可用:在工作站里直接执行 `guancli` / `guanetl` / `guanvis` / `guands` / `guanmetric` / `guanwf`(无需安装)。
|
|
532
|
+
- 认证:BI 凭证由网关注入,**不要**执行 `auth login` 或设置 token,直接运行业务命令即可。
|
|
533
|
+
- 文件路径一律用以 `/` 开头的绝对路径(`/` 即工作区根,跨会话持久)。
|
|
534
|
+
- 本技能的参考文档在 `/skills/<技能名>/references/` 下、示例工程在 `/skills/<技能名>/evals/` 下(均只读),用 read_file 工具或 `cat` 按需阅读;正文引用 `references/xxx` / `evals/xxx` 时按此路径解析。
|
|
535
|
+
- 图片文件(png/jpg/gif/webp)用 read_file 工具读取,**不要**用 `cat`/`head` 读图片。默认部署下图片以图像内容返回、模型可直接查看;若 read_file 返回"当前部署已关闭图像内容返回"的提示(部署方接入的模型不支持图像理解),则只有文本元信息,此时不要做任何依赖看图的验证,改用数据类命令核对。
|
|
536
|
+
- 不支持 `cd`、`$VAR` 展开、命令替换 `$(...)`、glob 展开;需要组合时把中间结果写入文件。
|
|
537
|
+
- 文本搜索用 `rg`(工作站内无独立 grep 二进制,`grep`/`egrep`/`fgrep` 会自动转成 `rg` 执行,无需绕路)。
|
|
538
|
+
- `install-skill` / profile 切换 / npm 相关步骤在工作站内不适用,忽略即可。
|
|
539
|
+
|
|
540
|
+
### guanwf 在工作站内的差异(必读)
|
|
541
|
+
|
|
542
|
+
- 本文档与参考文档提到的 `guancli workflow ...` 只读查询命令在工作站内**可用**(guancli help 里默认隐藏,直接执行即可)。
|
|
543
|
+
- `guanwf export` 依赖的 guanetl 已内置于工作站(宿主级联调用),无需安装,`GUANETL_BIN` 环境变量不适用。
|