# dsh-tool-orchestrate

[English](README.md) | 中文

DeepSeek Harness 的声明式任务 DAG 编排插件。这个可选 Cordis 插件注册面向模型的 `orchestrate_tasks` 工具，在启动任何内容之前校验有向无环任务图，并通过现有 `ctx.workflowEngine` 执行。

这是独立的社区插件，并非 DeepSeek 官方软件包。

包内固定 worker 脚本执行确定性的拓扑层。模型编写的任务 id、提示词、依赖 id、schema、提供方名称、模型名称与上游结果只作为 JSON 数据传递，绝不插值到 JavaScript 源码中。

## 安装

```sh
dsh plugin --profile web add dsh-tool-orchestrate
```

可以把 `web` 换成需要扩展的 profile。包声明了 DSH bundle manifest，因此安装时会自动加入 `tool-orchestrate` Cordis 行。本项目通过 npm 分发预构建版本，不支持直接从 GitHub 仓库安装。

插件要求 DeepSeek Harness 部署已经提供：

- `ctx.tools`
- `ctx.systemPrompt`
- `ctx.workflowEngine`，通常由 `@deepseek-ai/dsh-workflow-worker-thread` 提供
- workflow engine 选定的 subagent provider

## 手动配置 Cordis

执行 `dsh plugin add` 后通常无需手动配置。自定义组合可以加入：

```yaml
- id: tool-orchestrate
  name: 'dsh-tool-orchestrate'
```

标准 DSH base bundle 已经加载 `workflow-worker-thread`。自定义组合必须提供 `ctx.workflowEngine`；如果某个 preset 关闭了 workflow engine，应在后续 patch 层显式重新启用。

## 模型输入

`orchestrate_tasks` 接收：

- `meta`：规范化 `name` 与 `description`；
- `tasks`：非空任务数组，任务包含小写 kebab-case `id`、`title` 和规范化 `prompt`；
- 可选逐任务 `dependsOn`、`provider`、`model` 与对象根 `outputSchema`。

完成的任务返回子级文本或结构化值。失败子级变为 `{ status: 'failed', error: 'subagent_failed' }`；被失败或跳过的直接依赖阻塞的任务变为 `skipped`，并带有确定性的 `blockedBy` id。结果保持原始任务数组顺序，并附带聚合计数与顶层 `completed`、`partial` 或 `failed` 状态。

## API key 归属

本插件不拥有也不保存 API key。子任务使用宿主部署已有的 LLM 路由与凭证来源，例如进程环境中的 `DEEPSEEK_API_KEY`、宿主凭证 provider 或其他已配置路由。除非任务选择不同的 provider/model 路由，subagent 会继承与父级组合相同的凭证配置。

不要把 API key 写入提示词、`cordis.yml`、源码或 GitHub Actions 日志。优先使用环境变量或部署方的凭证机制。

## 配置

| 键 | 默认值 | 含义 |
|---|---|---|
| `toolName` | `orchestrate_tasks` | 面向模型的工具名称。 |
| `maxTasks` | `64` | 单次调用最大任务数。 |
| `maxDependencies` | `16` | 单个任务最大直接依赖数。 |
| `maxPromptChars` | `32768` | 单个任务规范化提示词最大字符数。 |
| `maxResultChars` | `50000` | 渲染规范 JSON 的上限。 |

所有数值限制都必须是正安全整数；`toolName` 必须是非空且已规范化的字符串。

## 开发

```sh
pnpm install
pnpm run typecheck
pnpm run check
```

发布从干净 checkout 通过手动触发的 `Publish to npm` GitHub Actions workflow 完成。维护者需要先配置该 workflow 使用的 `npm` environment 和 `NPM_TOKEN` secret。
