Skip to content

文档操作

文档运行、内容读写、协同感知、协作状态管理和复制等操作。

源码: apps/backend/src/routes/documents.tsapps/backend/src/routes/document-edit.tsapps/backend/src/routes/document-awareness.ts

GET /documents/:documentId/content

获取文档的 JSON 内容和内容哈希(content_hash)。哈希用于后续编辑时的乐观并发控制。

认证方式

JWT Token / API Key / Agent Token(combinedAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

响应格式

状态码: 200

json
{
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "codeBlock",
        "attrs": { "id": "block-uuid", "name": "代码块" },
        "content": [{ "type": "text", "text": "console.log('hello')" }]
      }
    ]
  },
  "content_hash": "a1b2c3d4",
  "title": "文档标题",
  "updated_at": "2026-03-12T10:00:00.000Z"
}
字段类型说明
contentProsekitDocumentProseMirror 格式的文档内容
content_hashstringFNV-1a 哈希(8 字符 hex),用作 base_version
titlestring | null文档标题
updated_atstring最后更新时间

错误码

状态码说明
404文档不存在或无权访问

POST /documents/:documentId/edit

命令式或全量编辑文档内容,支持乐观并发控制。

认证方式

JWT Token / API Key / Agent Token(combinedAuth),需要文档写入权限。

并发控制机制

  1. 调用方先通过 GET /documents/:documentId/content 获取 content_hash
  2. 编辑时将此值作为 base_version 传入
  3. 若文档在此期间被修改,返回 409 Conflict + 最新内容
  4. 若文档正在被协同编辑(Hocuspocus 活跃连接),返回 423 Locked

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

Body 参数

参数类型必填说明
base_versionstring当前持有的 content_hash
mode"commands" | "content"编辑模式
commandsCommand[]mode=commands 时必填命令列表
contentProsekitDocumentmode=content 时必填全量替换的文档内容

编辑模式

全量替换模式 (mode: "content")

直接替换整个文档内容:

json
{
  "base_version": "a1b2c3d4",
  "mode": "content",
  "content": {
    "type": "doc",
    "content": [...]
  }
}

命令式编辑模式 (mode: "commands")

通过命令序列精细操作文档中的 Block:

json
{
  "base_version": "a1b2c3d4",
  "mode": "commands",
  "commands": [
    { "op": "list" },
    { "op": "read", "blockId": "block-uuid" },
    { "op": "write", "blockId": "block-uuid", "content": { "type": "paragraph", "content": [...] } },
    { "op": "insert", "after": "block-uuid", "block": { "type": "codeBlock", "attrs": { "id": "new-uuid" }, "content": [...] } },
    { "op": "delete", "blockId": "block-uuid" },
    { "op": "replace", "blockId": "block-uuid", "block": { ... } },
    { "op": "move", "blockId": "block-uuid", "after": "target-uuid" },
    { "op": "str_replace", "blockId": "block-uuid", "old_str": "旧文本", "new_str": "新文本" }
  ]
}

支持的命令:

命令参数说明
list-列出所有顶层 Block 的 id、type、name、index
readblockId读取指定 Block 的完整内容
read_rangefrom, to读取两个 Block 之间(含)的所有 Block
writeblockId, content替换指定 Block 的 content(保留 type 和 attrs)
insertblock, after?在指定 Block 之后插入新 Block(after=null 则插入开头)
deleteblockId删除指定 Block
replaceblockId, block整体替换指定 Block(包括 type 和 attrs)
moveblockId, after?将 Block 移动到指定位置(after=null 则移到开头)
str_replaceblockId, old_str, new_str在 Block 内做唯一文本替换(匹配数不为 1 则报错)

响应格式

成功 200

json
{
  "success": true,
  "version": "e5f6g7h8",
  "results": [
    { "op": "list", "success": true, "data": [...] },
    { "op": "write", "success": true }
  ]
}

版本冲突 409

json
{
  "error": "version_conflict",
  "message": "文档已被修改,请重新获取最新内容",
  "current_version": "new-hash",
  "current_content": { "type": "doc", "content": [...] }
}

文档锁定 423

json
{
  "error": "document_locked",
  "message": "文档正在被协同编辑或等待落库,请稍后重试",
  "active_connections": 2,
  "scope": "local"
}

错误码

状态码错误说明
400无效请求base_version 缺失、mode 无效、commands 为空等
403无写入权限用户缺少 write 权限
404文档不存在或无权访问文档不存在或用户无权限
409version_conflict文档在读取后已被修改
423document_locked文档正在被协同编辑

GET /documents/:documentId/awareness

获取文档的在线协作者信息,包括用户身份、光标位置和所在 Block。

认证方式

