239 lines
6.7 KiB
Markdown
239 lines
6.7 KiB
Markdown
# 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`.
|