Files
eryao/docs/protocols/divination/divination-run-protocol.md
T

239 lines
6.7 KiB
Markdown
Raw Normal View History

# Divination Run Protocol (Frontend <-> Backend)
This document defines the structured contract for divination run input, backend hexagram derivation, and run event output.
Protocol verification status:
- Backend route source: `backend/src/v1/agent/router.py`
- Backend derivation source: `backend/src/core/divination/derivation.py`
- Runtime payload schema source: `backend/src/schemas/domain/divination.py`
## Compatibility strategy
- Current strategy: additive evolution only.
- Existing required fields cannot be removed or renamed without migration notes.
- Canonical divination terminology values must remain Chinese.
## Route overview
- Submit run: `POST /api/v1/agent/runs`
- Stream events: `GET /api/v1/agent/runs/{threadId}/events?runId=...`
- History snapshot: `GET /api/v1/agent/history`
## Run request contract
`RunAgentInput` uses AG-UI shape. This protocol constrains two sections:
1) `messages[0].content` (question text)
2) `forwardedProps.divinationPayload` (structured divination input)
### Required request shape
```json
{
"threadId": "uuid",
"runId": "run_20260403_xxx",
"state": {},
"messages": [
{
"id": "msg_run_20260403_xxx_user_0",
"role": "user",
"content": "我最近换工作是否合适?"
}
],
"tools": [],
"context": [],
"forwardedProps": {
"runtime_mode": "chat",
"client_time": {
"device_timezone": "Asia/Shanghai",
"client_now_iso": "2026-04-03T20:30:00+08:00",
"client_epoch_ms": 1775219400000
},
"divinationPayload": {
"divinationMethod": "手动起卦",
"questionType": "事业",
"question": "我最近换工作是否合适?",
"divinationTimeIso": "2026-04-03T20:30:00+08:00",
"yaoLines": [
"少阳",
"少阴",
"老阳",
"少阴",
"少阳",
"老阴"
]
}
}
}
```
### AG-UI required base fields
- `state`: required object, frontend sends `{}` by default.
- `messages[0].id`: required string id for user message.
- `tools`: required array, frontend sends empty array when no tools requested.
- `context`: required array, frontend sends empty array when no extra context.
### `divinationPayload` strict rules
- `divinationMethod`: enum, allowed values `手动起卦 | 自动起卦`
- `questionType`: non-empty string, recommended Chinese category labels
- `question`: non-empty string
- `divinationTimeIso`: RFC3339 datetime with timezone offset
- `yaoLines`: exactly 6 items, order is `初爻 -> 上爻`
- `yaoLines` item enum: `少阳 | 少阴 | 老阳 | 老阴`
- Additional fields are forbidden.
## Event output contract
During run streaming, backend emits standard AG-UI lifecycle events and two divination-relevant payload events:
### 1) `DIVINATION_DERIVED`
- Emitted once after backend derives hexagram data.
- Payload field: `divination` (strict object).
`divination` object:
```json
{
"question": "我最近换工作是否合适?",
"questionType": "事业",
"divinationMethod": "手动起卦",
"divinationTime": "2026年04月03日 20:30",
"binaryCode": "101001",
"changedBinaryCode": "100001",
"guaName": "山火贲",
"upperName": "艮",
"lowerName": "离",
"targetGuaName": "山雷颐",
"worldPosition": 1,
"responsePosition": 4,
"hasChangingYao": true,
"ganzhi": {
"yearGanZhi": "丙午",
"monthGanZhi": "壬辰",
"dayGanZhi": "辛亥",
"timeGanZhi": "乙巳",
"yearKongWang": "子丑",
"monthKongWang": "午未",
"dayKongWang": "寅卯",
"timeKongWang": "戌亥",
"yueJian": "辰土",
"riChen": "亥水",
"yuePo": "戌土",
"riChong": "巳火"
},
"wuXingStatuses": {
"木": "囚",
"火": "休",
"土": "旺",
"金": "相",
"水": "死"
},
"yaoInfoList": [
{
"position": 1,
"spiritName": "虎",
"relationName": "官鬼",
"tiganName": "卯",
"elementName": "木",
"isYang": true,
"isChanging": false,
"specialMark": "世"
}
],
"targetYaoInfoList": [],
"fushenPositions": [2],
"fushenInfoList": [
{
"position": 2,
"relationName": "父母",
"tiganName": "午",
"elementName": "火"
}
]
}
```
### 2) `TEXT_MESSAGE_END`
- Standard final answer event.
- Existing fields remain canonical: `sign_level`, `conclusion`, `focus_points`, `advice`, `keywords`, `answer`.
- Language rule: `conclusion`, `focus_points`, `advice`, `keywords`, `answer` should follow user `ai_language` preference unless user explicitly requests otherwise.
- Canonical six-yao terms remain Chinese in protocol text (for example: 世爻、应爻、动爻、静爻、六亲、六神、伏神、月建、日辰、月破、日冲、空亡、五行旺衰).
Frontend should combine:
- structural divination data from `DIVINATION_DERIVED`
- interpretation text from `TEXT_MESSAGE_END`
## History snapshot contract
`GET /api/v1/agent/history` is the canonical replay source for frontend history list and result reconstruction.
### Required response shape
```json
{
"scope": "history_day",
"threadId": "uuid|null",
"day": "2026-04-05|null",
"hasMore": false,
"messages": [
{
"id": "uuid",
"seq": 12,
"role": "assistant",
"content": "...",
"timestamp": "2026-04-05T12:34:56+00:00",
"agent_output": {
"status": "success",
"sign_level": "中上签",
"conclusion": ["..."],
"focus_points": ["..."],
"advice": ["..."],
"keywords": ["..."],
"answer": "...",
"divination_derived": {
"binaryCode": "101001",
"changedBinaryCode": "100001",
"guaName": "山火贲"
}
}
},
{
"id": "uuid",
"seq": 11,
"role": "user",
"content": "我最近换工作是否合适?",
"timestamp": "2026-04-05T12:34:12+00:00",
"attachments": [
{
"mimeType": "image/png",
"url": "https://...signed..."
}
]
}
]
}
```
Rules:
- `assistant` message MUST provide `agent_output` when backend has valid worker output metadata.
- `agent_output.divination_derived` uses the same shape as `DIVINATION_DERIVED.divination` payload.
- Frontend reconstructs divination result page from `agent_output` data, not from local mock data.
- `agent_output.sign_level` allowed values: `上上签` / `中上签` / `中下签` / `下下签`.
### Breaking change note
- `ui_schema` is removed from history response and is no longer part of this project protocol.
- This repository currently accepts non-backward-compatible protocol evolution (no production compatibility burden).
## Error contract linkage
- All errors use RFC7807 with extension `code` and optional `params`.
- Error code registry source: `docs/protocols/common/http-error-codes.md`.