JWT Token / API Key / Agent Token(combinedAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

响应格式

状态码: 200

json
{
  "collaborators": [
    {
      "clientId": 1234,
      "userId": "user-uuid",
      "name": "张三",
      "color": "#ff6b6b",
      "cursor": { "anchor": 42, "head": 42 },
      "selection": {
        "blockId": "block-uuid",
        "blockType": "codeBlock",
        "text": null
      }
    }
  ],
  "active_connections": 1,
  "scope": "local"
}
字段类型说明
collaboratorsarray在线协作者列表
collaborators[].clientIdnumberYjs 客户端 ID
collaborators[].userIdstring | null用户 ID
collaborators[].namestring | null用户名
collaborators[].colorstring | null光标颜色
collaborators[].cursorobject | nullProseMirror 光标位置
collaborators[].selectionobject | null光标所在的 Block 信息
collaborators[].selection.blockIdstringBlock ID
collaborators[].selection.blockTypestringBlock 类型
collaborators[].selection.textstring | undefined选区文本(有选区时)
active_connectionsnumber活跃连接数
scopestring固定为 "local"(仅当前进程)

scope 说明:当前仅覆盖本进程的协同连接。多实例部署时,协作连接可能分布在不同实例上。

错误码

状态码说明
404文档不存在或无权访问

POST /documents/:documentId/run

运行文档(调试模式)。支持三种响应模式:SSE 流式、NDJSON 流式、JSON 一次性。

认证方式

JWT Token(仅支持 JWT,combinedAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

Body 参数

json
{
  "inputs": { "inputName": "值" },
  "stream": true,
  "format": "sse",
  "content": { "type": "doc", "content": [...] },
  "timeout": 60
}
参数类型默认值说明
inputsobject{}Input Block 的输入值(key 为 Input Block 名称)
streambooleantrue是否使用流式响应
format"sse" | "ndjson""sse"流式响应格式(仅 stream=true 时生效)
contentobject-ProseMirror 文档内容(可选,调试模式可直接传入,跳过数据库查询)
timeoutnumber-超时时间(秒),不超过管理后台配置的最大值

允许空 body(使用默认值)。

响应格式

SSE 流式响应(默认)

Content-Type: text/event-stream

事件类型:

事件数据字段说明
run_startrunId, documentId运行开始
block_startblockId, blockType, blockNameBlock 开始执行
block_chunkblockId, deltaBlock 输出片段(流式输出)
block_completeblockId, outputBlock 执行完成
block_endblockIdBlock 生命周期结束
block_errorblockId, errorBlock 执行出错
tool_startblockId, toolCallId, toolName工具调用开始
tool_resultblockId, toolCallId, result工具调用结果
run_errorrunId, error, message运行异常(如超时)
run_completerunId, globalCtx, sessions, completedBlocks, duration, timedOut运行完成

NDJSON 流式响应

Content-Type: application/x-ndjson

每行一个 JSON 对象,包含 type 字段标识事件类型,字段与 SSE 事件一致。

JSON 一次性响应(stream: false

状态码: 200

json
{
  "runId": "uuid",
  "documentId": "uuid",
  "globalCtx": [...],
  "sessions": [
    {
      "blockId": "uuid",
      "blockType": "code",
      "blockName": "代码块",
      "status": "completed",
      "output": "输出内容"
    }
  ],
  "duration": 1234,
  "timedOut": false
}

错误码

状态码错误说明
400输入参数验证失败inputs 不符合 Input Block 的 schema 定义
400no_team_associated文档没有关联团队
402insufficient_credits积分余额不足
403调试模式仅支持 JWT 认证使用了非 JWT 认证
403无运行权限,请联系项目管理员授权用户缺少 execute 权限
404文档不存在或无权访问文档不存在或用户无权限
500balance_check_failed余额查询异常

GET /documents/:documentId/yjs-state

获取文档的 Yjs 协作状态缓存。

认证方式

JWT Token / API Key(combinedAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

响应格式

状态码: 200

json
{
  "state": [1, 2, 3, ...]
}
字段类型说明
statenumber[] | nullYjs 状态数组,null 表示无缓存

错误码

状态码错误说明
404文档不存在或无权访问无权限或文档不存在

PUT /documents/:documentId/yjs-state

保存文档的 Yjs 协作状态缓存。

认证方式

JWT Token / API Key(combinedAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID

Body 参数

json
{
  "state": [1, 2, 3, ...]
}
参数类型必填说明
statenumber[]Yjs 状态数组

响应格式

状态码: 200

json
{
  "success": true
}

错误码

状态码错误说明
400无效的 state 参数state 缺失或非数组
403无写入权限用户缺少 write 权限
404文档不存在或无权访问无权限或文档不存在

POST /documents/:projectId/duplicate

复制文件或文件夹节点(包含其下所有文档)。

认证方式

JWT Token(仅支持 JWT,combinedAuth

请求参数

Path 参数

参数类型必填说明
projectIdstring项目 UUID

Body 参数

json
{
  "nodeKey": "document-uuid-or-folder-key",
  "nodeType": "file"
}
参数类型必填说明
nodeKeystring目标节点的 key(文档 ID 或文件夹 key)
nodeType"file" | "folder"节点类型

响应格式

状态码: 200

json
{
  "success": true,
  "node": {
    "key": "new-uuid",
    "label": "[Copy]原文档名",
    "type": "file",
    "docType": "workflow",
    "isLeaf": true
  }
}
字段类型说明
successboolean是否成功
nodeFolderNode新创建的节点信息

复制命名规则:

  • "文档A" -> "[Copy]文档A"
  • "[Copy]文档A" -> "[Copy-2]文档A"

错误码

状态码错误说明
400nodeKey and nodeType are required缺少必填参数
403仅支持 JWT 认证使用了非 JWT 认证
403Permission denied非项目所有者且非团队成员
404Project not found项目不存在
404Node not found in filesFolder节点在文件树中不存在
500Failed to copy documents文档复制失败
500Failed to update project config项目配置更新失败
500Internal server error内部错误

AI Workflow Editor