Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 74 additions & 1 deletion docs/guide/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,80 @@ steps:
agent: reviewer
```

`schemaVersion` must be `v1alpha1`. `name` must match the file name. `description` is required. Each step has a unique `id` and exactly one of `command`, `prompt`, or `prompt_file`. `agent` is optional on prompt steps. `output` uses the existing shorthand: `string`, `number`, `boolean`, a literal union, an object, or an array with one item type. TeamAI validates successful command stdout or a prompt tool's `output` against it.
`schemaVersion` must be `v1alpha1`. `name` must match the file name. `description` is required. Each step has a unique `id` and at most one action: `command`, `prompt`, `prompt_file`, or `workflow` (or a pure `end` step). `agent` is optional on prompt steps. `output` uses the existing shorthand: `string`, `number`, `boolean`, a literal union, an object, or an array with one item type. TeamAI validates successful command stdout or a prompt tool's `output` against it.

### Dependencies and Conditions

Use `needs` to declare dependencies as a directed acyclic graph (DAG). When steps do not declare `needs`, they run sequentially.

```yaml
steps:
- id: build
command: npm run build
- id: test
needs: [build]
command: npm test
- id: notify_failure
needs: [test]
if: steps.test.outcome == 'failed'
command: node notify.js
```

- **Join rule**: a step with multiple dependencies is skipped only when every dependency was skipped.
- **Conditions (`if`)**: expressions evaluate boolean logic, comparisons (`==`, `!=`, `<`, `<=`, `>`, `>=`), and access `inputs.*` or settled step results `steps.<id>.outcome`, `steps.<id>.outputs.*`, and `steps.<id>.end`. JavaScript `eval` is not used.
- **Recovery branches**: when a dependency fails, downstream steps are skipped unless their `if` condition explicitly reads the failed step.

### Inputs and Command Environment

Inputs are declared at the workflow root. Command steps receive inputs only through explicit `env:` mappings. Command strings are never template-expanded, preventing shell injection when values contain characters like `$(...)`.

```yaml
inputs:
target:
type: string
steps:
- id: deploy
command: ./deploy.sh
env:
DEPLOY_TARGET: "{{ inputs.target }}"
```

### Sub-workflows and Composition

A step can run another workflow by name (file sub-workflow) or define an inline sub-workflow.

```yaml
steps:
- id: sub
workflow: build
with:
target: prod
- id: inline_step
workflow:
steps:
- id: nested
command: echo "running nested step"
outputs:
status: steps.nested.outcome
```

File sub-workflows isolate their inputs to only what is passed in `with:`. Inline workflows can read values from their enclosing scope.

### Outputs and Named Ends

Declare `outputs` to export settled values from a workflow. Declare `ends` to define named terminal outcomes (`succeeded` or `failed`) that settle the workflow early and expose their outcome to parent steps as `steps.<id>.end`.

```yaml
ends:
rejected: failed
approved: succeeded
steps:
- id: check
command: node check.js
end: approved
outputs:
decision: steps.check.end
```

`teamai pull` and `teamai push` check each file on its own. A `prompt_file` must be a regular, non-symlink file under `prompts/` in the team repo. Its text is cached with the validated workflow, so an existing run keeps that revision even if the source is later changed or deleted. A file that was valid before keeps that version in the local cache when a new revision is invalid. A field this version of teamai does not know is different: that workflow has nothing to run until teamai is updated.

Expand Down
75 changes: 74 additions & 1 deletion docs/guide/zh-CN/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,80 @@ steps:
agent: reviewer
```

