openapi: 3.0.3 info: title: ChatSession & Message API version: 1.0.0 description: | ChatSession & Message MVP-1,支持会话创建、消息追加、增量查询。自然语言:中文。 servers: - url: http://localhost:8000/api description: 本地开发(FrankenPHP / Docker) tags: - name: ChatSession description: 会话管理与消息 paths: /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}/messages: post: 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/AppendMessageRequest' responses: "201": description: 追加成功 content: application/json: schema: $ref: '#/components/schemas/MessageResource' "403": description: 状态门禁禁止 content: application/json: schema: $ref: '#/components/schemas/Error' "401": description: 未授权 /sessions/{session_id}/messages/{message_id}: get: tags: [ChatSession] 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}/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}/sse: get: tags: [ChatSession] 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}: 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: 未找到 get: tags: [ChatSession] 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}: 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: 未授权 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] 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: type: object nullable: true 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 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