petstore-docs/contracts/booking-agent-m0.openapi.yaml
2026-08-02 15:23:55 +08:00

560 lines
14 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.0.3
info:
title: Petstore Booking Agent M0 API
version: 0.1.0
description: |
智能预约 M0 冻结契约。M0 只生成并回填预约草稿,不注册 confirm endpoint
不直接创建 Appointment。除鉴权拦截器的 HTTP 401 外,当前 Petstore 客户端以
响应体 code 作为业务结果;实现不得借本功能顺带重构全局响应语义。
security:
- bearerAuth: []
x-contract-status: frozen-for-m0
x-business-error-codes:
- UNAUTHENTICATED
- FORBIDDEN
- AGENT_DISABLED
- STORE_NOT_FOUND
- SESSION_NOT_FOUND
- SESSION_EXPIRED
- SESSION_TERMINAL
- DRAFT_VERSION_CONFLICT
- INVALID_INPUT
- INVALID_AUDIO
- AUDIO_TOO_LARGE
- RATE_LIMITED
- AGENT_UNAVAILABLE
- ASR_UNAVAILABLE
paths:
/api/booking-agent/sessions:
post:
operationId: createBookingAgentSession
summary: 创建 customer 智能预约会话
description: |
仅已登录 customer。M0 要求先在普通预约页选定门店entrySource 由服务端固定为
appointment_create不从客户端接收。
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSessionRequest'
responses:
'200':
description: 成功或带业务 code 的可理解失败
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SessionEnvelope'
- $ref: '#/components/schemas/ErrorEnvelope'
'401':
$ref: '#/components/responses/Unauthenticated'
/api/booking-agent/sessions/{sessionId}/messages:
post:
operationId: submitBookingAgentMessage
summary: 提交一轮已确认文字并刷新草稿
parameters:
- $ref: '#/components/parameters/SessionId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SubmitMessageRequest'
responses:
'200':
description: 成功或带业务 code 的可理解失败
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SessionEnvelope'
- $ref: '#/components/schemas/ErrorEnvelope'
'401':
$ref: '#/components/responses/Unauthenticated'
/api/booking-agent/sessions/{sessionId}/transcriptions:
post:
operationId: transcribeBookingAgentAudio
summary: 转写当前 customer 会话的一段短音频
description: |
只做语音转写,不自动提交消息。客户端必须把返回文字放回可编辑输入框,用户确认后
再调用 messages。后端从 session 解析门店和 customer 范围,不接受客户端上传词表。
parameters:
- $ref: '#/components/parameters/SessionId'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: false
required:
- audio
properties:
audio:
type: string
format: binary
description: 单段不超过 60 秒、3 MBMIME 与真实文件头必须一致
responses:
'200':
description: 成功或带业务 code 的可理解失败
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/TranscriptionEnvelope'
- $ref: '#/components/schemas/ErrorEnvelope'
'401':
$ref: '#/components/responses/Unauthenticated'
/api/booking-agent/sessions/{sessionId}/fallback:
post:
operationId: handoffBookingAgentDraft
summary: 结束助手并返回可回填普通表单的已验证草稿
parameters:
- $ref: '#/components/parameters/SessionId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DraftVersionRequest'
responses:
'200':
description: 成功或带业务 code 的可理解失败
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/HandoffEnvelope'
- $ref: '#/components/schemas/ErrorEnvelope'
'401':
$ref: '#/components/responses/Unauthenticated'
/api/booking-agent/sessions/{sessionId}:
delete:
operationId: cancelBookingAgentSession
summary: 结束本人智能预约会话
parameters:
- $ref: '#/components/parameters/SessionId'
responses:
'200':
description: 成功或带业务 code 的可理解失败
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/CancelEnvelope'
- $ref: '#/components/schemas/ErrorEnvelope'
'401':
$ref: '#/components/responses/Unauthenticated'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: PetstoreSessionToken
parameters:
SessionId:
name: sessionId
in: path
required: true
description: 不可预测的 UUID仍必须和 current.userId 联合查询
schema:
type: string
format: uuid
responses:
Unauthenticated:
description: session token 缺失、失效或账号权限已变化
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
code: 401
message: 登录已失效,请重新登录
bizCode: UNAUTHENTICATED
schemas:
CreateSessionRequest:
type: object
additionalProperties: false
required:
- storeId
properties:
storeId:
type: integer
format: int64
minimum: 1
SubmitMessageRequest:
type: object
additionalProperties: false
required:
- inputType
- text
- draftVersion
properties:
inputType:
type: string
enum:
- text
- voice
text:
type: string
minLength: 1
maxLength: 500
description: 用户确认后的当轮输入;服务端不得写日志或长期持久化
draftVersion:
type: integer
minimum: 0
DraftVersionRequest:
type: object
additionalProperties: false
required:
- draftVersion
properties:
draftVersion:
type: integer
minimum: 0
BookingAgentStatus:
type: string
enum:
- collecting
- proposing
- confirmable
- fallback
- expired
- cancelled
MissingField:
type: string
enum:
- pet
- service
- date
- time
BookingDraft:
type: object
additionalProperties: false
required:
- storeId
- storeName
- petId
- petName
- petType
- serviceTypeId
- serviceType
- durationMinutes
- dateConstraint
- timeWindow
- appointmentTime
- appointmentEndTime
- remark
- missingFields
properties:
storeId:
type: integer
format: int64
storeName:
type: string
maxLength: 128
petId:
type: integer
format: int64
nullable: true
petName:
type: string
nullable: true
maxLength: 64
petType:
type: string
nullable: true
maxLength: 32
serviceTypeId:
type: integer
format: int64
nullable: true
serviceType:
type: string
nullable: true
maxLength: 64
durationMinutes:
type: integer
nullable: true
minimum: 1
dateConstraint:
type: string
format: date
nullable: true
timeWindow:
$ref: '#/components/schemas/TimeWindow'
appointmentTime:
$ref: '#/components/schemas/NullableLocalDateTime'
appointmentEndTime:
$ref: '#/components/schemas/NullableLocalDateTime'
remark:
type: string
nullable: true
maxLength: 200
missingFields:
type: array
uniqueItems: true
items:
$ref: '#/components/schemas/MissingField'
TimeWindow:
type: object
nullable: true
additionalProperties: false
required:
- start
- end
properties:
start:
type: string
nullable: true
pattern: '^(?:[01]\d|2[0-3]):[0-5]\d$'
end:
type: string
nullable: true
pattern: '^(?:[01]\d|2[0-3]):[0-5]\d$'
SlotOption:
type: object
additionalProperties: false
required:
- startTime
- endTime
- label
properties:
startTime:
$ref: '#/components/schemas/LocalDateTime'
endTime:
$ref: '#/components/schemas/LocalDateTime'
label:
type: string
maxLength: 64
QuickReply:
type: object
additionalProperties: false
required:
- type
- value
- label
properties:
type:
type: string
enum:
- pet
- service
- slot
- date
- fallback
value:
type: string
maxLength: 128
label:
type: string
maxLength: 64
SessionView:
type: object
additionalProperties: false
required:
- sessionId
- status
- assistantMessage
- draft
- slotOptions
- quickReplies
- confirmable
- draftVersion
- expiresAt
properties:
sessionId:
type: string
format: uuid
status:
$ref: '#/components/schemas/BookingAgentStatus'
assistantMessage:
type: string
maxLength: 300
description: 服务端模板渲染,不包含模型思考或供应商错误
draft:
$ref: '#/components/schemas/BookingDraft'
slotOptions:
type: array
maxItems: 3
items:
$ref: '#/components/schemas/SlotOption'
quickReplies:
type: array
maxItems: 10
items:
$ref: '#/components/schemas/QuickReply'
confirmable:
type: boolean
draftVersion:
type: integer
minimum: 0
expiresAt:
$ref: '#/components/schemas/LocalDateTime'
LocalDateTime:
type: string
pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$'
description: Asia/Shanghai 下的本地日期时间,格式 yyyy-MM-ddTHH:mm:ss
NullableLocalDateTime:
type: string
nullable: true
pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$'
description: null 或 Asia/Shanghai 下的本地日期时间;非空时格式为 yyyy-MM-ddTHH:mm:ss
HandoffData:
type: object
additionalProperties: false
required:
- source
- draft
properties:
source:
type: string
enum:
- booking-agent-m0
draft:
$ref: '#/components/schemas/BookingDraft'
TranscriptionData:
type: object
additionalProperties: false
required:
- text
properties:
text:
type: string
maxLength: 500
description: 可编辑转写;不返回供应商原始响应或外部 request ID
CancelData:
type: object
additionalProperties: false
required:
- sessionId
- status
properties:
sessionId:
type: string
format: uuid
status:
type: string
enum:
- cancelled
SessionEnvelope:
type: object
additionalProperties: false
required:
- code
- data
properties:
code:
type: integer
enum:
- 200
data:
$ref: '#/components/schemas/SessionView'
TranscriptionEnvelope:
type: object
additionalProperties: false
required:
- code
- data
properties:
code:
type: integer
enum:
- 200
data:
$ref: '#/components/schemas/TranscriptionData'
HandoffEnvelope:
type: object
additionalProperties: false
required:
- code
- data
properties:
code:
type: integer
enum:
- 200
data:
$ref: '#/components/schemas/HandoffData'
CancelEnvelope:
type: object
additionalProperties: false
required:
- code
- data
properties:
code:
type: integer
enum:
- 200
data:
$ref: '#/components/schemas/CancelData'
ErrorEnvelope:
type: object
additionalProperties: false
required:
- code
- message
- bizCode
properties:
code:
type: integer
enum:
- 400
- 401
- 403
- 404
- 409
- 410
- 413
- 429
- 503
message:
type: string
maxLength: 200
bizCode:
type: string
enum:
- UNAUTHENTICATED
- FORBIDDEN
- AGENT_DISABLED
- STORE_NOT_FOUND
- SESSION_NOT_FOUND
- SESSION_EXPIRED
- SESSION_TERMINAL
- DRAFT_VERSION_CONFLICT
- INVALID_INPUT
- INVALID_AUDIO
- AUDIO_TOO_LARGE
- RATE_LIMITED
- AGENT_UNAVAILABLE
- ASR_UNAVAILABLE