`schemaVersion` 必须是 `v1alpha1`。`name` 必须和文件名一致。`description` 必填。每个步骤有唯一的 `id`,并且必须且只能使用 `command`、`prompt`、`prompt_file` 之一。提示词步骤可选填 `agent`。`output` 沿用已有简写:`string`、`number`、`boolean`、字面量联合、对象,或只含一种元素类型的数组。TeamAI 会用它校验成功命令的 stdout 或提示词工具返回的 `output`。
`schemaVersion` 必须是 `v1alpha1`。`name` 必须和文件名一致。`description` 必填。每个步骤有唯一的 `id`,最多指定一个动作:`command`、`prompt`、`prompt_file`、`workflow` 之一(或纯 `end` 步骤)。提示词步骤可选填 `agent`。`output` 沿用已有简写:`string`、`number`、`boolean`、字面量联合、对象,或只含一种元素类型的数组。TeamAI 会用它校验成功命令的 stdout 或提示词工具返回的 `output`。

### 依赖关系与条件执行

使用 `needs` 声明有向无环图(DAG)依赖。当步骤未声明 `needs` 时,按顺序执行。

```yaml
steps:
- id: build
command: npm run build
- id: test
needs: [build]
command: npm test
- id: notify_failure
needs: [test]
if: steps.test.outcome == 'failed'
command: node notify.js
```

- **汇聚规则(Join rule)**:具有多个依赖的步骤,仅当其所有依赖项均被跳过(skipped)时才会被跳过。
- **条件表达式(`if`)**:支持布尔逻辑、比较(`==`、`!=`、`<`、`<=`、`>`、`>=`),可读取 `inputs.*` 或已结算的步骤属性 `steps.<id>.outcome`、`steps.<id>.outputs.*` 与 `steps.<id>.end`。不使用 JavaScript `eval`。
- **故障恢复分支(Recovery branches)**:当依赖项失败时,后续步骤默认会被跳过,除非其 `if` 条件明确读取了失败的依赖项。

### 输入与命令环境变量

在工作流根层级声明 `inputs`。命令步骤仅通过声明的 `env:` 映射接收输入值。命令字符串本身不会进行模板展开,能防止输入包含 `$(...)` 等字符时被 shell 误执行。

```yaml
inputs:
target:
type: string
steps:
- id: deploy
command: ./deploy.sh
env:
DEPLOY_TARGET: "{{ inputs.target }}"
```

### 子工作流与组合

步骤可通过名称调用另一个工作流(文件子工作流),或声明内联子工作流。

```yaml
steps:
- id: sub
workflow: build
with:
target: prod
- id: inline_step
workflow:
steps:
- id: nested
command: echo "running nested step"
outputs:
status: steps.nested.outcome
```

文件子工作流的输入仅限于 `with:` 传入的参数,作用域相互隔离。内联工作流可访问外层作用域中的变量。

### 输出与命名结束状态

声明 `outputs` 导出工作流结算后的值。声明 `ends` 定义命名的终态(`succeeded` 或 `failed`),可提前结算工作流,并将终态名称暴露给父级步骤(如 `steps.<id>.end`)。

```yaml
ends:
rejected: failed
approved: succeeded
steps:
- id: check
command: node check.js
end: approved
outputs:
decision: steps.check.end
```

`teamai pull` 和 `teamai push` 分别检查每个文件。`prompt_file` 必须是团队仓库 `prompts/` 下的普通文件,不能是符号链接。校验时会把文件内容和工作流一起缓存,因此已经开始的运行会继续使用对应修订版,即使源文件后来被修改或删除。新修订版无效时,仍保留上一份有效缓存。这一版 teamai 不认识的字段除外:该工作流没有可运行版本,需要先更新 teamai。

Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/workflow-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ steps:
await syncWorkflowDefinitions(config);
expect(await loadCachedWorkflow(config, 'build')).not.toBeNull();

writeWorkflow(config, 'build', VALID.replace('command: node compile.js', 'command: node compile.js\n if: success'));
writeWorkflow(config, 'build', VALID.replace('command: node compile.js', 'command: node compile.js\n retry: 3'));
const synced = await syncWorkflowDefinitions(config);

expect(synced.unrunnable).toContain('workflows/build.yaml');
Expand Down
Loading
Loading