website: generate the API reference from source (cordis + all 15 harness services)

scripts/gen-website-api.ts renders website/zh-CN/api/{cordis,harness}/* and the
api-sidebar.json fragment the VitePress config imports, so pages and navigation
can never drift from the code: signatures, @param/@returns prose, dispatch
modes, and GitHub source links are extracted, never transcribed, and the
generator hard-errors on any rendered member missing docs. verify-website-api
(doc-sync + run-gates) is the freshness gate.

Replaces the hand-written zh api pages (7 pages covering 7 of 15 services,
with phantom APIs: Context.current/Context.events, agent/post-step, tool/call,
compact/*, llm/pre-request none of which exist) with generated English
references: 5 cordis pages, 15 per-service pages, and a 35-event catalog
grouped by scope. The hand-written hub api/index.md stays and now indexes the
full surface; zh for these pages arrives with the unified translation flow.
This commit is contained in:
lintianle
2026-07-16 18:13:34 +08:00
parent da26138592
commit efba9fab0a
31 changed files with 2983 additions and 931 deletions
+36 -95
View File
@@ -1,122 +1,63 @@
# Tools (dsh-tools)
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
Tool 注册表和 `defineTool` DSL。
# ctx.tools
**包名:** `@deepseek-ai/dsh-tools`
**服务名:** `ctx.tools`
`ToolRegistry` — provided by `@deepseek-ai/dsh-tools`.
## ToolRegistry
Tool registry (`ctx.tools`): tool plugins register definitions; the agent loop executes calls through the `tools/pre-execute` → `tools/execute` → `tools/post-execute` pipeline. The registry contributes its schemas into the system-prompt assembly — WHICH schemas is governed by its `mode` config (see Config.mode); under a non-native mode it also registers the `run_code` tool and the `tools:sdk` prompt section itself.
### ctx.tools.register(tool)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/tools/src/index.ts#L345)
- **tool:** `ToolDefinition`
- **返回值:** `() => void` disposer
### ctx.tools.register(definition)
注册一个 tool。返回的 disposer 可手动撤销注册(通常不需要,插件卸载时自动撤销)。
## defineTool\<S\>(options)
类型安全的 tool 定义辅助函数。
```typescript
import { defineTool } from '@deepseek-ai/dsh-tools'
const tool = defineTool({
name: 'read_file',
description: 'Read a file from disk.',
parameters: {
path: { type: 'string', required: true, description: 'Absolute file path' },
offset: { type: 'number' },
limit: { type: 'number', description: 'Max lines to read' },
},
async execute(args) {
// args: { path: string; offset?: number; limit?: number }
},
})
```ts website-api
register(definition: ToolDefinition): () => void
```
### DefineToolOptions\<S\>
Register a tool. Throws if a tool with the same name is already registered. The tool's schema (minus the `execute` function) is automatically contributed to the system-prompt assembly. Disposed with the calling fiber. Emits `tools/change` on register/unregister.
| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | `string` | Tool 名称(全局唯一) |
| `description` | `string` | 发送给模型的描述 |
| `parameters` | `SchemaSpec` | 参数 schema(见下文) |
| `execute` | `(args: InferArgs<S>, exec: ToolExecution) => Promise<ToolExecuteReturn>` | 执行函数 |
| `presentCall?` | `(args: InferArgs<S>) => ToolCallView \| undefined` | UI 展示(纯函数) |
| `presentResult?` | `(args: InferArgs<S>, result: ToolResult) => ToolResultView \| undefined` | 结果 UI 展示(纯函数) |
- `definition` — the tool's schema plus its execute (and optional presentation) functions.
## SchemaSpec
**Returns** the disposer that unregisters the tool.
参数 schema DSL。每个属性是一个 `SchemaProp`:
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/tools/src/index.ts#L420)
```typescript
interface SchemaProp {
type: 'string' | 'number' | 'boolean' | 'object' | 'array'
required?: true
description?: string
enum?: string[]
properties?: SchemaSpec // type: 'object' 时
items?: SchemaProp // type: 'array' 时
}
### ctx.tools.get(name)
```ts website-api
get(name: string): ToolDefinition | undefined
```
### 类型推导 (InferArgs)
Look up a registered tool.
`InferArgs<S>` 自动从 `SchemaSpec` 推导 TypeScript 类型:
- `name` — the tool name as registered.
- `required: true` → 必填字段
- 无 `required` → 可选字段(`?`)
- `type: 'object'` + `properties` → 递归推导嵌套对象
- `type: 'array'` + `items` → 推导为数组
**Returns** the definition, or undefined when no tool has that name.
## ToolDefinition
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/tools/src/index.ts#L447)
运行时 tool 定义(`defineTool` 的返回值):
### ctx.tools.schemas()
```typescript
interface ToolDefinition {
name: string
description: string
parameters: Record<string, unknown> // JSON Schema
execute(args: unknown, exec: ToolExecution): Promise<ToolExecuteReturn>
presentCall?(args: unknown): ToolCallView | undefined
presentResult?(args: unknown, result: ToolResult): ToolResultView | undefined
}
```ts website-api
schemas(): ToolSchema[]
```
## ToolExecuteReturn
Return all registered tool schemas — exactly the model-facing fields (`name`, `description`, `parameters`), as sent to the model via the system-prompt assembly. Constructed EXPLICITLY rather than by stripping known non-schema members: a `ToolDefinition` also carries `execute` and the optional `presentCall`/`presentResult` UI callbacks, and those (especially the functions) must never leak into a model request. An allowlist can't drift when a new non-schema member is added to the definition; a denylist (rest-destructure) would silently leak it.
```typescript
type ToolExecuteReturn =
| ContentBlock[] // 仅内容
| { content: ContentBlock[]; meta?: unknown } // 内容 + 元信息
**Returns** one deep-cloned schema per registered tool, in registration order.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/tools/src/index.ts#L462)
### ctx.tools.execute(exec)
```ts website-api
async execute(exec: ToolExecution): Promise<ToolExecutionResult>
```
## ToolArgsError
Execute one tool call through the `tools/pre-execute` → `tools/execute` (around dispatch) → `tools/post-execute` pipeline. `pre-execute` is the gate (allow/deny), `tools/execute` wraps core dispatch (a timeout/retry/metrics seam), and `post-execute` is the inspect/transform seam; core dispatch sits as the base `next()` of the `tools/execute` waterfall. The whole thing is wrapped in one outer try/catch so a throwing listener (in any waterfall) becomes an `isError` result instead of failing the turn; the tool body ALSO keeps its own inner try/catch, so a thrown tool becomes an `isError` result that `tools/execute` and `post-execute` listeners can still inspect. If the tool is not registered, the result is an `isError` carrying a `UNKNOWN_TOOL` structured error. A thrown HarnessError surfaces its `{ name, code }` on the result.
当模型生成的参数不匹配 schema 时抛出:
- `exec` — the call to run (name, parsed arguments, caller agent, signal).
```typescript
class ToolArgsError extends HarnessError {
code: 'INVALID_ARGS'
violations: string[]
}
```
**Returns** the final result after every waterfall; failures resolve as `isError` results, never rejections.
框架自动捕获并转换为 `isError` 结果返回给模型。
## validateArgs(spec, args)
- **spec:** `SchemaSpec`
- **args:** `unknown`
- **返回值:** `string[]` 违规信息列表(空 = 合法)
手动校验参数。`defineTool` 内部使用,通常不需要直接调用。
## schemaSpecToJsonSchema(spec)
- **spec:** `SchemaSpec`
- **返回值:** `JsonSchemaObject`
将 SchemaSpec 转换为标准 JSON Schema。用于发送给模型的 wire format。
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/tools/src/index.ts#L487)