openapi: 3.0.3 info: title: ChatSession & Message API version: 1.1.1 description: | ChatSession & Message API(含 Archive/GetMessage/SSE 与 Run 调度)。自然语言:中文。 servers: - url: http://localhost:8000/api description: 本地开发(FrankenPHP / Docker) tags: - name: ChatSession description: 会话管理 - name: Message description: 消息追加与查询 - name: Run description: Agent Run 调度 paths: /test: summary: 测试接口 get: tags: [Test] responses: "200": description: 成功 /sessions: post: tags: [ChatSession] summary: 创建会话 security: - bearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/CreateSessionRequest' responses: "201": description: 创建成功 content: application/json: schema: $ref: '#/components/schemas/ChatSession' "401": description: 未授权 get: tags: [ChatSession] summary: 会话列表 security: - bearerAuth: [] parameters: - in: query name: page schema: type: integer default: 1 - in: query name: per_page schema: type: integer default: 15 maximum: 100 - in: query name: status schema: type: string enum: [OPEN, LOCKED, CLOSED] - in: query name: q schema: type: string description: 模糊匹配 session_name responses: "200": description: 分页会话列表 content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/ChatSession' links: $ref: '#/components/schemas/PaginationLinks' meta: $ref: '#/components/schemas/PaginationMeta' "401": description: 未授权 /sessions/{session_id}: get: tags: [ChatSession] summary: 获取会话详情 security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid responses: "200": description: 会话详情 content: application/json: schema: $ref: '#/components/schemas/ChatSession' "401": description: 未授权 "404": description: 未找到 patch: tags: [ChatSession] summary: 更新会话(重命名/状态) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateSessionRequest' responses: "200": description: 更新成功 content: application/json: schema: $ref: '#/components/schemas/ChatSession' "403": description: 状态门禁禁止 content: application/json: schema: $ref: '#/components/schemas/Error' "422": description: 校验失败 "401": description: 未授权 /sessions/{session_id}/archive: post: tags: [ChatSession] summary: 归档会话(设为 CLOSED,幂等) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid responses: "200": description: 归档成功(或已归档) content: application/json: schema: $ref: '#/components/schemas/ChatSession' "401": description: 未授权 "404": description: 未找到 /sessions/{session_id}/messages: post: tags: [Message] summary: 追加消息(含幂等与状态门禁) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AppendMessageRequest' responses: "201": description: 追加成功 content: application/json: schema: $ref: '#/components/schemas/MessageResource' "403": description: 状态门禁禁止 content: application/json: schema: $ref: '#/components/schemas/Error' "401": description: 未授权 get: tags: [Message] summary: 按 seq 增量查询消息 security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid - in: query name: after_seq schema: type: integer default: 0 description: 仅返回 seq 大于该值的消息 - in: query name: limit schema: type: integer default: 50 maximum: 200 description: 返回数量上限 responses: "200": description: 按 seq 升序的消息列表 content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/MessageResource' "401": description: 未授权 /sessions/{session_id}/messages/{message_id}: get: tags: [Message] summary: 获取单条消息(校验 session_id) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid - in: path name: message_id required: true schema: type: string format: uuid responses: "200": description: 消息详情 content: application/json: schema: $ref: '#/components/schemas/MessageResource' "401": description: 未授权 "404": description: 未找到或不属于该会话 /sessions/{session_id}/sse: get: tags: [Message] summary: SSE 增量推送(backlog + Redis 实时) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid - in: query name: after_seq schema: type: integer default: 0 description: backlog 起始 seq(若有 Last-Event-ID 以其为准) - in: query name: limit schema: type: integer default: 200 maximum: 500 responses: "200": description: text/event-stream SSE 流 content: text/event-stream: schema: type: string example: | id: 1 event: message data: {"message_id":"...","seq":1} "401": description: 未授权 "404": description: 未找到 /sessions/{session_id}/runs: post: tags: [Run] summary: 触发一次 Agent Run(按 trigger_message_id 幂等) security: - bearerAuth: [] parameters: - in: path name: session_id required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchRunRequest' responses: "201": description: 已触发(或复用进行中的 RUNNING) content: application/json: schema: type: object properties: run_id: type: string format: uuid "401": description: 未授权 "404": description: session 或 trigger_message 不存在 components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: ChatSession: type: object properties: session_id: type: string format: uuid session_name: type: string nullable: true status: type: string enum: [OPEN, LOCKED, CLOSED] last_seq: type: integer last_message_id: type: string format: uuid nullable: true last_message_at: type: string format: date-time nullable: true last_message_preview: type: string last_message_role: type: string nullable: true last_message_type: type: string nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time CreateSessionRequest: type: object properties: session_name: type: string maxLength: 255 UpdateSessionRequest: type: object properties: session_name: type: string minLength: 1 maxLength: 255 status: type: string enum: [OPEN, LOCKED, CLOSED] DispatchRunRequest: type: object required: [trigger_message_id] properties: trigger_message_id: type: string format: uuid AppendMessageRequest: type: object required: [role, type] properties: role: type: string enum: [USER, AGENT, TOOL, SYSTEM] type: type: string maxLength: 64 example: user.prompt content: type: string nullable: true payload: nullable: true oneOf: - $ref: '#/components/schemas/RunStatusPayload' - $ref: '#/components/schemas/AgentMessagePayload' - $ref: '#/components/schemas/MessageDeltaPayload' - $ref: '#/components/schemas/RunCancelPayload' - $ref: '#/components/schemas/RunErrorPayload' - $ref: '#/components/schemas/ToolCallPayload' - $ref: '#/components/schemas/ToolResultPayload' - type: object reply_to: type: string format: uuid nullable: true dedupe_key: type: string maxLength: 128 nullable: true MessageResource: type: object properties: message_id: type: string format: uuid session_id: type: string format: uuid seq: type: integer role: type: string enum: [USER, AGENT, TOOL, SYSTEM] type: type: string content: type: string nullable: true payload: type: object nullable: true reply_to: type: string format: uuid nullable: true dedupe_key: type: string nullable: true created_at: type: string format: date-time Error: type: object properties: message: type: string example: Session is closed RunStatusPayload: type: object properties: run_id: type: string format: uuid status: type: string enum: [RUNNING, DONE, FAILED, CANCELED] trigger_message_id: type: string format: uuid nullable: true error: type: string nullable: true AgentMessagePayload: type: object properties: run_id: type: string format: uuid provider: type: string MessageDeltaPayload: type: object properties: run_id: type: string format: uuid delta_index: type: integer RunCancelPayload: type: object properties: run_id: type: string format: uuid RunErrorPayload: type: object properties: run_id: type: string format: uuid message: type: string retryable: type: boolean nullable: true http_status: type: integer nullable: true provider: type: string nullable: true latency_ms: type: integer nullable: true raw_message: type: string nullable: true ToolCallPayload: type: object properties: run_id: type: string tool_run_id: type: string tool_call_id: type: string name: type: string arguments: type: object additionalProperties: true ToolResultPayload: type: object properties: run_id: type: string parent_run_id: type: string tool_call_id: type: string name: type: string status: type: string error: type: string nullable: true truncated: type: boolean PaginationLinks: type: object properties: first: type: string example: http://localhost:8000/api/sessions?page=1 last: type: string example: http://localhost:8000/api/sessions?page=1 prev: type: string nullable: true next: type: string nullable: true PaginationMeta: type: object properties: current_page: type: integer from: type: integer nullable: true last_page: type: integer path: type: string per_page: type: integer to: type: integer nullable: true total: type: integer