openapi: 3.0.3 info: title: Agents API v1 version: "1.0" description: | 多工作区 + 后台任务 + HTTP 轮询进度 + 文件上传/下载。 - 鉴权:Authorization: Bearer (token 为自定义字符串,服务端存 SHA256) - 事件流:与网页端 WebSocket 同粒度(text_chunk、tool_start 等) - 多工作区:所有对话/消息/文件都在指定 workspace 下进行 servers: - url: https://agent.cyjai.com components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: token schemas: ErrorResponse: type: object properties: success: { type: boolean, example: false } error: { type: string, example: "无效的 Token" } required: [success, error] CreateConversationRequest: type: object description: 可选参数;用于在创建对话时绑定 prompt/personalization properties: prompt_name: type: string nullable: true description: 自定义主 prompt 名称(用户级共享,shared/prompts/.txt) personalization_name: type: string nullable: true description: 个性化配置名称(用户级共享,shared/personalization/.json) additionalProperties: false CreateConversationResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } conversation_id: { type: string, example: "conv_20260123_234245_036" } required: [success, workspace_id, conversation_id] SendMessageRequest: type: object properties: message: type: string description: 用户消息文本(message 与 images 至少其一不为空) images: type: array items: { type: string } description: 图片路径列表(相对 project 根目录) conversation_id: type: string description: 对话 ID;不传则自动创建 model_key: type: string nullable: true description: 模型 key(可选,取决于服务端配置) run_mode: type: string nullable: true description: 运行模式:fast | thinking | deep;若传入则优先使用 thinking_mode: type: boolean nullable: true description: 是否开启思考模式(true/false) max_iterations: type: integer nullable: true description: 最大迭代次数(最多允许多少轮模型调用/工具循环) prompt_name: type: string nullable: true description: 自定义主 prompt 名称(用户级共享,shared/prompts/.txt) personalization_name: type: string nullable: true description: 个性化配置名称(用户级共享,shared/personalization/.json) additionalProperties: false PersonalizationConfig: type: object description: 个性化配置结构(content),服务端会规范化与回落默认值 properties: enabled: { type: boolean, default: false } self_identify: { type: string, default: "" } user_name: { type: string, default: "" } profession: { type: string, default: "" } tone: { type: string, default: "" } considerations: type: array items: { type: string } default: [] description: 最多 10 条,每条最多 50 字符 thinking_interval: type: integer nullable: true description: 1~50;非法值会被置空 disabled_tool_categories: type: array items: { type: string } default: [] default_run_mode: type: string nullable: true description: fast/thinking/deep 或 null auto_generate_title: { type: boolean, default: true } tool_intent_enabled: { type: boolean, default: true } default_model: type: string default: kimi description: kimi/deepseek/qwen3-max/qwen3-vl-plus additionalProperties: true example: enabled: true user_name: "Jojo" tone: "企业商务" considerations: ["优先给出结论,再补充依据"] PromptUpsertRequest: type: object properties: name: { type: string, example: "prompt_strict" } content: { type: string, example: "严格模式:..." } required: [name, content] additionalProperties: false PromptGetResponse: type: object properties: success: { type: boolean, example: true } name: { type: string, example: "prompt_strict" } content: { type: string, example: "严格模式:..." } required: [success, name, content] PromptListItem: type: object properties: name: { type: string, example: "prompt_strict" } size: { type: integer, example: 123 } updated_at: { type: number, format: double, example: 1769182550.59 } required: [name, size, updated_at] PromptListResponse: type: object properties: success: { type: boolean, example: true } items: type: array items: { $ref: "#/components/schemas/PromptListItem" } required: [success, items] PersonalizationUpsertRequest: type: object properties: name: { type: string, example: "biz_mobile" } content: { $ref: "#/components/schemas/PersonalizationConfig" } required: [name, content] additionalProperties: false PersonalizationGetResponse: type: object properties: success: { type: boolean, example: true } name: { type: string, example: "biz_mobile" } content: { $ref: "#/components/schemas/PersonalizationConfig" } required: [success, name, content] PersonalizationListItem: type: object properties: name: { type: string, example: "biz_mobile" } size: { type: integer, example: 345 } updated_at: { type: number, format: double, example: 1769182550.59 } required: [name, size, updated_at] PersonalizationListResponse: type: object properties: success: { type: boolean, example: true } items: type: array items: { $ref: "#/components/schemas/PersonalizationListItem" } required: [success, items] ConversationListItem: type: object properties: workspace_id: { type: string, example: "ws1" } id: { type: string, example: "conv_20260124_023218_677" } title: { type: string, example: "新对话" } created_at: { type: string, example: "2026-01-24T02:32:18.677Z" } updated_at: { type: string, example: "2026-01-24T02:33:10.123Z" } run_mode: { type: string, nullable: true, example: "fast" } model_key: { type: string, nullable: true, example: "kimi" } custom_prompt_name: { type: string, nullable: true, example: "custom_a" } personalization_name: { type: string, nullable: true, example: "biz_mobile" } messages_count: { type: integer, example: 6 } required: [workspace_id, id, title, created_at, updated_at, messages_count] ConversationListResponse: type: object properties: success: { type: boolean, example: true } data: type: array items: { $ref: "#/components/schemas/ConversationListItem" } total: { type: integer, example: 42 } required: [success, data, total] ConversationGetResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } data: type: object additionalProperties: true required: [success, workspace_id, data] DeleteConversationResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } message: { type: string, example: "对话已删除: conv_..." } required: [success, workspace_id, message] ModelsResponse: type: object properties: success: { type: boolean, example: true } items: type: array items: type: object properties: model_key: { type: string, example: "kimi" } name: { type: string, example: "Kimi" } supports_thinking: { type: boolean, example: true } fast_only: { type: boolean, example: false } required: [model_key, name, supports_thinking, fast_only] required: [success, items] HealthResponse: type: object properties: success: { type: boolean, example: true } status: { type: string, example: "ok" } required: [success, status] SendMessageResponse: type: object properties: success: { type: boolean, example: true } task_id: { type: string, example: "60322db3-f884-4a1e-a9b3-6eeb07fbab47" } conversation_id: { type: string, example: "conv_20260123_234245_036" } workspace_id: { type: string, example: "ws1" } status: { type: string, example: "running" } created_at: { type: number, format: double, example: 1769182965.3038778 } required: [success, task_id, conversation_id, workspace_id, status, created_at] TaskEvent: type: object properties: idx: { type: integer, example: 12 } type: { type: string, example: "text_chunk" } data: type: object additionalProperties: true ts: { type: number, format: double, example: 1769182968.154797 } required: [idx, type, data, ts] TaskPollResponse: type: object properties: success: { type: boolean, example: true } data: type: object properties: task_id: { type: string } workspace_id: { type: string, nullable: true } status: { type: string, example: "running" } created_at: { type: number, format: double } updated_at: { type: number, format: double } error: { type: string, nullable: true } events: type: array items: { $ref: "#/components/schemas/TaskEvent" } next_offset: { type: integer, example: 3 } required: [task_id, status, created_at, updated_at, error, events, next_offset] required: [success, data] CancelResponse: type: object properties: success: { type: boolean, example: true } required: [success] UploadResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } path: { type: string, example: "inputs/hello.txt" } filename: { type: string, example: "hello.txt" } size: { type: integer, example: 16 } sha256: { type: string, example: "0f5bd6..." } required: [success, workspace_id, path, filename] ListFilesItem: type: object properties: name: { type: string, example: "hello.txt" } is_dir: { type: boolean, example: false } size: { type: integer, example: 16 } modified_at: { type: number, format: double, example: 1769182550.594278 } path: { type: string, example: "inputs/hello.txt" } required: [name, is_dir, size, modified_at, path] ListFilesResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } base: { type: string, example: "." } items: type: array items: { $ref: "#/components/schemas/ListFilesItem" } required: [success, workspace_id, base, items] WorkspaceCreateRequest: type: object properties: workspace_id: type: string description: 仅允许字母/数字/._-,长度1-40 required: [workspace_id] additionalProperties: false WorkspaceInfo: type: object properties: workspace_id: { type: string, example: "ws1" } project_path: { type: string } data_dir: { type: string } has_conversations: { type: boolean } required: [workspace_id, project_path, data_dir, has_conversations] WorkspacesListResponse: type: object properties: success: { type: boolean, example: true } items: type: array items: { $ref: "#/components/schemas/WorkspaceInfo" } required: [success, items] WorkspaceCreateResponse: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } project_path: { type: string } data_dir: { type: string } required: [success, workspace_id, project_path, data_dir] ToolsCategory: type: object properties: id: { type: string, example: "network" } label: { type: string, example: "网络检索" } default_enabled: { type: boolean, example: true } silent_when_disabled: { type: boolean, example: false } tools: type: array items: { type: string } required: [id, label, default_enabled, silent_when_disabled, tools] ToolsResponse: type: object properties: success: { type: boolean, example: true } categories: type: array items: { $ref: "#/components/schemas/ToolsCategory" } required: [success, categories] security: - bearerAuth: [] paths: /api/v1/tools: get: summary: 获取工具分类与工具名称列表 security: [{ bearerAuth: [] }] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/ToolsResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces: get: summary: 列出工作区 security: [{ bearerAuth: [] }] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/WorkspacesListResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } post: summary: 创建/确保工作区存在 security: [{ bearerAuth: [] }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/WorkspaceCreateRequest" } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/WorkspaceCreateResponse" } "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}: get: summary: 查询单个工作区 security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: type: object properties: success: { type: boolean, example: true } workspace: { $ref: "#/components/schemas/WorkspaceInfo" } required: [success, workspace] "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } delete: summary: 删除工作区(若有运行中任务则 409) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: type: object properties: success: { type: boolean, example: true } workspace_id: { type: string, example: "ws1" } required: [success, workspace_id] "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "409": description: Conflict (该工作区有运行中任务) content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/conversations: post: summary: 创建对话(工作区内) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } requestBody: required: false content: application/json: schema: { $ref: "#/components/schemas/CreateConversationRequest" } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/CreateConversationResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } get: summary: 获取对话列表(工作区内) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } - in: query name: limit required: false schema: { type: integer, default: 20, minimum: 1, maximum: 100 } - in: query name: offset required: false schema: { type: integer, default: 0, minimum: 0 } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/ConversationListResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/conversations/{conversation_id}: get: summary: 获取单个对话(工作区内,可选 full=1 返回 messages) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } - in: path name: conversation_id required: true schema: { type: string } - in: query name: full required: false schema: { type: string, default: "0", enum: ["0", "1"] } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/ConversationGetResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } delete: summary: 删除对话(工作区内) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } - in: path name: conversation_id required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/DeleteConversationResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/messages: post: summary: 发送消息并创建后台任务(工作区内) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/SendMessageRequest" } responses: "202": description: Accepted content: application/json: schema: { $ref: "#/components/schemas/SendMessageResponse" } "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found (prompt/personalization 不存在) content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "409": description: Conflict (该工作区已有运行任务) content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/prompts: get: summary: 列出 Prompt security: [{ bearerAuth: [] }] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/PromptListResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } post: summary: 创建/覆盖 Prompt security: [{ bearerAuth: [] }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/PromptUpsertRequest" } responses: "200": description: OK content: application/json: schema: type: object properties: success: { type: boolean, example: true } name: { type: string, example: "prompt_strict" } required: [success, name] "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/prompts/{name}: get: summary: 获取 Prompt 内容 security: [{ bearerAuth: [] }] parameters: - in: path name: name required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/PromptGetResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/personalizations: get: summary: 列出个性化配置 security: [{ bearerAuth: [] }] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/PersonalizationListResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } post: summary: 创建/覆盖个性化配置(服务端会 sanitize 并返回清洗后的 content) security: [{ bearerAuth: [] }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/PersonalizationUpsertRequest" } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/PersonalizationGetResponse" } "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/personalizations/{name}: get: summary: 获取个性化配置内容(服务端会 sanitize 并可能回写) security: [{ bearerAuth: [] }] parameters: - in: path name: name required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/PersonalizationGetResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/models: get: summary: 列出服务端模型(公开) security: [] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/ModelsResponse" } /api/v1/health: get: summary: 健康检查(公开) security: [] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/HealthResponse" } /api/v1/tasks/{task_id}: get: summary: 轮询任务事件 security: [{ bearerAuth: [] }] parameters: - in: path name: task_id required: true schema: { type: string } - in: query name: from required: false schema: { type: integer, default: 0 } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/TaskPollResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/tasks/{task_id}/cancel: post: summary: 请求停止任务 security: [{ bearerAuth: [] }] parameters: - in: path name: task_id required: true schema: { type: string } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/CancelResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/files/upload: post: summary: 上传文件到 user_upload security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary filename: type: string dir: type: string description: user_upload 下子目录 required: [file] responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/UploadResponse" } "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/files: get: summary: 列出 project 目录内容 security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } - in: query name: path required: false schema: { type: string, default: "" } responses: "200": description: OK content: application/json: schema: { $ref: "#/components/schemas/ListFilesResponse" } "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } /api/v1/workspaces/{workspace_id}/files/download: get: summary: 下载文件或目录(目录会打包成 zip) security: [{ bearerAuth: [] }] parameters: - in: path name: workspace_id required: true schema: { type: string } - in: query name: path required: true schema: { type: string } responses: "200": description: File content content: application/octet-stream: schema: type: string format: binary application/zip: schema: type: string format: binary "400": description: Bad Request content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "401": description: Unauthorized content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" } "404": description: Not Found content: application/json: schema: { $ref: "#/components/schemas/ErrorResponse" }