145 lines
3.3 KiB
Markdown
145 lines
3.3 KiB
Markdown
# reply-end-controls - Telegram V1 Design
|
|
|
|
## Scope
|
|
|
|
This project is Telegram-only.
|
|
|
|
No Discord, Slack, or cross-channel abstraction is part of V1.
|
|
|
|
## Product behavior
|
|
|
|
At the end of every assistant reply sent to Telegram, attach two inline buttons:
|
|
|
|
- `A. 繼續`
|
|
- `B. 就這樣吧,不需要額外處理`
|
|
|
|
Button selection must be captured and stored in conversation/session state.
|
|
|
|
If the user types a new message instead of pressing a button, the typed message takes priority.
|
|
|
|
## V1 rules
|
|
|
|
### Rule 1
|
|
|
|
Every assistant reply gets reply-end buttons.
|
|
|
|
### Rule 2
|
|
|
|
If the user taps `繼續`:
|
|
|
|
- store `lastChoice=continue`
|
|
- allow follow-up behavior on later turns
|
|
|
|
### Rule 3
|
|
|
|
If the user taps `就這樣吧,不需要額外處理`:
|
|
|
|
- store `lastChoice=stop`
|
|
- suppress unnecessary continuation behavior on later turns
|
|
|
|
### Rule 4
|
|
|
|
If the user sends a new typed message, that input overrides the button state.
|
|
|
|
### Rule 5
|
|
|
|
After a button is clicked, the original message buttons should be updated so the selection is visually resolved and repeated clicks are reduced.
|
|
|
|
## State model
|
|
|
|
Store this in Telegram conversation/session state:
|
|
|
|
```json
|
|
{
|
|
"replyEndControls": {
|
|
"lastChoice": "continue | stop",
|
|
"lastChoiceAt": "ISO timestamp",
|
|
"sourceMessageId": "telegram message id",
|
|
"sourceCallbackId": "telegram callback query id",
|
|
"active": true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Telegram callback payloads
|
|
|
|
Suggested callback data format:
|
|
|
|
- `rec:continue`
|
|
- `rec:stop`
|
|
|
|
If message-scoped state is needed later, extend to:
|
|
|
|
- `rec:continue:<messageId>`
|
|
- `rec:stop:<messageId>`
|
|
|
|
## Technical flow
|
|
|
|
### Outbound reply flow
|
|
|
|
1. Assistant reply text is produced.
|
|
2. Telegram reply payload is decorated with inline keyboard.
|
|
3. Message is sent to Telegram.
|
|
|
|
### Callback flow
|
|
|
|
1. User clicks button.
|
|
2. Telegram sends callback query.
|
|
3. Callback handler parses `continue` or `stop`.
|
|
4. State is persisted.
|
|
5. Original message buttons are updated to reflect the chosen option.
|
|
|
|
### Next-turn behavior
|
|
|
|
1. A later turn begins.
|
|
2. Runtime checks `replyEndControls.lastChoice`.
|
|
3. If `stop`, do not proactively extend or continue the previous thread unless the user explicitly asks.
|
|
4. If `continue`, normal continuation behavior is allowed.
|
|
|
|
## Suggested implementation modules
|
|
|
|
### 1. Reply decorator
|
|
|
|
Responsibility:
|
|
|
|
- append Telegram inline keyboard to every assistant reply
|
|
|
|
### 2. Callback handler
|
|
|
|
Responsibility:
|
|
|
|
- receive Telegram callback queries
|
|
- parse reply-end action
|
|
- update state
|
|
|
|
### 3. State storage helper
|
|
|
|
Responsibility:
|
|
|
|
- persist and retrieve the latest reply-end selection for the current conversation/session
|
|
|
|
### 4. Behavior policy hook
|
|
|
|
Responsibility:
|
|
|
|
- inspect `lastChoice`
|
|
- suppress proactive continuation when `stop` is active
|
|
|
|
## Acceptance criteria for V1
|
|
|
|
V1 is complete when all of the following are true:
|
|
|
|
1. A normal Telegram assistant reply shows both buttons.
|
|
2. Clicking `繼續` is received and stored.
|
|
3. Clicking `就這樣吧,不需要額外處理` is received and stored.
|
|
4. After click, the original message is updated to show the choice state.
|
|
5. A new typed user message still works without pressing any button.
|
|
6. A later turn can read the stored choice and alter continuation behavior.
|
|
|
|
## Non-goals for V1
|
|
|
|
- multi-channel abstraction
|
|
- governance integration
|
|
- analytics dashboard
|
|
- complex branching controls beyond `continue` and `stop`
|