mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-20 19:33:28 +08:00
feat(feishu): persistent session watches and completion pushes
- /watch resolves the target READ-ONLY: sessions are validated against registered workspace listings (current or any other) without binding the conversation or switching workspaces. /unwatch and /watchlist round out the command set; the watchlist card supports button and number-reply unwatching. - Watches persist in the state store (sessionId + title + chatId + lastSeq) and resume at runtime start: the bridge starts the global event-mux watcher in its constructor when the harness supports it. - Completion pushes fire on turn/end, deduped by sessionId + turn id, with the seq watermark persisted per watch. After a mux reconnect the bridge replays each watched session's recent history (session.history) through the normal handler, so missed turn/end events are compensated without duplicates. - Bound-session push targets are persisted (chatTargets) instead of living only in memory, and refresh on every accepted message. - Watch failures map to safe user-facing messages.
This commit is contained in:
parent
0579c24b13
commit
beb269dc0e
6 changed files with 746 additions and 132 deletions
|
|
@ -153,3 +153,32 @@ export function menuHelpText() {
|
|||
'/workspace 绝对路径 切换工作区',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
/** The watch list for one conversation (unwatch buttons + reply fallback). */
|
||||
export function watchListCard(entries) {
|
||||
const elements = entries.length === 0
|
||||
? [{ tag: 'div', text: markdown('当前没有关注的会话。\n`/watch <ID|序号>` 关注后,任务完成会自动推送。') }]
|
||||
: [
|
||||
{ tag: 'div', text: markdown('任务完成会自动推送,回复数字或点按钮取消关注:') },
|
||||
...entries.map((entry, index) => button(
|
||||
`${index + 1}. ${safeTitle(entry.title)}`,
|
||||
`unwatch:${entry.sessionId}`,
|
||||
)),
|
||||
];
|
||||
return cardWith('👁 关注列表', elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* The completion push card. `title` is the session title, `reason` the
|
||||
* turn-end kind (completed / stopped / aborted).
|
||||
*/
|
||||
export function completionCard(sessionId, title, reason) {
|
||||
const reasonText = reason === 'stopped' ? '已停止' : reason === 'aborted' ? '已中止' : '已完成';
|
||||
return cardWith('✅ 任务完成', [
|
||||
{ tag: 'div', text: markdown(`**${safeTitle(title)}**\n\`${sessionId}\``) },
|
||||
{ tag: 'div', text: markdown(`**状态**:${reasonText}`) },
|
||||
button('打开会话列表', 'sessions'),
|
||||
button('工作区', 'workspaces'),
|
||||
{ tag: 'div', text: markdown('绑定该会话后可继续追问,输入文字即可。') },
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue